目前正在获得
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一样正常工作
发布于 2019-02-11 01:00:19
当您在问题中用两层引号打印它时,该命令应该会像预期的那样工作。要调试这类问题,请使用'ssh -v‘并查找“发送命令:”行来查看实际发送到远程主机的内容。例如:
$ ssh -v remotehost 2>&1 'sh -c "touch 1 && echo 2"' | grep command
debug1: Sending command: sh -c "touch 1 && echo 2"当我删除单引号时,我可以复制您的错误:
$ ssh remotehost 2>&1 sh -c "touch 1 && echo 2"
touch: missing file operand使用"ssh -v“进行调试,如上面所示,我们得到:
ssh -v remotehost 2>&1 sh -c "touch 1 && echo 2" | grep command
debug1: Sending command: sh -c touch 1 && echo 2所以这里发生的是一个标准的shell引用问题。使用两层引号(我上面的工作示例),下面是如何解析它:
输入命令:
ssh remotehost 'sh -c "touch 1 && echo 2"'shell将其解析为三个字符串:
string1: ssh
string2: remotehost
string3: sh -c "touch 1 && echo 2"然后,shell找到"ssh“命令,并使用两个参数(上面的string2和string3 )运行它。
然后,"ssh“命令在远程主机上执行string3的内容,将内容分解为3个字符串:
string1: sh
string2: -c
string3: touch 1 && echo 2现在,这个shell必须解析string3。它将其分解为五个令牌,并按您的预期进行解释。
如果没有两层引号,远程shell将尝试执行:
sh -c touch 1 && echo 2如果将其粘贴到本地命令行中,就会看到同样的结果。由于shell的命令行解析有些模糊,所以删除了"1“,尽管命令的其余部分按预期进行了解析。如果您将"&&“更改为”区“(以便执行表达式的两边),您将看到"2”仍然被打印出来。
这个故事的寓意是,你永远不想让一个shell调用另一个,因为你会像上面所发现的那样,潜入无穷无尽的问题迷宫,用引号、反斜杠逃逸、变量扩展和解析歧义。唉,通常没有办法避免这些结构,所以如果你必须这样做的话,一定要小心地引用,并且尽量保持表达式的简单。
https://serverfault.com/questions/953087
复制相似问题