
Я запускаю 3 приложения с одинаковым именем файла из разных путей:
$ ~/app1/main
$ ~/app2/main
$ ~/app3/main
Я хочу создать bash-скрипт, который принимает полное имя исполняемого файла и завершает это приложение.
$ ./my_killer.sh /home/me/app2/main
Как это сделать, в частности, как завершить приложение по его полному имени?
решение1
Если вам нужна поддержка только Linux (что, как я полагаю, и происходит, учитывая, что ваш вопрос помечен как linux), вы можете воспользоваться символическими /proc/%d/exe
ссылками.
Вот пример того, как может выглядеть сценарий, который это может сделать.
#!/bin/bash
if [ "$#" != 1 ] || [ "$1" = "" ]
then
echo "Usage: $0 <full-exe-path>" 1>&2
exit 1
fi
shopt -s extglob
cd /proc
for PID in [1-9]*([0-9])
do
if [ "$(readlink "$PID"/exe)" = "$1" ]
then
kill "$PID"
fi
done
Одно предостережение, которое следует отметить, заключается в том, что если идентификатор процесса является потоком ядра или не принадлежит вам, readlink
произойдет сбой и "$(readlink "$PID"/exe)"
будет оценен как пустая строка. Чтобы избежать попытки убить все эти процессы, скрипт откажется что-либо делать, если $1
это пустая строка.
Также обратите внимание, что этот скрипт использует , extglob
который позволяет сопоставлять каталоги с , [1-9]*([0-9])
который означает символ в интервале 1-9
, за которым следует любое количество символов в интервале 0-9
.
решение2
Я делаю это в одну строку с кантом (вам понадобится gawk
и xargs
):
$>ps -ax | grep "/app2/main" | grep -v "grep" | gawk '{print $1}' | xargs kill
что здесь происходит?
ps -ax # — list all processes in extended format
grep "/app2/main" # — show only processes that contain "/app2/main"
grep -v "grep" # — sort out the previous grep process with the mentioned string
gawk '{print $1}' # — use gawk to pick only the first column (process id)
xargs kill # — use xargs to pass pid to kill as an argument
Это фактически посылает сигнал kill нужному вам процессу. Вы можете обернуть его в скрипт bash, если вам нужна короткая команда с аргументом.