Уничтожить запущенные экземпляры процессов, за исключением тех, которые вызваны текущей выполненной командой.

Уничтожить запущенные экземпляры процессов, за исключением тех, которые вызваны текущей выполненной командой.

Мне нужно завершить все запущенные экземпляры Xvfb с помощью скрипта оболочки, поэтому у меня есть следующий код:

for pid in $(ps -ef | awk '/Xvfb/ {print $2}'); do kill -9 $pid; done

Он убивает все экземпляры, но один из них завершается со следующей ошибкой:

kill: (142898) - No such process

Кажется, выше выполненная команда создает еще один экземпляр, но который больше не существует при убийстве. В этом случае, как я могу пропустить это и успешно выполнить скрипт?

решение1

Проблема в том, что вы передаете вывод psв вызов, awkкоторый ищет строку "Xvfb" и, следовательно, также содержит строку "Xvfb" в своей собственной командной строке. Поскольку оба процесса конвейера выполняются одновременно, awkсам вызов также будет зарегистрирован в выводе ps(попробуйте, что произойдет, если вы просто введете ps -ef | awk '/Xvfb/'в командной строке).

Однако к моменту запуска цикла (что происходит, когда подстановка команды $( … ), а следовательно awk, и процесс тоже завершаются), этот awkпроцесс уже не существует, поэтому killнатыкаемся на это.

Вы будете в безопасности, если измените команду в подстановке команд на

ps -ef | awk '$0 ~ /Xvfb/ && index($0,"awk")==0 {print $2}'

что гарантирует, что ни одна команда, содержащая подстроку, не awkбудет включена в список.

решение2

Вы пытаетесь убить awk.

Простой трюк с регулярными выражениями, позволяющий избежать этого, — использовать какой-либо вид экранирования. Например wor[d], .

Итак, для вашего кода (с добавлением кавычек переменных)

for pid in $(ps -ef | awk '/Xvf[b]/ {print $2}'); do kill -9 "$pid"; done

Связанный контент