通常情况下,如果你像这样向 ssh 传递命令
ssh [email protected] 'some-command.sh'
您将获得一个非交互式会话,并且一旦运行命令(或脚本,或其他任何内容),ssh 就会退出。我如何才能获得交互式会话,同时运行我从本地计算机指定的命令。例如,我希望能够打开屏幕并重新启动特定的屏幕会话:
ssh [email protected] 'screen -r 12345'
但这是不允许的,返回错误“必须连接到终端。”我推测这本质上意味着“必须从交互式 shell 调用此命令”。
再举一个例子,我在工作中使用了大量的机器,这些机器经常要求我使用共享帐户才能获得执行某些操作的权限(是的,我知道:这是一个坏主意,但不要怪我,我没有那样设置),并且它们通常将 ksh 作为默认 shell。我想登录,切换到 bash(或 zsh),并获取我自己帐户的 .bash_profile(或 .zshrc)。如果我可以建立一个交互式 ssh 会话,这将很容易和将命令传递给远程机器在登录时运行。
我想到了一个非常笨拙(且未经测试)的解决方案,我将发布它,但我希望有人知道更好的方法。
更新:对于那些没有意识到这一点的人,我并不打算手动完成所有这些操作,因此告诉我打开一个交互式会话然后手动完成实际上并不能解决任何问题。
第二次更新:再次尝试澄清:我试图在服务器上运行(任意)命令(在客户端以编程方式指定),但然后打开一个交互式会话,该会话受到这些编程命令所做的任何操作的影响。
答案1
您可以尝试以下命令来启动 bash,并在 ssh 时获取您自己的配置文件:
ssh -t hostname "bash --rcfile ~user/.bashrc"
答案2
根据 dogbane 的回答,完整的解决方案如下:
ssh -t user@server 'cd /a/great/place; bash'
这里我使用-t
强制分配一个伪终端,这是交互式 shell 所必需的。然后我在服务器上执行两个命令:首先是我在打开交互式 shell 之前想要做的事情(在我的情况下,将目录更改为特定文件夹),然后是交互式 shell 本身。bash 看到它有一个伪终端并以交互方式响应。
单引号确保整个内容作为默认 shell 运行的命令传递到远程服务器。
再次感谢 dogbane 用 提供必要的线索-t
。我以前用 来解决这个问题expect
,这绝对是用大炮打死一只老鼠。(:
答案3
尝试这个解决方案。
echo "command" | ssh user@remote_host
登录是交互式的,您的命令就像您在交互式命令行中输入的一样。会话终止,就像您输入了
ssh user@remote_host 'command'
答案4
laggingreflex 的答案很接近...我会将其更改如下:
echo "command\n$(cat -)" | ssh user@remote_host
不幸的是,你可能不喜欢这种工作方式,因为“cat”会缓冲它写入标准输出的行...如果我们创建一个名为“echo-cat”的脚本,它看起来像这样:
{
echo "${@}"
#cat buffers & won't flush to stdout immediately
#cat -
IFS='\n'
while read line
do
echo "${line}"
done
}
即使没有缓冲,我们也会得到相同的结果:
echo-cat "command" | ssh user@remote_host
这可能会让你更接近你的目标......