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

标签 linux bash ssh

我遇到了一个非常奇怪的行为。我发现了似乎可以解决的问题,但我希望有人可以向我解释为什么我会看到这种疯狂的行为。

我正在做的事情的概要:我想要一个 shell 脚本来停止我的进程。我希望它足够健壮,能够终止我正在寻找的进程的一个或多个实例。如果没有进程在运行,我不希望它失败(这意味着我想要一个 0 返回码……而不是传递给 kill 命令的空 arg 列表)

我看到的是,通过 ssh 传递命令调用脚本时,脚本的行为与在本地执行相同脚本时的行为不同。非常奇怪的是,通过向我的 ssh 命令添加一个看似任意的命令,我能够让我的脚本正确执行,我不知道为什么!

stop scipt(echo statments 在那里帮助我调试 - 不是真实脚本的一部分)

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

没有进程运行时本地执行脚本的结果:

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 已经消失。

现在 - 这是带有额外“date | grep crap”的 SAME ssh 命令:

命令:

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 脚本中随机留下这样一个金 block 呢???没有人会知道为什么会这样。连我也不行!如果有人遇到过这个请帮助!

最佳答案

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

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

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

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

关于linux - 当本地相同的脚本成功时,通过 ssh 运行脚本失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27115381/

相关文章:

python - 有没有办法同时使用 fabric run() 和 sudo() ?

node.js - Joyent no.de 和 Cloud9 ide

linux - 在整个目录上运行 bash 脚本

linux - 如何更改备份在 Ubuntu 16.04 中创建备份的时间?

c - 静态变量的地址在运行时改变

linux - 如何在没有 dpkg、apt 和 ar 的情况下安装 dpkg

linux - 在可能具有重复文件名的目录中移动多个文件

java - maven 安装后运行脚本

Bash:如何检查目录是否存在?

git - ansible git clone 权限被拒绝问题