从ssh进程读取pid来自不同服务器的grep输出

时间:2017-02-05 18:26:19

标签: bash ssh

读取来自每个服务器的进程grep管道命令的PID并将其终止。 当我运行以下代码片段时 - 它会显示与其余服务器的第一个主机相同的ID。换句话说,它不会更新新的PID

for h in host1 host2 host3
do
  if [ $(hostname -s) = $h ]; then
    PID=$(echo "`ps -ef | grep x_user | grep x_project | grep JMX_SCRIPT.PID=webservice | grep '/bin/bash' | awk '{print $2;}'`")
  else
    PID=$(ssh $h "echo \"`ps -ef | grep x_user | grep x_project | grep JMX_SCRIPT.PID=webservice | grep '/bin/bash' | awk '{print $2;}'`\"")
  fi

  echo "Killing pid - $PID... on $h"
  sleep 5
done

输出如下:

Killing pid - 18334... on host_1
Killing pid - 18334... on host_2
Killing pid - 18334... on host_3

专家 - 我在这里做错了什么?在此先感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

问题在于您的ssh命令:

PID=$(ssh $h "echo \"`ps -ef | grep x_user | grep x_project | grep JMX_SCRIPT.PID=webservice | grep '/bin/bash' | awk '{print $2;}'`\"")

ps -ef ...部分正在本地主机上运行,​​而不是远程主机。这就是你每次获得相同PID的原因。

您可以通过将命令管道存储在文件或字符串中并将其提供给ssh来解决此问题。

答案 1 :(得分:0)

你的问题来自引用。在引号内引用是很棘手的,做你想做的事情的最好方法通常是完全取消引用内部引号。

首先,将远程命令放在一个数组中:

declare -a remote_command=()
remote_command+=(ps -ef '|' grep x_user '|' grep x_project '|')
remote_command+=(grep JMX_SCRIPT.PID=webservice '|' grep '/bin/bash')
remote_command+=('|' awk '{print $2;}')

然后,像这样运行:

PID="$(ssh $h "${remote_command[@]}")"

数组扩展将执行您所需的操作,即单独提供每个参数,但不执行扩展或分词。特别是"管道"符号(|)不会在本地解释,但会作为参数传递给ssh命令,并将远程解释为管道。

顺便说一句,这种技术的一个优点是,由于您的命令是以编程方式构建的,因此您可以轻松地包含或不包含可选部分(即参数),例如,带有{{1的简单if块语句,对容易出错的引用仍然没有问题。