我想做类似的事情ssh example.com 'ls'
但是根据 ssh 手册页:
如果命令被指定,它将在远程主机上执行,而不是在登录 shell 上执行。
因此发生的情况是ls
显示其输出然后 ssh 退出。
我无法弄清楚如何打开完整的登录 shell,然后在该 shell 中运行命令。运行命令后让 shell 保持打开状态。就好像我手动完成了以下操作:
localhost$ ssh example.com
example.com$ ls
/folder1
/folder2
example.com$ _
有任何想法吗?
答案1
只需告诉 bash 执行ls
,然后让它自己在登录 shell 中运行
$ ssh user@host -t 'bash -l -c "ls;bash"'
答案2
ssh user@host -t 'ls; exec $SHELL -l'
-t
强制分配伪终端。这可用于在远程机器上执行任意基于屏幕的程序。比 更合适一些bash -i
。
exec
没有创建新的流程。
-l
按顺序查找 ~/.bash_profile、~/.bash_login 和 ~/.profile,然后读取并执行命令...如果没有这个,您可能无法从 ~/bin 目录运行脚本/命令,因为如果没有标志,就不会执行来自 ~/.profile 的这段代码-l
:
if [ -d "$HOME/bin" ] ; then
PATH="$HOME/bin:$PATH"
fi
答案3
在您对 fons 的答案的评论中,您说使用时它不起作用screen
。
你能详细说明一下吗?查看 openssh 的源代码,sshd 通过调用以下代码来执行命令
YOUR_DEFAULT_SHELL -c COMMAND
因此,例如,如果您的默认 shell 是screen
,那么这将无法正常工作,因为screen
的-c
标志会覆盖其.scrreenrc
。因此,如果它是您的默认 shell,则实际上无法向 screen 发送命令。您必须实际运行 screen 作为给 ssh 的命令,但使用非 screen 的默认 shell。
如果你正在尝试这样做,我认为事情会变得非常奇怪,因为它screen
也会关闭非交互式程序的窗口,所以你必须使用与 fons 类似的技巧,但要更深一层。所以,例如 /bin/bash(而不是屏幕)作为默认 shell就像是:
ssh user@host -t 'screen bash -l -c "ls;bash"'
应该 --深吸一口气 -- ssh 进入主机,运行 bash -c 并使用 screen 命令,这将创建一个新窗口。如果此窗口刚刚打开 ls,它将结束,screen 也将终止,因此我们使用 fons 的技巧在新屏幕窗口内。
我认为这会起作用,如果这就是你想做的事的话;)
答案4
因为我经常难以正确地退出我的命令,所以抓住这个功能:
sshlogin() { ssh -tt "$1" "$(printf "%q " bash -lc '"$@"' -- "${@:2}")"; };
有了它,不仅可以运行登录 shell,还可以保留空格和引号:
$ sshlogin server echo "a space b"
a space b