如何通过SSH传递包含特殊字符的命令?

时间:2017-11-15 16:42:25

标签: regex awk ssh escaping

我想从Jenkins运行以下命令:

ssh -i ~/.ssh/company.pem -o StrictHostKeyChecking=no user@$hostname "supervisorctl start company-$app ;  awk -v app=$app '$0 ~ "program:company-"app  {p=NR} p && NR==p+6 && /^autostart/ {$0="autostart=true" ; p=0} 1' /etc/supervisord.conf > $$.tmp && sudo mv $$.tmp /etc/supervisord.conf”

这是创建CloudFormation堆栈的作业的最后一步。

从目标服务器的终端运行命令可以正常工作。

在此步骤中,我希望ssh到每个服务器(新堆栈中的ASG成员)并搜索并替换{{1}中所示的特定行。 ,基本上将一个特定服务设置为自动启动。

当我运行命令时,我收到以下错误:

/etc/supervisord.conf

我试过逃避双引号但得到同样的错误,不知道我做错了什么?

1 个答案:

答案 0 :(得分:0)

由于shell处理嵌套引号的方式,您正在遇到此问题。这是 HERE DOCUMENT heredoc 的用例 - HERE DOCUMENT 允许您编写通过bash传递的多行命令而无需担心引号。结构如下:

$ ssh -t user@server.com <<'END'
command |\
command2 |\
END

&lt; ---哦,是的, -t 对ssh命令很重要,因为它让shell知道行为就好像是以交互方式使用,并且会避免警告和意外结果

在您的具体情况下,您应该尝试以下方式:

$ ssh -t -i ~/.ssh/company.pem -o StrictHostKeyChecking=no user@$hostname <<'END'
supervisorctl start company-$app |\
awk -v app=$app '$0 ~ \"program:company-\"app  {p=NR} p && NR==p+6 \
&& /^autostart/ {$0="autostart=true" ; p=0} 1' \
/etc/supervisord.conf > $$.tmp && sudo mv $$.tmp /etc/supervisord.conf
END

只是一个注释,因为我无法确定您所运行的命令的所需输出,建议您跟踪自己的"'标记,并逃避它们相应地在您的awk命令中,就像在交互式终端上一样。我注意到"周围的program:company并且我对它们感到困惑如果它们是被搜索字符串中的模式的一部分,则需要相应地进行转义。附: