当本地相同的脚本成功时,通过ssh运行脚本失败

时间:2014-11-24 22:29:10

标签: linux bash ssh

我正在经历一种非常奇怪的行为。我发现似乎是一种解决方法,但我希望有人可以向我解释为什么我会看到这种疯狂的行为。

我正在做的事情的高级别:我想要一个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脚本中留下这样的金块?没有人会知道为什么会这样。甚至不是我!如果有人遇到这个,请帮忙!

1 个答案:

答案 0 :(得分:2)

解析ps以查找进程是脆弱且容易出错的。你的例子很好地说明了原因:

一个不相关的进程(由bash启动的ssh进程)包含进程名称作为命令行的一部分,并且被ps解析器意外地接收。

当您使命令行包含单词“grep”时,grep -v grep将删除不相关的进程。

相反,只需使用pgreppkill即可。这些工具基于可执行文件名列出/终止进程,因此比解析ps更加健壮。