通过 SSH 在远程服务器上运行命令 - 无需退出

Mic*_*ann 6 ssh bash networking remote

我经常连接到我学校的 Linux 实验室来远程完成我的编程作业。有时,当有很多其他学生登录到服务器时,连接很慢,并且在连接超时期间我失去了工作。实验室里有几台服务器可供选择,我希望能够who在建立连接后立即自动运行,这样我就可以看到服务器有多拥挤,如果它很满就使用另一台。现在,我在 .bash_aliases 文件中使用一个函数来简化连接和密码输入:

在文件中~/.bash_aliases

#!/bin/bash

# ssh to the Linux lab. Takes hostnames defined in ~/.ssh/config as 
# parameters
function sshll()
{
    if [ "$@" ]
      echo "Connecting to hostname $@";
      sshpass -f <password_file> ssh $@;
    else
      echo "Connecting to default host";
      sshpass -f <password_file> ssh <user@ipaddress>;
    fi
}
Run Code Online (Sandbox Code Playgroud)

这有效,所以我添加whossh命令的末尾:

在文件中~/.bash_aliases

#!/bin/bash

# ssh to the linux lab. Takes hostnames defined in ~/.ssh/config as 
# parameters
function sshll()
{
    if [ "$@" ]
      echo "Connecting to hostname $@";
      sshpass -f <password_file> ssh $@ 'who';
    else
      echo "Connecting to default host";
      sshpass -f <password_file> ssh <user@ipaddress> 'who';
    fi
}
Run Code Online (Sandbox Code Playgroud)

这会连接,自动输入我的密码,然后运行who,但随后关闭连接。有没有办法可以who自动运行,而不用关闭连接?

int*_*_ua 5

只需执行bash就足够了:

 sshpass -f <password_file> ssh <user@ipaddress> 'who; bash';
Run Code Online (Sandbox Code Playgroud)

  • bash 根本不会清除终端历史记录(至少在默认情况下),因此您应该看到之前的所有行。AFAIU 这些行将无法用于某些自动处理,但在您的情况下应该不是问题。此外,如果您使用普通的 `ssh`,则必须使用 `-t` 键。 (2认同)

Ser*_*nyy 5

TL;DR:int_ua 的答案是要走的路,最简单和轻松。

为什么这样做

这可以追溯到任何 shell 的基本行为。当您ssh user@server.domain.whatever在获得交互式版本的 shell时登录。当你运行时,ssh user@some.server.net -t "command1;command2"你基本上得到/bin/sh -c 'command1;command2'. 第一个允许您stdin在获取点文件时运行您放入的任何内容,而第二个只是执行这些命令并退出。本质上,没有办法在交互式使用之前运行命令(除非它在一个点文件中)或从单次命令获取交互式 shell sh -c(或它可能是哪个 shell,不一定sh)。

失败或不完整的想法

我的第一个想法是:如果 shell 使用服务器的本地文件.bashrc,是否可以让它使用服务器上客户端的本地文件?嗯,没有。除非您使用 scp 或 rsync将点文件复制到远程服务器

我的第二个想法是PROMPT_COMMAND. 这个非常好的bash变量每次在显示PS1提示之前都会运行命令,那么为什么不在生成之前设置这个变量bashPROMPT_COMMAND="who; unset PROMPT_COMMAND"以便我们将它作为单次运行呢?

问题是这个变量必须导出到远程服务器,Gilles 的回答帮助我做这样的事情:

ssh -o SendEnv=PS1 ssh localhost -t bash
Run Code Online (Sandbox Code Playgroud)

或者

ssh localhost -t " PROMPT_COMMAND='who; unset PROMPT_COMMAND' bash  "
Run Code Online (Sandbox Code Playgroud)

问题 ?-o 选项 SendEnv 必须允许您尝试发送的特定变量,/etc/ssh/sshd_config而且在任何一种情况下,您仍然可以使用/bin/sh -c

对 int_ua 的回答略有改进

所以现在我们可以看到这种ssh user@server -t 'command1;shell'模式效果最好。除了有一个小问题:/bin/sh -cprocess 仍然存在,那么为什么不运行bashwithexec来替换该进程呢?

 ssh user@server.net -t 'who;exec bash'
Run Code Online (Sandbox Code Playgroud)