我有一些进程在本地和同一主机上的 docker 容器中运行。由于我运行多个具有相同名称的进程,我想创建一个别名/函数,它允许我杀死主机上运行的所有进程,但忽略在 docker 中运行的进程。
我现在使用的命令具有以下形式:
kill $(ps aux | grep 'process_name' | awk '{print $2}')
我注意到这个命令杀死了所有正在运行的容器中具有相同名称的进程,这使得它们崩溃。我怎样才能防止这种情况发生?
这是主机上的进程的样子(作为 ps aux 的结果):
hamzam 9109 0.9 0.0 510912 24732 ? Ssl 14:21 0:00 python /opt/scripts/ex_script __name:=process_name __log:=/home/hamzam/.logs/0286c734-71fd-11e7-9dc4-901b0ed728a7/process_name-3.log
这是在容器之一中运行的进程:
hamzam 12168 2.3 0.0 472708 64312 ? Ssl 14:22 0:00 python /opt/scripts/ex_script __name:=process_name __log:=/home/logs/0/126e36dc-71fd-11e7-bd98-0242ac110003/process_name-3.log
答案1
pkill
有--ns pid
和--nslist name...
选项,可用于限制终止将影响哪些命名空间。
--ns pid
与 bash 内置变量 结合得很好,$$
它等于当前 shell 的 PID。
例如,在我的一个系统上,我在 docker 中运行一个 gitlab 实例,它在该容器中运行的服务之一是 redis:
# ps u -C redis-server
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
997 30006 0.1 0.0 35504 2896 ? Ssl 16:05 0:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
记下 PID,30006。
如果我使用 pkill 的-ns $$
选项,那么它不会被杀死,因为它与我的 shell 位于不同的命名空间中。注意 PID 没有改变——这表明它没有被杀死并重新启动。
# pkill --ns $$ redis-server
# ps u -C redis-server
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
997 30006 0.1 0.0 35504 2896 ? Ssl 16:05 0:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
如果我不使用该选项,那么(不出所料)它将被杀死。
# pkill redis-server
# ps u -C redis-server
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
997 459 0.5 0.0 35504 2896 ? Ssl 16:11 0:00 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
redis-server的PID现在是459。它已经被杀死并重新启动。
顺便说一句,pgrep
支持相同的选项,因此很容易获取同一命名空间中其他进程的列表。例如,向pgrep -a --ns 459
我展示了与上面的 redis-server 相同的命名空间中运行的所有进程。
ps
还有各种输出格式选项用于显示命名空间详细信息。例如:
# ps -o pidns,pid,cmd -C redis-server
PIDNS PID CMD
4026532661 459 /opt/gitlab/embedded/bin/redis-server 127.0.0.1:0
从man ps
:
pidns PIDNS
描述进程所属命名空间的唯一索引节点号。请参阅命名空间(7)。