Exécuter la commande ssh à distance avec un shell de connexion complet

48

J'aimerais faire quelque chose comme ssh example.com 'ls'Cependant par page de manuel ssh:

Si commande est spécifiée, elle est exécutée sur l'hôte distant au lieu d'un shell de connexion.

Donc, ce qui se passe, c’est qu’il lsaffiche sa sortie puis ssh se ferme.

Ce que je n'arrive pas à comprendre, c'est comment ouvrir le shell de connexion complet puis exécuter la commande à l'intérieur de ce shell. Laisser le shell ouvert après l'exécution de la commande. Comme si j'avais fait manuellement les choses suivantes:

  localhost$ ssh example.com 
example.com$ ls
             /folder1 
             /folder2 
example.com$ _

Des idées?

Matthieu
la source
c'est une question similaire superuser.com/questions/261617/… mais aucune des réponses ne semble vraiment correspondre à ce que j'essaie de faire.
matthew
Que diriez- ssh example.com 'ls;bash'vous
Andrejs Cainikovs
vous avez besoin de -i sur mes systèmes pour rendre le second shell interactif.
Flexo
l'option -t est la réponse à votre question. D'autres options (par exemple, le trousseau) existent mais dépendent de vos besoins réels, qui ne sont pas assez clairs pour moi.
hornetbzz
@hornetbzz -t me donne un pseudo-tty. Mais sinon, le comportement est le même. Je souhaite lancer un shell interactif, exécuter une commande à l'intérieur de ce shell et le laisser rester ouvert une fois la commande exécutée.
matthew

Réponses:

40

Il suffit de dire à bash de s’exécuter lspuis de se lancer dans un shell de connexion

$ ssh user@host  -t 'bash -l -c "ls;bash"'
fons
la source
2
Malheureusement, cela ne semble pas fonctionner pendant l'utilisation screen. Sinon, cela ressemble à ce que j'essayais de faire.
matthew
31
ssh user@host -t 'ls; exec $SHELL -l'

-tForcer l'allocation pseudo-terminale. Ceci peut être utilisé pour exécuter des programmes d'écran arbitraires sur une machine distante. Est légèrement plus approprié que bash -i.

exec Aucun nouveau processus n'est créé.

-lrecherche ~ / .bash_profile, ~ / .bash_login et ~ / .profile, dans cet ordre, puis lit et exécute les commandes depuis ... Sans cela, vous ne pouvez probablement pas exécuter de scripts / commandes depuis le répertoire ~ / bin, car ce code from ~ / .profile ne sera pas exécuté sans -ldrapeau:

if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi
Grawity
la source
@grawity @Alan Cela pourrait fonctionner comme une solution de contournement, mais j'aimerais vraiment que la commande soit exécutée à l'intérieur du shell et non simplement ouvrir un nouveau shell après l'exécution de la commande.
matthew
+1, -t est définitivement la bonne façon de passer en revue -i, je viens juste de l’oublier.
Flexo
@ Matthew: Vous devrez bashvous corriger pour permettre cela.
Grawity
@grawity pas vraiment, voir ma réponse ci
fons
@ matthew, utilisez exec bashouexec $SHELL
Eugen Konkov
1

Dans votre commentaire sur la réponse de fons, vous dites que cela ne fonctionne pas pendant l'utilisation screen.

Pouvez-vous développer sur ce sujet? En regardant le code source de openssh, sshd exécute la commande en appelant

YOUR_DEFAULT_SHELL -c COMMAND

Ainsi, par exemple, si votre shell par défaut est screen, cela ne fonctionnera pas si bien parce que screende » -cdrapeau juste l' emporte sur son .scrreenrc. Donc, il n'y a vraiment aucun moyen d'envoyer des commandes à l'écran s'il s'agit de votre shell par défaut. Vous devrez en fait lancer screen en tant que commande donnée à ssh, mais avec un shell par défaut qui n'est pas screen .

Si c'est ce que vous essayez de faire, je pense que les choses vont devenir vraiment bizarres, car screenelles fermeront également les fenêtres avec des programmes non interactifs. Vous devrez donc faire un tour similaire à celui de fons, mais à un niveau plus profond. SO, avec par exemple / bin / bash (et non screen) comme shell par défaut. Quelque chose comme:

ssh user@host -t 'screen bash -l -c "ls;bash"'

Ce qui devrait - prendre une profonde respiration-- ssh dans l'hôte, lancez bash -c avec une commande de screen, ce qui créera une nouvelle fenêtre. Si cette fenêtre venait juste d'ouvrir ls, elle se terminerait et l'écran se terminerait. Nous utilisons donc le truc de fons à l'intérieur de la nouvelle fenêtre d'écran .

Je pense que ça va marcher, si c'est même ce que tu essayais de faire;)

Scott Walls
la source
Je pense que le problème que je rencontre screendans cette situation est que je le charge normalement avec exec screen -RRmon fichier .profile. Cela signifie que bash -ltente de charger l'écran qui rejette le reste. il semble que je puisse contourner le problème en supprimant '-l' dans vos solutions, ainsi que dans vos solutions (votre solution me laisse ensuite screen). C'est un peu moche cependant.
matthew
0

Plusieurs options -t forcent l'allocation de tty, même si ssh n'a pas de tty local:

ssh -tt user@host 'bash -l -c "/path/to/command'
panticz.de
la source