这里有一些情况我是在foo是ssh服务器的密码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 , -c , exec , $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"'