当通过ssh传递时,为什么带引号的空格命令不起作用? [英] Why doesn't a command with quoted whitespace work when passed over ssh?

查看:471
本文介绍了当通过ssh传递时,为什么带引号的空格命令不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建此项目,在该项目中必须使用ssh执行UNIX命令。这是我的问题:在UNIX shell中执行以下命令时,

I am building this project in which I have to execute UNIX commands using ssh. Here is my question : When I execute the following command in a UNIX shell,

echo "Hello           World"

它产生输出:

Hello           World

参数之间有5个空格用双引号引起来。我也想通过ssh达到相同的效果。我试图使用反斜杠转义双引号,如下所示:

With 5 spaces in between as the arguments were given within double quotes. I want to achieve the same effects with ssh as well. I am trying to escape the double quotes using backslash as follows :

ssh localhost echo \"Hello           World\"

因为我不希望bash处理报价。但这只会产生

as I do not want bash to process the quotes. But it just produces

Hello           World

Hello之后只有一个空格
为什么?

There is only one space after "Hello" Why is that?

推荐答案

ssh 执行一个命令,该命令是通过调用远程shell给出的,该脚本由脚本组成,该脚本由完整的本地参数集以及它们之间的空格组成。

ssh executes a command it's given by invoking a remote shell with a script composed of the full set of local arguments concatenated together with whitespace between them.

如果您运行:

# This has only syntactic quotes -- none of the quotes are literal.
ssh somehost echo "Hello   World"

..然后将此参数列表传递给 ssh (使用C语法,不包括主机名和ssh命令本身)为 { echo, Hello World,NULL}

..then this list of arguments passed to ssh (in C syntax, excluding the hostname and the ssh command itself) is { "echo", "Hello World", NULL }.

连接成一个字符串,然后变成 echo Hello World

Concatenated together into a string, this then becomes "echo Hello World".

因此,远程shell运行 echo Hello World ,它没有语法引号。

Thus, the remote shell runs echo Hello World, which has no syntactic quotes.

如果您运行:

ssh somehost echo \"Hello   World\"

...然后是命令列表(再次使用C语法)是 { echo, \ Hello, World\,NULL} :引号是文字,但空格已由本地外壳程序删除(在运行SSH之前)在分词过程中。

...then the list of commands (again, in C syntax) is { "echo", "\"Hello", "World\"", NULL }: The quotes are literal, but the spaces were removed by the local shell (before SSH was run) during the word-splitting process.

连接到字符串中后,它会成为 echo Hello World 。因此,您得到的是报价,但是却失去了空格。

Concatenated into a string, this becomes echo "Hello World". Thus, you get quotes, but lose your spaces.

相反,这是可行的(但不是最佳实践) )示例,请考虑:

By contrast, as a working (but not particularly best-practice) example, consider:

ssh somehost echo \"Hello"   "World\"

在这里,您要传递 ssh 两个参数: \ 的开头和结尾是第一个shell的文字(没有语法含义,因此 Hello 是第一个shell未引用);但是仅在空白周围的 是语法上的,并告诉Shell保留该空白(因此引用了 space )调用 ssh 时。因此,您将得到 { echo, \ Hello World\,NULL} ,它连接到字符串 echo Hello世界。

Here, you're passing ssh two arguments: The \"s at the beginning and end are literal to the first shell (having no syntactical meaning, so the word Hello is to that first shell unquoted); but the "s just surrounding the whitespace is syntactical, and tells the shell to preserve that whitespace (so the spaces are quoted) when invoking ssh. Thus, you get { "echo", "\"Hello World\"", NULL }, which concatenates to the string echo "Hello World".

最佳做法是通过仅传递单个字符串来避免此行为

The best practice is to avoid this behavior by passing only a single string to ssh containing the entire script you want to run.

# This works
ssh somehost 'echo "Hello   World"'

...如果要以编程方式生成该字符串,则可以这样操作(如果您知道您的远程shell是bash -即使bash-in- / bin / sh 模式也是安全的):

...if you want to generate that string programatically, you can do so as such (if you know that your remote shell is bash -- even bash-in-/bin/sh mode is safe):

remote_command=( echo "Hello   World" )
printf -v remote_command_q '%q ' "${remote_command[@]}"
ssh somehost "$remote_command_q"

要使用任何符合POSIX的远程shell安全地执行此操作,请参见< a href = https://stackoverflow.com/questions/45308395/how-to-have-simple-and-double-quotes-in-a-scripted-ssh-command>如何在脚本化的ssh命令中使用单引号和双引号

To do that safely with any POSIX-compliant remote shell, see the Python-assisted answer in How to have simple and double quotes in a scripted ssh command

这篇关于当通过ssh传递时,为什么带引号的空格命令不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆