问题与ssh,bash –login和exec的组合

这里有一些情况我是在foossh服务器的密码lesslogin设置。

 $ ssh foo $ bash --login -c 'exec $0 "$@"' ls -lrt 

它按预期工作。

 ssh foo bash --login -c ls -lrt 

这不像预期的那样工作。 只有ls正在工作忽略-lrt参数。

而我的要求是运行第一个例子像SSH

 ssh foo bash --login -c 'exec $0 "$@"' ls -lrt 

我知道我有第二个例子本身的问题。 但是,我只是想尽一切办法,find问题所在。 第三个例子没有显示任何错误/输出。

我如何着手实现第三个例子?

你可以做ssh foo bash --login -c '"exec \$0 \$@"' ls -lrt

要了解实际情况, strace是你的朋友。

ssh foo strace -vff -e execve bash --login -c 'exec $0 "$@"' ls -lrt给我这样的东西:

execve("/bin/bash", ["bash", "--login", "-c", "exec", "zsh", "ls", "-lrt"], [LANG=…]

我的shell是zsh,它应该给你提示这里发生了什么: $0被shell生成parsing通过SSH命令发送的命令行。 如果我们只是转义$0"$@"部分,如: ssh foo strace -vff -e execve bash --login -c 'exec \$0 "\$@"' ls -lrt我们得到:

execve("/bin/bash", ["bash", "--login", "-c", "exec", "$0", "$@", "ls", "-lrt"], ["LANG=..正如你在这里看到的,bash被调用的参数--login-cexec$0等等,这并不能让我们一直到我们想要的地方,因为现在有效的方法是自己调用exec ,为了解决这个问题,我们需要引用-c参数后面的内容,这样就不会太早解压,比如ssh foo strace -vff -e execve bash --login -c '"exec \$0 \$@"' ls -lrt

execve("/bin/bash", ["bash", "--login", "-c", "exec $0 $@", "ls", "-lrt"], ["LANG=…

这被bash接受,因为它允许你使用$@ ,但是如果你正在编写正确的POSIX sh,你应该使用"$@" ,在这种情况下,正确的答案是ssh foo strace -vff -e execve bash --login -c '"exec \$0 \"\$@\""' ls -lrt

execve("/bin/bash", ["bash", "--login", "-c", "exec $0 \"$@\"", "ls", "-lrt"], ["LANG=…

我假设你使用ls -lrt作为一些其他更复杂的命令的代理,而这些命令实际上需要bash --login等,否则只要执行第一个注释中的build议,并使用ssh foo 'ls -lrt'来代替。

ssh只接受一个参数作为命令,因此它应该在引号或撇号中。 这同样适用于bash -c参数 – 它只是一个被接受的参数。 其他人被传递给bash而不是ls 。 下面的例子工作得很好:

 ssh foo 'bash --login -c "ls -lrt"'