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

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

我经常连接到学校的 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
}

这有效,所以我who在命令末尾添加了ssh

在文件中~/.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
}

这将连接、自动输入我的密码并运行who,但随后关闭连接。有没有一种方法可以让我who自动运行,而无需随后关闭连接?

答案1

总结:int_ua 的答案是正确的,最简单,最轻松。

为什么会有这样的效果

这又回到了任何 shell 的基本行为。当您登录时,您会得到 shell 的交互式版本。当您运行时,您基本上会得到。第一个允许您在获取点文件的同时运行您输入的任何内容,而第二个只执行这些命令并退出。本质上,没有办法在交互式使用之前运行命令(除非它在其中一个点文件中)或从单次命令(或任何 shell,不一定)获取交互式 shell。ssh [email protected]ssh [email protected] -t "command1;command2"/bin/sh -c 'command1;command2'stdinsh -csh

失败或不完整的想法

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

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

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

ssh -o SendEnv=PS1 ssh localhost -t bash

或者

ssh localhost -t " PROMPT_COMMAND='who; unset PROMPT_COMMAND' bash  "

问题 ? -o 选项 SendEnv 必须允许您尝试发送的特定变量/etc/ssh/sshd_config,此外,无论哪种情况,您仍然可以使用/bin/sh -c

对 int_ua 的答案略有改进

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

 ssh [email protected] -t 'who;exec bash'

答案2

只需执行bash就足够了:

 sshpass -f <password_file> ssh <user@ipaddress> 'who; bash';

答案3

这是一个答案是,但绝对不是回答。

我发现sshd(远程主机上的 ssh 服务守护进程)在连接时会运行 ~/.ssh/rc 中的命令。我刚刚创建了这个文件,并添加到who那里,现在每次我进行远程连接时都会显示一个用户列表,而且我仍然会获得登录 shell。

在远程主机上:

File ~/.ssh/rc:

#!/bin/bash

# This file is executed by sshd when a remote connection is started over ssh
who

在客户端:

In file ~/.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
}

但是,我仍然有兴趣了解如何从客户端执行此操作,但是对于遇到类似问题的其他用户,由于缺乏权限或其他原因而无法使用 ~/.ssh/rc。

答案4

我知道这是一个老问题,但我想知道为什么没有人提到expect,这似乎只是为这种情况设计的。(当然,您需要expect先安装该软件包)。

!#/usr/bin/expect

spawn ssh user@host
expect "assword:"
send "mypassword\r"
expect "$ "
send "who\r"
interact

相关内容