Ste*_*eve 3 shell ssh xargs awk quoting
我正在检索我想要杀死的两个 PID 的列表。我的管道看起来像
ps -ef | grep foo | grep -v grep | awk {'print $2'} | xargs kill -9
在本地执行此操作时,两个进程都会被终止。但是当将它与 ssh 一起使用时
ssh foo@<IP Address> "ps -ef | grep foo | grep -v grep | awk {'print $2'} | xargs kill -9"
两个PID中只有一个被删除。它输出kill: <PID>: No such process
. 是否试图在本地杀死第二个进程?
该$2
是本地shell命令行上双引号内,由当地壳所以扩展(可能为空字符串)。
所以在远程主机上运行的命令是这样的:
ps -ef | grep foo | grep -v grep | awk {'print '} | xargs kill -9
Run Code Online (Sandbox Code Playgroud)
该awk
命令是空操作(打印所有行),xargs
最终将运行:
kill -9 <all-the-words-present-in-the-output-of-ps|grep...>
Run Code Online (Sandbox Code Playgroud)
这包括pid和ppid,用户名...
此外,如果 kill 命令的 pid 在该列表中,它将杀死自己,因此无法杀死列表中的其余命令。
在这里,你会想要:
ssh foo@<IP Address> 'pkill -KILL -f foo'
Run Code Online (Sandbox Code Playgroud)
(杀死其命令行(至少它的前几千字节)包含的所有进程foo
)。
或者如果远程系统没有pkill
命令:
ssh foo@<IP Address> '
ps -Ao pid= -o args= |
awk "/[f]oo/ {print \$1}" |
xargs kill -s KILL'
Run Code Online (Sandbox Code Playgroud)
我们在本地端使用单引号(所以那里没有变量扩展),并在远程 shell 命令行中对 awk 代码使用双引号,所以我们需要对$
in进行转义,$1
以便它不会被远程 shell 扩展。
awk
是 的超集grep
,您通常不需要将它们通过管道连接在一起。最好是告诉ps
只输出你想要匹配的东西,这里假设你想foo
在 ps 显示的参数列表中搜索你的使用-f
建议。
如果你想杀死远程用户的所有进程(这里是用户 foo 和 sshing 为 foo),你可以这样做:
ssh foo@<IP Address> 'kill -s KILL -- -1'
Run Code Online (Sandbox Code Playgroud)
这将杀死用户有权杀死的所有进程。对于普通用户来说,就是所有进程的真实或保存的设置用户id与被杀进程的真实或有效用户id相同的进程。
或者:
ssh foo@<IP Address> 'pkill -KILL -U "$(id -u)"'
Run Code Online (Sandbox Code Playgroud)
(或pkill -U foo
)。杀死所有真实用户 id 与远程用户的有效用户 id 相同的进程。
或者你可以这样做:
ssh foo@<IP Address> '
trap "" HUP
ps -Ao sid= -o pid= -U "$(id -u)" |
awk "\$1 != $(ps -eo sid= -p "\$\$") {print \$2}" |
xargs kill -s KILL'
Run Code Online (Sandbox Code Playgroud)
(检查sid
以便kill
不会杀死自身、外壳awk
或xargs
,并忽略 SIGHUP 以防杀死用户sshd
进程导致发送该信号)
我们假设远程用户的登录 shell 类似于 Bourne。如果远程用户的登录 shell 是具有不同语法的 csh 或 rc 系列,则必须调整这些命令。
更好的做法是通过名称而不是编号来引用信号,因为这样会更清晰,并且信号编号可以随系统变化(尽管 SIGKILL 为 9 是非常普遍的)。
归档时间: |
|
查看次数: |
10752 次 |
最近记录: |