我有一个 shell 脚本来检查端口状态。检查端口后,如果端口繁忙,则将其终止。
#check port and kill
checkPort(){
check=$(sudo netstat -nlpt | grep 2020 | awk '{print $6}')
word="LISTEN"
killProcess=$(sudo netstat -nlpt | grep 2020 | awk '{print $7}' |
sed 's/.\{5\}$//' | sort -u | xargs -t kill -9)
if [[ "$check" == "$word" ]];
then
echo "killing the port 2020"
$killProcess
else
echo "Not Listen"
fi
}
当我运行$killProcess
变量时,我收到错误。但如果我将完整命令放入条件sudo netstat -nlpt | grep 2020 | awk '{print $7}' | sed 's/.\{5\}$//' | sort -u | xargs -t kill -9
中if
,它就可以正常工作。这里的错误是什么?
我收到的错误:
kill -9
Usage:
kill [options] <pid|name> [...]
Options:
-a, --all do not restrict the name-to-pid conversion to processes
with the same uid as the present process
-s, --signal <sig> send specified signal
-q, --queue <sig> use sigqueue(2) rather than kill(2)
-p, --pid print pids without signaling them
-l, --list [=<signal>] list signal names, or convert one to a name
-L, --table list signal names and numbers
-h, --help display this help and exit
-V, --version output version information and exit
我把 改为xargs -i kill -kill {}
。xargs kill -9
效果很好。这是一种好的做法吗?
答案1
该语法var=$(command)
将运行command
并将其输出分配给变量$var
。这意味着脚本中的这一行:
killProcess=$(sudo netstat -nlpt | grep 2020 | awk '{print $7}' |
sed 's/.\{5\}$//' | sort -u | xargs -t kill -9)
将要总是运行以该命令结尾的管道kill
,并将其输出分配给$killprocess
。由于该kill
命令没有输出,因此此行稍后将不会执行任何操作:
$killProcess
您想要做的是killProcess="sudo netstat ... | xargs -t kill -9
。但是您的命令还存在其他问题。首先,它将匹配任何包含 2020 的行,但您只想要2020
端口的情况。如果它是 PID 怎么办?
这是您的函数的工作版本,但有一些更改:
checkPort(){
## Get the target port. If none is given, default to 2020
targetPort=${1:-2020}
## Collect the PID(s) that are listening on the port in the
# array 'pids'.
pids=( $(sudo netstat -nlpt | awk "\$4~/:$targetPort\$/{print \$7}" |
sed 's|/.*||'))
## If no processes were listening, move on
if [[ -z ${pids[0]} ]];
then
echo "No process listening on port $targetPort"
## If any processes were listening, kill them.
else
echo "killing process(es) listening on port $targetPort"
## First, try to kill the process gracefully
kill "${pids[@]}"
## Check if any are still running
for pid in "${pids[@]}"; do
## If it is still running
if kill -0 "$pid"; then
## Kill it with fire
kill -9 "$pid"
fi
done
fi
}
现在可以接受一个参数,因此运行它来checkport
检查端口 2020,并将checkport 22
检查端口 22。它还首先尝试正常终止(kill -9
除非绝对必要,否则您应该始终避免),并且仅kill -9
在失败时使用。