You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bash脚本无法杀死SSH远程会话启动进程的问题求助

问题根源:本地Shell提前解析了远程命令

我太懂这个坑了!你脚本里的问题核心在于:当用<< EOF这种Here Document时,里面的命令替换($(...))会被你的本地Shell先解析,而不是传到远程机器执行。

举个例子,你第一个脚本里的kill $(pidof tshark),本地Shell会先跑一遍pidof tshark,拿到你本地机器上的tshark进程PID(如果本地没跑tshark,就是空值),然后把这个PID传到远程执行kill xxx——这显然杀的不是远程的tshark进程,自然没用!

第二个脚本里的pid=$(ps -ef | grep tshark.sh ...)也是同样的道理,本地Shell先执行了这个过滤命令,拿到的是本地的进程PID,传到远程去kill,完全是南辕北辙。

而你手动SSH的时候,所有命令都是在远程Shell里执行的,pidof tshark拿到的是远程的PID,所以能正常杀掉。

几种可行的解决方案

下面给你几个靠谱的写法,按简洁度排序:

1. 用单引号包裹Here Document分界符(最省心)

把<< EOF改成<< 'EOF',这样整个Here Document里的内容会被当作纯文本,本地Shell不会解析任何变量或命令替换,原封不动传给远程执行:

# 启动tshark进程
ssh localadmin@10.101.30.61 &>/dev/null << 'EOF'
tshark -i ens160 -w /home/localadmin/dns_traffic_61.pcap &>/dev/null &
EOF

# 杀死tshark进程
ssh localadmin@10.101.30.61 &>/dev/null << 'EOF'
kill $(pidof tshark)
EOF

2. 直接用SSH命令行传参(最简洁)

对于短命令,不用Here Document,直接把命令用单引号包裹传给SSH,本地Shell不会解析单引号里的内容:

# 启动进程
ssh localadmin@10.101.30.61 'tshark -i ens160 -w /home/localadmin/dns_traffic_61.pcap &>/dev/null &'

# 杀死进程
ssh localadmin@10.101.30.61 'kill $(pidof tshark)'

3. 转义命令替换符号

如果不想改分界符,也可以把$(...)里的$转义成\$,让本地Shell跳过解析:

ssh localadmin@10.101.30.61 &>/dev/null << EOF
kill \$(pidof tshark)
EOF

4. 用pkill简化操作(更可靠)

如果不需要精准到单个PID,直接用pkill tshark可以一键杀死所有tshark进程(适合你只启动了一个的场景):

ssh localadmin@10.101.30.61 'pkill tshark'

5. 记录PID到文件(最稳妥)

如果担心误杀其他tshark进程,启动时把PID写入临时文件,杀进程时读取这个文件:

# 启动并记录PID
ssh localadmin@10.101.30.61 'tshark -i ens160 -w /home/localadmin/dns_traffic_61.pcap &>/dev/null & echo $! > /tmp/tshark.pid'

# 读取PID并杀死,最后删除临时文件
ssh localadmin@10.101.30.61 'kill $(cat /tmp/tshark.pid); rm /tmp/tshark.pid'

这里的$!是上一个后台进程的PID,能精准定位你启动的那个tshark。

验证小技巧

可以先远程查看PID,确认命令能拿到正确的值:

ssh localadmin@10.101.30.61 'pidof tshark'

如果返回了有效的PID,再执行kill命令就肯定没问题了。

内容的提问来源于stack exchange,提问作者Giannis Pappas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:32:54