Присвоенная переменная для конвейера не работает

У меня есть сценарий оболочки для проверки состояния порта. После проверки порта, если это занято затем, уничтожит его.

#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
задан 7 December 2018 в 13:39

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. Это также первые попытки уничтожить корректно (ou должен всегда избегать kill -9 если абсолютно необходимый), и только использует kill -9 если это перестало работать.

2
ответ дан 7 December 2019 в 13:20

Другие вопросы по тегам:

Похожие вопросы: