Bash - 转义SSH命令

时间:2013-06-02 21:31:29

标签: bash ssh

我有一组脚本用于通过FTP下载文件,然后从服务器中删除它们。

它的工作原理如下:

for dir in `ls /volume1/auto_downloads/sync-complete`
do
if [ "x$dir" != *"x"* ]
then
echo "DIR: $dir"

echo "Moving out of complete"
        # Soft delete from server so they don't get downloaded again
        ssh dan@172.19.1.15 mv -v "'/home/dan/Downloads/complete/$dir'" /home/dan/Downloads/downloaded

现在$ dir可能是“这是一个文件”,工作正常。

我遇到的问题是特殊字符,例如:

  • “这是(a)档案”
  • 这是一个文件&东西“

倾向于错误:

bash: -c: line 0: syntax error near unexpected token `('
bash: -c: line 0: `mv -v '/home/dan/Downloads/complete/This is (a) file' /home/dan/Downloads/downloaded'

我无法弄清楚如何逃避它,因此变量得到评估并且命令被正确转义。我尝试了各种转义字符,字面引号,正常引号等组合

5 个答案:

答案 0 :(得分:17)

如果双方都在使用bash,您可以使用printf '%q '来转义参数,例如:

ssh dan@172.19.1.15 "$(printf '%q ' mv -v "/home/dan/Downloads/complete/$dir" /home/dan/Downloads/downloaded)"

答案 1 :(得分:1)

您需要引用整个表达式ssh user@host "command"

ssh dan@172.19.1.15 "mv -v /home/dan/Downloads/complete/$dir /home/dan/Downloads/downloaded"

答案 2 :(得分:0)

我很困惑,因为你写的代码对我有用:

> dir='foo & bar (and) baz'
> ssh host  mv -v "'/home/dan/Downloads/complete/$dir'" /home/dan/Downloads/downloaded
mv: cannot stat `/home/dan/Downloads/complete/foo & bar (and) baz': No such file or directory

要进行调试,请使用脚本顶部的set -vx来查看正在进行的操作。

答案 3 :(得分:0)

Palmer建议使用printf是否很好,但我认为将文字部分放在ssh user@host "$(printf 'mkdir -p -- %q && cd -- "$_" && tar -zx' "$DIR")" 的格式中会更有意义。

这样,多命令单行编写更直观:

>>> [name for name in names if any(substring in name for substring in wanted_list)]
['aet2000', 'xxx2001']

答案 4 :(得分:0)

一个人可以使用python shlex.quote(s)

返回字符串s的脱机转义版本

docs