使用ssh,如何在不退出的情况下在远程机器上运行命令?

ico*_*ast 35 ssh

通常,如果您像这样将命令传递给 ssh

ssh me@example.com 'some-command.sh'
Run Code Online (Sandbox Code Playgroud)

您将获得一个非交互式会话,并且只要运行命令(或脚本或其他任何内容),ssh 就会退出。如何获得交互式会话,同时运行我从本地计算机指定的命令。例如,我希望能够打开屏幕并重新启动特定的屏幕会话:

ssh me@example.com 'screen -r 12345'
Run Code Online (Sandbox Code Playgroud)

但这是不允许的,返回错误“必须连接到终端”。我认为这基本上意味着“必须从交互式 shell 调用此命令”。

再举一个例子,我在工作中使用了大量的机器,这些机器通常需要我使用共享帐户才能有权做某些事情(是的,我知道:坏主意,但不要怪我,我没有设置方式),并且它们通常将 ksh 作为默认 shell。我想登录,切换到 bash(或 zsh),并获取我自己帐户的 .bash_profile(或 .zshrc)。如果我可以建立一个交互式 ssh 会话并将命令传递给远程机器以在登录时运行,这将很容易。

我有一个非常笨拙(未经测试)的解决方案,我会发布,但我希望有人知道更好的方法。

更新:对于那些没有意识到这一点的人,我不打算手工完成所有这些,所以告诉我打开一个交互式会话然后手工完成并不能真正解决任何问题。

第二次更新:再次尝试澄清:我正在尝试在服务器上运行(任意)命令(在客户端上以编程方式指定),但随后打开了一个交互式会话,该会话受到这些编程命令所做的任何事情的影响。

dog*_*ane 29

您可以尝试以下命令来启动 bash 并在 ssh 时获取您自己的配置文件:

ssh  -t hostname "bash --rcfile ~user/.bashrc"
Run Code Online (Sandbox Code Playgroud)

  • +1。`-t` 开关也用 `screen` 解决了提问者的问题。 (4认同)
  • 这可以与任意命​​令一起使用,而无需关闭连接吗?如果我尝试`ssh -t www.dev "echo 'hi there'"`,则在执行命令后立即关闭连接。 (3认同)

小智 11

基于 dogbane 的回答,完整的解决方案如下所示:

ssh -t user@server 'cd /a/great/place; bash'
Run Code Online (Sandbox Code Playgroud)

这里我-t用来强制分配一个伪终端,这是交互式 shell 所必需的。然后我在服务器上执行两个命令:首先是在打开交互式 shell 之前我想做的事情(在我的例子中,将目录更改为特定文件夹),然后是交互式 shell 本身。bash 看到它有一个伪终端并交互响应。

单引号确保将整个内容作为要由默认 shell 运行的命令传递到远程服务器。

再次感谢 dogbane 提供了必要的线索-t。我曾经用 解决这个问题expect,这绝对是用大炮杀死一只老鼠。(:


ico*_*ast 0

这是笨拙的,未经测试的,但我认为它应该有效。

创建一个名为(例如)remote-starter 的脚本,该脚本在 user@host 参数后采用带引号的参数:

remote-starter user@example.com 'some-command.sh arg1 arg2'
Run Code Online (Sandbox Code Playgroud)

该脚本应首先将引用的命令(不带引号)保存在.onetime远程计算机上名为 (eg) 的文件中,然后运行常规 ssh 命令,这次不传递任何要在远程计算机上运行的命令。(如果从脚本中运行 ssh user@example.com,则运行 exec ssh user@example.com 可能会起作用。)

为此,远程计算机必须.onetime从其 .bash_profile 或 .zshrc 或其他内容获取源。运行后.onetime,它应该删除.onetime,这样您下次定期登录时就不会运行该文件。