Bash - 转义 SSH 命令

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16887513/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 05:35:08  来源:igfitidea点击:

Bash - Escaping SSH commands

bashssh

提问by Dan

I have a set of scripts that I use to download files via FTP and then delete them from the server.

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

It works as follows:

它的工作原理如下:

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 [email protected] mv -v "'/home/dan/Downloads/complete/$dir'" /home/dan/Downloads/downloaded

Now $dir could be "This is a file" which works fine.

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

The problem I'm having is with special characters eg:

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

  • "This is (a) file"
  • This is a file & stuff"
  • “这是(a)文件”
  • 这是一个文件和东西”

tend to error:

容易出错:

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'

I can't work out how to escape it so both the variable gets evaluated and the command gets escaped properly. I've tried various combinations of escape characters, literal quotes, normal quotes, etc

我无法弄清楚如何转义它,因此变量都会被评估并且命令会被正确转义。我尝试了转义字符、文字引号、普通引号等的各种组合

回答by Will Palmer

If both sides are using bash, you can escape the arguments using printf '%q ', eg:

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

ssh [email protected] "$(printf '%q ' mv -v "/home/dan/Downloads/complete/$dir" /home/dan/Downloads/downloaded)"

回答by fedorqui 'SO stop harming'

You need to quote the whole expression ssh user@host "command":

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

ssh [email protected] "mv -v /home/dan/Downloads/complete/$dir /home/dan/Downloads/downloaded"

回答by Old Pro

I'm confused, because your code as written works for me:

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

> 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

For debugging, use set -vxat the top of the script to see what's going on.

对于调试,set -vx在脚本顶部使用以查看发生了什么。

回答by antak

Will Palmer's suggestion of using printfis great but I think it makes more sense to put the literal parts in printf's format.

Will Palmer 的使用建议printf很好,但我认为将文字部分放在printf's 格式中更有意义。

That way, multi-command one-liners are more intuitive to write:

这样,多命令单行程序编写起来更直观:

ssh user@host "$(printf 'mkdir -p -- %q && cd -- "$_" && tar -zx' "$DIR")"