ssh
运行时有一个烦人的功能:
ssh user@host cmd and "here's" "one arg"
Run Code Online (Sandbox Code Playgroud)
它不是cmd
用它的参数运行它host
,而是将它cmd
和带有空格的参数连接起来,并运行一个 shellhost
来解释结果字符串(我想这就是为什么它被调用ssh
而不是sexec
)。
更糟糕的是,您不知道将使用什么 shell 来解释该字符串,因为它的登录 shelluser
甚至不能保证像 Bourne 一样,因为仍然有人使用tcsh
作为他们的登录 shell 并且fish
还在增加。
有没有办法解决这个问题?
假设我有一个命令作为存储一个在参数列表bash
阵列,其每一个可以包含的非空字节的任何序列,是否有任何方式把它上执行host
如user
以一致的方式,无论该登录壳的user
上host
(我们假设它是主要的 Unix shell 系列之一:Bourne、csh、rc/es、fish)?
我应该能够做出的另一个合理假设是,有一个sh
与Bourne 兼容的命令host
可用$PATH
。
例子:
cmd=(
'printf'
'<%s>\n'
'arg with $and spaces'
'' # empty
$'even\n* * *\nnewlines'
"and 'single quotes'"
'!!'
)
Run Code Online (Sandbox Code Playgroud)
我可以在本地运行它与 …
我突然意识到我不知道如何通过 SSH 执行事情。
我试着做
$ ssh user@server sh -c 'echo "hello"'
Run Code Online (Sandbox Code Playgroud)
但它什么都不输出,或者更确切地说,它输出一个空行。如果给出的命令在远程主机上ssh
运行$SHELL -c
,那么我可以理解为什么会这样(或者我可以尝试将其合理化)。
好的,第二次尝试:
$ ssh user@server 'echo "hello"'
hello
Run Code Online (Sandbox Code Playgroud)
一切都很好。
现在对于我真正希望的工作:
$ ssh user@server 'echo "hello $1"' sh "world"
hello sh world
Run Code Online (Sandbox Code Playgroud)
嗯……sh
从哪里来的?这表明这$1
是空的,并且在另一侧真正执行的是类似的
$SHELL -c 'echo "hello sh world"'
Run Code Online (Sandbox Code Playgroud)
而不是我所希望的,
$SHELL -c 'echo "hello $1"' sh "world"
Run Code Online (Sandbox Code Playgroud)
有没有办法安全地将参数传递给通过 执行的脚本ssh
,以类似于运行的理智和明智的方式
sh -c 'script text' sh "my arg1" "my arg2" "my arg3" ...
Run Code Online (Sandbox Code Playgroud)
但在远程主机上?
我的本地和远程登录 shell 都是/bin/sh
.
安全 = …