管道分配的变量不起作用

管道分配的变量不起作用

我有一个 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 -9if,它就可以正常工作。这里的错误是什么?

我收到的错误:

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在失败时使用。

相关内容