我正在经历一种非常奇怪的行为。我发现似乎是一种解决方法,但我希望有人可以向我解释为什么我会看到这种疯狂的行为。
我正在做的事情的高级别:我想要一个shell脚本来阻止我的进程。我希望它足够强大,可以杀死我正在寻找的过程的一个或多个实例。如果没有进程正在运行,我不希望它失败(意味着我想要一个0返回代码......不是传递给kill命令的空arg列表)
我所看到的是,通过ssh传递命令调用脚本的行为与在本地执行相同脚本时的行为不同。非常奇怪的是,通过在我的ssh命令中添加一个看似随意的命令,我能够让我的脚本正确执行,我不知道为什么!
停止scipt(echo声明可以帮助我调试 - 不是真实脚本的一部分)
echo "Stopping myProcess" echo "-->
ps aux | grep myProcess | grep -v grep" pid=
ps -ef | grep myProcess | grep -v grep | awk'{print $ 2}'echo "Here: ${pid}" if [[ ! -z $pid ]]; then echo "Here2" kill -9 $pid else echo "Here3" echo "not stopping anything - no myProcess process running." fi echo "Here4" exit 0
当NO进程正在运行时本地执行脚本的结果:
Stopping myProcess --> Here: Here3 not stopping anything - no myProcess running. Here4
通过以下命令从其他计算机执行脚本的结果:
命令:
ssh eak0703 @ myServer'source $ {HOME} /.bash_profile; cd / usr / local / myprocess / bin /;./ stop-myProcess'
结果:
Stopping myProcess --> eak0703 2099 0.0 0.0 10728 1500 ? Ss 17:08 0:00 bash -c source ${HOME}/.bash_profile;cd /usr/local/myProcess/bin/;./stop-myProcess eak0703 2100 0.0 0.0 10740 992 ? S 17:08 0:00 bash -c source ${HOME}/.bash_profile;cd /usr/local/myProcess/bin/;./stop-myProcess eak0703 2101 0.0 0.0 10740 668 ? S 17:08 0:00 bash -c source ${HOME}/.bash_profile;cd /usr/local/myProcess/bin/;./stop-myProcess Here: 2099 2100 2105 Here2
注意:对于一些奇怪且无法解释的原因,我的命令似乎有3次调用。我也知道这个命令不会以退出代码0终止。我假设这是因为当调用kill -9时,grep拾取的进程ID就不见了。
现在 - 这是SAME ssh命令,其中包含额外的“date | grep crap”:
命令:
ssh eak0703 @ myServer'source $ {HOME} /.bash_profile; cd / usr / local / myprocess / bin /; date | grep crap; ./ stop-myProcess'
结果:
Stopping myProcess --> Here: Here3 not stopping anything - no myProcess running. Here4
使用“date | grep crap”修复问题。似乎魔术在“|” (管道)操作员。所以我实际上能够使用“anycommand | anyothercommand”来完成这项工作。
我可以使它工作 - 但我怎么能证明随机在bash脚本中留下这样的金块?没有人会知道为什么会这样。甚至不是我!如果有人遇到这个,请帮忙!
答案 0 :(得分:2)
解析ps
以查找进程是脆弱且容易出错的。你的例子很好地说明了原因:
一个不相关的进程(由bash
启动的ssh
进程)包含进程名称作为命令行的一部分,并且被ps
解析器意外地接收。
当您使命令行包含单词“grep”时,grep -v grep
将删除不相关的进程。
相反,只需使用pgrep
或pkill
即可。这些工具基于可执行文件名列出/终止进程,因此比解析ps
更加健壮。