我希望看到两个命令都打印 hello
$ bash -l -c "/bin/echo hello"
hello
$ ssh example_host bash -l -c /bin/echo hello
$
怎么可能
hello
在 ssh
中作为参数传递命令?bash -l -c
是必需的,因此会执行登录 shell 启动脚本。获取
ssh
启动登录外壳也可以解决问题。
最佳答案
当您在 -c
之后传递额外的参数时,它们在该命令执行时被放入 shell 的 argv 中。你可以这样看:
bash -l -c '/bin/echo "$0" "$@"' hello world
...所以,这些参数不会放在 echo 的命令行上(除非你不遗余力地这样做),而是放在你告诉运行 echo 的 shell 的命令行上没有论据。
也就是说:当你跑
bash -l -c /bin/echo hello
...这相当于:
(exec -a hello bash -c /bin/echo)
...这把
hello
进入 $0
仅运行 /bin/echo
的 bash .自从运行 /bin/echo
不看$0
,当然不会打印 hello
.现在,因为通过 ssh 执行事情意味着您要经历两个 shell 扩展步骤,所以它增加了一些额外的复杂性。幸运的是,您可以让 shell 自动为您处理,如下所示:
printf -v cmd_str '%q ' bash -l -c '/bin/echo "$0" "$@"' hello world
ssh remote_host "$cmd_str"
这告诉 bash(
printf %q
是 bash 扩展,在 POSIX printf 中不可用)引用您的命令,以便它在被 shell 处理时扩展为自身,然后将结果提供给 ssh
.说了这么多——治疗
$0
作为常规参数是不好的做法,通常不应该在没有具体和令人信服的理由的情况下这样做。正确的事情更像是以下内容:printf -v cmd '%q ' /bin/echo hello world # your command
printf -v cmd '%q ' bash -l -c "$cmd" # your command, in a login shell
ssh remotehost "$cmd" # your command, in a login shell, in ssh
关于bash - 脚本在 '$ ssh bash script arg' 中看不到 arg,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26304644/