使用ssh运行远程脚本文件时如何保持参数带有空格? [英] how to keep parameter with spaces when running remote script file with ssh?

查看:68
本文介绍了使用ssh运行远程脚本文件时如何保持参数带有空格?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现当我在本地运行脚本时,例如

I found that when I run a script locally, such as

./run.sh a "b c"

在run.sh中使用"$ @"时,它将标识两个参数.但是,当通过ssh在远程计算机中使用时,不是那样的.

It will identify two parameters when used "$@" in run.sh. However, when used in remote machine via ssh, it won't be that.

ssh user@host ./run.sh a "b c"

那我应该如何实现呢?

推荐答案

了解问题:当前命令 ssh user @ host ./run.sh一个"b c" 发生了什么这是因为本地外壳程序将命令解析为"words".(应用和删除所有引号和/或它所看到的转义符),并得到" ssh "," user @ host ",""./run/sh "," a "和" bc ".它以第一个( ssh )作为命令,并将其余的作为参数传递给它.ssh使用" user @ host "(这是关键所在),它只是将其余部分粘在一起(用空格分隔),作为要运行的远程命令.这给出了" ./run.sh a b c ".作为远程命令.然后将其传递到远程外壳程序,该远程外壳程序(因为现在不再引用)会解释" a "," b "和" c ""作为单独的参数.

Understanding the problem: What's happening with your current command, ssh user@host ./run.sh a "b c", is that the local shell parses the command into "words" (applying and removing any quotes and/or escapes it sees), and gets "ssh", "user@host", "./run/sh", "a", and "b c". It takes the first (ssh) as the command, and passes the rest to it as arguments. ssh takes "user@host" as where to ssh to, and (here's the critical thing) it just sticks the rest together (separated by spaces) as the remote command to run. This gives "./run.sh a b c" as the remote command. That then gets passed to the remote shell, which (since the quotes are now gone) interprets "a", "b", and "c" as separate arguments.

简而言之:引号是由本地外壳程序而不是远程外壳程序(您所关心的)应用和删除的.

In short: the quotes are getting applied and removed by the local shell, not the remote shell (which is the one you care about).

解决方案:用引号引起来或转义引号,以便本地Shell将它们视为仅作为要传递到远程Shell的数据.本质上,这意味着您需要两个级别的引用/转义,以便本地外壳程序将应用(并删除)一个级别,而远程外壳程序将应用(并删除)第二个级别.

The solution: quote or escape the quotes so that the local shell treats them as just data to be passed through to the remote shell. Essentially, this means you needs two levels of quoting/escaping, so that the local shell will apply (and remove) one level, and the remote shell will apply (and remove) the second level.

这是一种简单,干净的方法:

Here's a simple, clean way to do it:

ssh user@host './run.sh a "b c"'

本地外壳适用&删除单引号,因此双引号由远程外壳程序应用.请注意,引号通常不会嵌套在彼此之间,但由于双引号在单引号字符串中没有特殊含义,因此在这种情况下可以使用.您也可以在两个级别上都使用双引号,但是您需要转义内部引号:

The local shell applies & removes the single-quotes, so the double-quotes get applied by the remote shell. Note that quotes generally don't nest within themselves/each other, but since double-quotes have no special meaning in a single-quoted string, it works in this case. You could also use double-quotes for both levels, but you need to escape the inner quotes:

ssh user@host "./run.sh a \"b c\""

实际上,其中的外部双引号实际上并没有做任何事情(它们使ssh成为整个参数,但是如果它们是多个参数,则无论如何它们都将重新组合在一起,所以.)).您实际上可以删除它们:

In fact, the outer double-quotes in that aren't actually doing anything here (they make the whole thing one argument to ssh, but if they were multiple arguments they'd just get stuck back together anyway, so...). You could actually remove them:

ssh user@host ./run.sh a \"b c\"

实际上,有很多方法可以将本地和远程shell上的各种引号/转义选项组合在一起:

There are actually lots of ways to do this, combining various quoting/escaping options on the local and remote shells:

ssh user@host ./run.sh a '"b c"'
ssh user@host "./run.sh a 'b c'"
ssh user@host './run.sh a b\ c'
ssh user@host ./run.sh a b\\ c

顺便说一句,通常来说,回声 echo 是一种非常糟糕的方法,因为它只是将其参数与它们之间的空格粘在一起,因此很难找出您的参数是如何被解析的.但是由于 ssh 在创建远程命令时也是如此,因此您可以将 ssh user @ host 替换为 echo ,以查看实际的情况.传递给远程外壳程序:

BTW, in general, echoing something is a really bad way to find out how your arguments are being parsed, because it just sticks its arguments together with spaces between. But since that's the same thing ssh does when creating the remote command, you can replace ssh user@host with echo to see what will actually be passed to the remote shell:

$ echo ./run.sh a "b c"
./run.sh a b c
$ echo './run.sh a "b c"'
./run.sh a "b c"
$ echo "./run.sh a \"b c\""
./run.sh a "b c"
$ echo "./run.sh a 'b c'"
./run.sh a 'b c'
$ echo ./run.sh a b\\ c
./run.sh a b\ c

这篇关于使用ssh运行远程脚本文件时如何保持参数带有空格?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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