【问题标题】:quoting and escaping of a ssh command line [duplicate]引用和转义 ssh 命令行 [重复]
【发布时间】:2016-08-25 14:21:43
【问题描述】:

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

$  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 样式的输出重定向,如命令的 >/var/tmp/1.ouy 2>&1。

感谢您的帮助。

【问题讨论】:

  • 谢谢。我遵循该规则,但仍然无法使其工作。查看上面的更新
  • ssh rmthost "ps -ef |grep \"\&lt;defunct\&gt;\"|grep -v grep| awk '{print \$1}' " 有什么问题 - 还是我在这里遗漏了什么?即,通过将 ssh 的参数用双引号括起来,可以避免所有的尴尬。
  • bash -c 在这里也是多余的。 ssh 会将命令字符串发送到 shell 本身,从而为您节省整个转义级别。
  • 我忘了说我需要 bash -c 来启用 bash 样式的输出重定向 > /var/tmp/1.out 2>&1.用户的登录 shell 是 rmthost 上的 csh
  • 我强烈建议学习 awk 以避免过多的`grep | grep | awkawk 可以为您完成所有这些工作。

标签: bash


【解决方案1】:

说实话,我看不懂你写的代码。它太模糊了,我没有半小时的时间来弄清楚。为此,它很可能不是好的代码。

当您尝试理解多层解码时,这样的引用会变得非常混乱。因此,我不会尝试更正您的报价,而是尝试提供具有相同结果的更简洁的代码。

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}'

但是,为什么不尝试删除一些过多的 grep 管道。 awk 可以为你做过滤。我假设&lt;defunct&gt; 出现在行尾。如果是这样,那么您可以使用:

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}'

【讨论】:

  • 第一个命令出现“变量语法”错误,第二个命令出现“awk:第 1 行附近的语法错误 awk:第 1 行附近的非法语句”。
  • 这很奇怪,它在我的系统上运行良好。我在扁平示例中进行了编辑。我建议登录到远程系统并检查它们是否首先工作。这是非常简单的 awk 语法,所以我不相信 awk 有什么问题,但听起来好像是在扁平化引号时发生了一些奇怪的事情。
【解决方案2】:

这是一个使用引号的有效解决方案:

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

但是,我自己不太了解机制:-)。如果你交换单引号和双引号,它就不起作用。

【讨论】:

  • 无法重现您的“不匹配”错误。既然您似乎有一个可行的解决方案,我现在放弃了。
猜你喜欢
  • 2021-10-09
  • 2013-03-12
  • 2014-08-21
  • 2013-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-02
  • 2018-10-19
相关资源
最近更新 更多