我使用以下命令輸出與 CLOSE-WAIT 套接字相關的 PID 和 FD。
sudo ss -p | grep CLOSE-WAIT | awk '{ print $7 }' | sed 's/,pid=/ /' | sed 's/,fd=/ /' | sed 's/))//' | awk '{ print $2, $3 }'
它在 PID FD 對采用如下一行的情況下正確輸出。
22487 27
22652 21
21846 33
21780 26
22476 14
21571 10
22740 17
21901 26
但是,如果我使用 for 回圈,它的輸出會有所不同。
#!/bin/bash
for PidFd in `sudo ss -p | grep CLOSE-WAIT | awk '{ print $7 }' | sed 's/,pid=/ /' | sed 's/,fd=/ /' | sed 's/))//' | awk '{ print $2, $3 }'`
do
echo "$PidFd"
done
它在兩者之間添加了額外的換行符。
22487
27
22652
21
21846
33
21780
26
22476
14
21571
10
22740
17
21901
26
我想修復它以獲得相同的輸出。
uj5u.com熱心網友回復:
你會得到一個額外的換行符,因為for它不僅在換行符上拆分 - 它還在空格上拆分,因此不是將 pid/fd 對分配給PidFd,而是首先分配一個 PID,然后再分配一個 FD。正如在DontReadLinesWithFor中廣泛記錄的那樣,最佳實踐方法是使用while read回圈。
此外,你不需要使用awk, grep, 或者根本不需要sed在這里完成你想要完成的事情(盡管grep可以在具有大量套接字的系統上提高性能,但代價是在只有少量套接字的系統上變得更糟插座數量):
#!/usr/bin/env bash
case $BASH_VERSION in '') echo "ERROR: Your shell must be bash, not sh" >&2; exit 1;; esac
pid_re='pid=([[:digit:]] )($|[^[:digit:]])'
fd_re='fd=([[:digit:]] )($|[^[:digit:]])'
while IFS= read -r line; do pid=; fd=
[[ $line =~ $pid_re ]] && pid=${BASH_REMATCH[1]}
[[ $line =~ $fd_re ]] && fd=${BASH_REMATCH[1]}
[[ $pid && $fd ]] && echo "$pid $fd"
done < <(sudo ss -p | grep CLOSE-WAIT)
uj5u.com熱心網友回復:
正如查爾斯評論的那樣,awk 可以完成整個管道
sudo ss -p | awk '
/CLOSE-WAIT/ {
field = $7
sub(/,pid=/, " ", field)
sub(/,fd=/, " ", field)
sub(/))/, "", field)
split(field, a)
print a[2], a[3]
}
'
bashmapfile命令可以將行讀入陣列:
mapfile -t lines < <(
sudo ss -p | awk '
/CLOSE-WAIT/ {
field = $7
sub(/,pid=/, " ", field)
sub(/,fd=/, " ", field)
sub(/))/, "", field)
split(field, a)
print a[2], a[3]
}
'
)
現在,你可以做
for PidFd in "${lines[@]}"; do
echo "$PidFd"
done
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/474220.html
