首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么ssh远程服务器sh -c触摸1?

为什么ssh远程服务器sh -c触摸1?
EN

Server Fault用户
提问于 2019-02-09 02:39:26
回答 1查看 297关注 0票数 0

目前正在获得

代码语言:javascript
复制
touch: missing file operand
Try `touch --help' for more information.

我跟踪-c在ssh上执行su,发现我需要做ssh remote-server 'sh -c "touch 1 && echo 2"'。但我想知道为什么..。因为所有其他命令都像ssh remote-server echo -e 123一样正常工作

EN

回答 1

Server Fault用户

回答已采纳

发布于 2019-02-11 01:00:19

当您在问题中用两层引号打印它时,该命令应该会像预期的那样工作。要调试这类问题,请使用'ssh -v‘并查找“发送命令:”行来查看实际发送到远程主机的内容。例如:

代码语言:javascript
复制
$ ssh -v remotehost 2>&1 'sh -c "touch 1 && echo 2"' | grep command
debug1: Sending command: sh -c "touch 1 && echo 2"

当我删除单引号时,我可以复制您的错误:

代码语言:javascript
复制
$ ssh  remotehost 2>&1 sh -c "touch 1 && echo 2" 
touch: missing file operand

使用"ssh -v“进行调试,如上面所示,我们得到:

代码语言:javascript
复制
ssh -v remotehost 2>&1 sh -c "touch 1 && echo 2" | grep command
debug1: Sending command: sh -c touch 1 && echo 2

所以这里发生的是一个标准的shell引用问题。使用两层引号(我上面的工作示例),下面是如何解析它:

输入命令:

代码语言:javascript
复制
 ssh remotehost  'sh -c "touch 1 && echo 2"'

shell将其解析为三个字符串:

代码语言:javascript
复制
string1:  ssh
string2:  remotehost
string3:  sh -c "touch 1 && echo 2"

然后,shell找到"ssh“命令,并使用两个参数(上面的string2和string3 )运行它。

然后,"ssh“命令在远程主机上执行string3的内容,将内容分解为3个字符串:

代码语言:javascript
复制
string1: sh
string2: -c
string3: touch 1 && echo 2

现在,这个shell必须解析string3。它将其分解为五个令牌,并按您的预期进行解释。

如果没有两层引号,远程shell将尝试执行:

代码语言:javascript
复制
sh -c touch 1 && echo 2

如果将其粘贴到本地命令行中,就会看到同样的结果。由于shell的命令行解析有些模糊,所以删除了"1“,尽管命令的其余部分按预期进行了解析。如果您将"&&“更改为”区“(以便执行表达式的两边),您将看到"2”仍然被打印出来。

这个故事的寓意是,你永远不想让一个shell调用另一个,因为你会像上面所发现的那样,潜入无穷无尽的问题迷宫,用引号、反斜杠逃逸、变量扩展和解析歧义。唉,通常没有办法避免这些结构,所以如果你必须这样做的话,一定要小心地引用,并且尽量保持表达式的简单。

票数 2
EN
页面原文内容由Server Fault提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://serverfault.com/questions/953087

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档