it-swarm.com.de

Führen Sie den Befehl auf dem Remote-Server über SSH aus - ohne zu beenden

Ich stelle häufig eine Verbindung zum Linux Lab meiner Schule her, um meine Programmieraufgaben remote zu bearbeiten. Wenn viele andere Schüler am Server angemeldet sind, ist die Verbindung manchmal langsam und ich verliere die Arbeit während eines Verbindungs-Timeouts. Im Labor stehen mehrere Server zur Auswahl, und ich möchte who automatisch ausführen können, sobald die Verbindung hergestellt ist, damit ich sehen kann, wie voll der Server ist, und einen anderen Server verwenden, wenn er hübsch ist voll. Im Moment verwende ich eine Funktion in meiner .bash_aliases-Datei, um die Verbindung und die Kennworteingabe zu optimieren:

In der Datei ~/.bash_aliases:

#!/bin/bash

# ssh to the Linux lab. Takes hostnames defined in ~/.ssh/config as 
# parameters
function sshll()
{
    if [ "[email protected]" ]
      echo "Connecting to hostname [email protected]";
      sshpass -f <password_file> ssh [email protected];
    else
      echo "Connecting to default Host";
      sshpass -f <password_file> ssh <[email protected]>;
    fi
}

Das funktioniert, also habe ich who am Ende der ssh -Befehle hinzugefügt:

In der Datei ~/.bash_aliases:

#!/bin/bash

# ssh to the linux lab. Takes hostnames defined in ~/.ssh/config as 
# parameters
function sshll()
{
    if [ "[email protected]" ]
      echo "Connecting to hostname [email protected]";
      sshpass -f <password_file> ssh [email protected] 'who';
    else
      echo "Connecting to default Host";
      sshpass -f <password_file> ssh <[email protected]> 'who';
    fi
}

Dadurch wird eine Verbindung hergestellt, mein Kennwort wird automatisch eingegeben und who wird ausgeführt, die Verbindung wird jedoch geschlossen. Gibt es eine Möglichkeit, who automatisch auszuführen, ohne die Verbindung danach zu trennen?

5

TL; DR : Die Antwort von int_ua ist der einfachste und müheloseste Weg.

Warum funktioniert das so?

Dies geht auf das grundlegende Verhalten einer Shell zurück. Wenn Sie sich einfach als ssh [email protected] anmelden, erhalten Sie eine interaktive Version der Shell. Wenn Sie ssh [email protected] -t "command1;command2" ausführen, erhalten Sie im Grunde /bin/sh -c 'command1;command2'. Mit dem ersten Befehl können Sie alles ausführen, was Sie in stdin eingegeben haben, während Sie die Punktedateien suchen, während der zweite Befehl nur diese Befehle ausführt und beendet. Grundsätzlich gibt es keine Möglichkeit, einen Befehl vor der interaktiven Verwendung auszuführen (es sei denn, er befindet sich in einer der Punktedateien) oder eine interaktive Shell über den Single-Shot-Befehl sh -c abzurufen (oder welche Shell es auch sein mag, muss es nicht sein) sh).

Fehlgeschlagene oder unvollständige Ideen

Meine erste Idee, die ich hatte, ist folgende: Wenn die Shell den lokalen .bashrc des Servers verwendet, kann man sie dann veranlassen, die lokale Datei des Clients auf dem Server zu verwenden? Naja, nein . Nur wenn Sie kopieren Sie die Punktedatei auf den Remote-Server mit scp oder rsync.

Die zweite Idee, die ich hatte, ist der Prompt_COMMAND. Diese sehr schöne Variable bash führt jedes Mal den Befehl aus, bevor Sie Ihre Eingabeaufforderung PS1 anzeigen. Warum also diese Variable nicht vor dem Spawnen von bash auf Prompt_COMMAND="who; unset Prompt_COMMAND" setzen, damit wir sie als single-run ausführen? Schuss?

Das Problem ist, dass diese Variable auf den Remote-Server exportiert werden muss und Gilles-Antwort mir geholfen hat, so etwas zu tun:

ssh -o SendEnv=PS1 ssh localhost -t bash

oder

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

Problem ? -o Die Option SendEnv muss diese bestimmte Variable zulassen, die Sie in /etc/ssh/sshd_config senden möchten, und außerdem können Sie in beiden Fällen immer noch all diese Dinge mit /bin/sh -c ausführen.

Leichte Verbesserung der Antwort von int_ua

Inzwischen können wir also sehen, dass das ssh [email protected] -t 'command1;Shell' -Muster am besten funktioniert. Außer es gibt einen kleinen Trottel: /bin/sh -c Prozess ist noch da, warum also nicht bash mit exec ausführen, um diesen Prozess zu ersetzen?

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

Nur die Ausführung von bash sollte ausreichen:

 sshpass -f <password_file> ssh <[email protected]> 'who; bash';
5
int_ua

Dies ist eine Antwort, aber definitiv nicht die Antwort.

Ich habe festgestellt, dass sshd (der Daemon für ssh-Dienste auf dem Remote-Host) beim Herstellen der Verbindung Befehle in ~/.ssh/rc ausführt. Ich habe gerade diese Datei erstellt und dort who hinzugefügt, und jetzt wird jedes Mal, wenn ich eine Remoteverbindung herstelle, eine Liste der Benutzer angezeigt, und ich erhalte weiterhin eine Anmeldeshell.

Auf dem Remote-Host:

File ~/.ssh/rc:

#!/bin/bash

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

Auf dem Client:

In file ~/.bash_aliases:

#!/bin/bash

# ssh to the linux lab. Takes hostnames defined in ~/.ssh/config as 
# parameters
function sshll()
{
    if [ "[email protected]" ]
      echo "Connecting to hostname [email protected]";
      sshpass -f <password_file> ssh [email protected];
    else
      echo "Connecting to default Host";
      sshpass -f <password_file> ssh <[email protected]>;
    fi
}

Ich bin immer noch daran interessiert zu wissen, wie dies vom Client aus gemacht werden kann, jedoch für andere Benutzer mit ähnlichen Problemen, die ~/.ssh/rc wegen fehlender Berechtigungen oder aus irgendeinem anderen Grund nicht verwenden können.

3

int_uas Antwort würde ich verwenden. Wenn Sie der Vollständigkeit halber Ihren eigenen .profile oder .bashrc auf dem Remote-Server bearbeiten können, können Sie dies an einen der folgenden Werte anhängen:

if [[ -n $SSH_TTY ]]
then
    who
fi

SSH setzt verschiedene Variablen, von denen eine SSH_TTY ist - Sie können diese Variablen testen, um festzustellen, ob Sie über SSH verbunden sind. Einschränkungen für ~/.ssh/rc sollten Sie nicht daran hindern, dies zu verwenden.


Ich verwende dies, um meine Eingabeaufforderung festzulegen (beachte, wie ich den Hostnamen für lokale Shells überspringe):

if [[ -n $SSH_TTY ]]
then
    PS1="\[email protected]\h:\w \$ "
else
    PS1="\u:\w \$ "
fi
3
muru