引用和转义ssh命令行

时间:2016-04-30 12:33:49

标签: bash

以下命令看起来已正确引用和转义:

$  echo -e ssh -q rmthost 'bash -c "ps -ef|grep '\'''\\\<'defunct'\\\>''\''|grep -v grep|awk '\'''{print \$1}''\'' "'
ssh -q sbpsvrwm757 bash -c "ps -ef|grep '\<defunct\>'|grep -v grep|awk '{print $1}' "

但是在执行时,结果不是预期的结果:

$   ssh -q rmthost 'bash -c "ps -ef|grep '\'''\\\<'defunct'\\\>''\''|grep -v grep|awk '\'''{print \$1}''\'' "'
    root16986 16982   0        - ?           0:01 <defunct>

awk命令似乎没有提取正确的列。

现在我按照Siguza提供的链接提出了:

$  echo ssh -q rmthost "'"bash -c '"ps -ef|grep '"'\<defunct\>'|grep -v grep|awk '{print \$1}'"'"'"'"
ssh -q rmthost 'bash -c "ps -ef|grep '\<defunct\>'|grep -v grep|awk '{print $1}'"'

看起来也完全逃脱了,但仍然不起作用:

$  ssh -q rmthost  "'"bash -c '"ps -ef|grep '"'\<defunct\>'|grep -v grep|awk '{print \$1}'"'"'"'"
Missing }

,或者

$  echo ssh -q rmthost  bash -c '"ps -ef|grep '"'\<defunct\>'|grep -v grep|awk '{print \$1}'"'"'
ssh -q rmthost  bash -c "ps -ef|grep '\<defunct\>'|grep -v grep|awk '{print $1}'"
$  ssh -q rmthost  bash -c '"ps -ef|grep '"'\<defunct\>'|grep -v grep|awk '{print \$1}'"'"'
   root 16986 16982   0        - ?           0:01 <defunct>

,或者

$  echo ssh -q rmthost  "bash -c \"ps -ef |grep '\<defunct\>'|grep -v grep| awk '{print \$1}'\""
ssh -q rmthost  bash -c "ps -ef |grep '\<defunct\>'|grep -v grep| awk '{print $1}'"
$  ssh -q rmthost  "bash -c \"ps -ef |grep '\<defunct\>'|grep -v grep| awk '{print \$1}'\""
  root 16986 16982   0        - ?           0:01 <defunct>

任何想法为什么?

请注意,我需要使用bash -c为命令启用bash样式的输出重定向,例如&gt; /var/tmp/1.ouy 2&gt;&amp; 1。

感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

我会说实话,我看不懂你写的代码。这太混淆了,我没有半个小时才弄清楚。为此,它很可能不是很好的代码。

当您尝试理解多层解码时,这样的行情会变得非常混乱。因此,我不会尝试更正您的引号,而是尝试使用相同的结果来提供更清晰的代码。

ssh rmthost "bash -c \"ps -ef | grep '<defunct>' | grep -v grep | awk '{print \\\$2}'\""

# The remote system will execute this:
bash -c "ps -ef | grep '<defunct>' | grep -v grep | awk '{print \$2}'"

# Which in tells bash to execute this:

ps -ef | grep '<defunct>' | grep -v grep | awk '{print $2}'

然而,为什么不尝试删除一些exessive grep管道。 awk可以为您进行过滤。我假设<defunct>出现在该行的末尾。如果是这样,那么你可以使用:

ssh rmthost "bash -c \"ps -ef | awk '/<defunct>\\\$/ {print \\\$2}'\""

# the remote system executes this:
bash -c "ps -ef | awk '/<defunct>\$/ {print \$2}'"

# bash executes this:
ps -ef | awk '/<defunct>$/ {print $2}'

或者更好的是,使用ps -el中的第二列,对于僵尸进程将是Z

ssh rmthost "bash -c \"ps -el | awk '/^. Z / {print \\\$4}'\""

# the remote system executes this
bash -c "ps -el | awk '/^. Z / {print \$4}'"

# bash executes this:
ps -el | awk '/^. Z / {print $4}'

答案 1 :(得分:0)

这是一个使用引号的工作解决方案:

ssh -q rmthost "bash -c 'ps -ef|grep ''''\<'defunct'\>''''|grep -v grep|awk "'"{print \$2}"'" '"
然而,我自己并不完全理解这个机制:-)。如果换掉单引号和双引号,它就不起作用。