我正在从不同的路径运行 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
需要注意的一个警告是,如果进程 ID 是内核线程或不属于您,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
这有效地向您需要的进程发送终止信号。如果您想要一个带有参数的简短命令,您可以将其包装在 bash 脚本中。