Ssh, exécutez une commande lors de la connexion, puis restez connecté?

29

J'ai essayé cela avec espoir, mais cela n'a pas fonctionné: cela a fermé la connexion à la fin.

Pouvons-nous exécuter un script via ssh qui se connectera aux machines distantes, exécutera une commande et ne se déconnectera pas?

Alors ssh dans une machine, cd dans tel ou tel répertoire, puis exécutez une commande et restez connecté.

-Jonathan

(sauf que j'ai utilisé)

#!/usr/bin/expect -f
set password [lrange $argv 0 0]
spawn ssh root@marlboro "cd /tmp; ls -altr | tail"
expect "?assword:*"
send -- "$password\r"
send -- "\r"
interact
Jonathan
la source
9
Est-ce juste moi ou "automatisez-vous" l'authentification par mot de passe de cette façon, au lieu d'utiliser des clés de pub ou une autre méthode sensée?
grawity

Réponses:

25

Ajouter un ; /bin/bashà la fin de votre ligne de commande sur le côté distant? C'est:

spawn ssh -t root@marlboro "cd /tmp; ls -altr | tail; /bin/bash -i"

Encore mieux, changez le .bashrc de root pour qu'il ressemble à ceci:

PROMPT_COMMAND="cd /tmp && ls -altr | tail ; unset PROMPT_COMMAND"

:)

Bill Weiss
la source
2
Vous voudrez peut-être ajouter -ià ce bash.
Teddy
Ouais, je suppose :)
Bill Weiss
Quand je fais cela, la complétion des tabulations se casse dans le nouveau shell (même avec "-i") - une idée pourquoi / comment y remédier?
Coderer
1
J'ai testé ma nouvelle réponse ici, cela fonctionne très bien. Un peu rude, mais ça marche.
Bill Weiss
7
Essayez ssh -td'allouer un pty.
pause jusqu'à nouvel ordre.
4

Si vous êtes d'accord avec cela en Python, pexpect a un exemple qui fait presque exactement ce que vous demandez:

import pexpect
child = pexpect.spawn ('ftp ftp.openbsd.org')
child.expect ('Name .*: ')
child.sendline ('anonymous')
child.expect ('Password:')
child.sendline ('[email protected]')
child.expect ('ftp> ')
child.sendline ('ls /pub/OpenBSD/')
child.expect ('ftp> ')
print child.before   # Print the result of the ls command.
child.interact()     # Give control of the child to the user.

Pour ce faire avec ssh au lieu de ftp, vous voudriez un code similaire au suivant (les fichiers d'exemple dans pexpect ont beaucoup plus de détails et d'informations, mais voici les bases):

import pexpect
child = pexpect.spawn ('ssh root@marlboro')
child.expect ('Password:')
child.sendline ('password')
child.expect ('prompt# ')
child.sendline ('cd /tmp')
child.expect ('prompt# ')
child.sendline ('ls -altr | tail')
child.expect ('prompt# ')
print child.before, child.after   # Print the result of the ls command.
child.interact()     # Give control of the child to the user.

Ne vous méprenez pas, j'adore attendre (en particulier autoexpect), mais le python est tellement plus facile pour moi de grogner.

Jed Daniels
la source
Moi aussi, je passe d'une attente à une attente. python est maintenant beaucoup plus omniprésent.
JM Becker
4

Le moyen le plus simple et le plus propre de ssh sur un serveur, de générer un shell interactif et d'exécuter des commandes à l'intérieur de ce shell est de créer un fichier rc personnalisé pour bash.

Dans votre fichier bashrc personnalisé sur le serveur, commencez par trouver le fichier par défaut, puis ajoutez vos commandes personnalisées, par exemple

~ / .bashrc_custom:

. ~/.bashrc
cd dir/
workon virtualenvproject

Vous pouvez ensuite démarrer votre session SSH comme ceci:

$ ssh -t server "/bin/bash --rcfile ~/.bashrc_custom -i"

L' -toption force une allocation pseudo-tty, de sorte que des choses comme la complétion de tabulation fonctionnent.

L' --rcfileoption spécifie le fichier rc à charger au lieu de celui par défaut. Important: vous devez mettre "arguments à double tiret" sur la ligne de commande avant les options à un seul caractère pour être reconnu.

L' -iargument de / bin / bash est là pour invoquer un shell interactif.

Danilo Bargen
la source
pas vraiment. Que faire si je souhaite exécuter différentes commandes pour chaque connexion?
Eugen Konkov
1

Si quelqu'un veut des informations sur ce qui se passe en arrière-plan, vous devriez jeter un œil au manuel sshd:

Lorsqu'un utilisateur se connecte avec succès, sshd effectue les opérations suivantes:

  1. Si la connexion se fait sur un tty, et qu'aucune commande n'a été spécifiée, imprime la dernière heure de connexion et / etc / motd (sauf si empêché dans le fichier de configuration ou par ~ / .hushlogin; voir la section FICHIERS).
  2. Si la connexion est sur un terminal, enregistre l'heure de connexion.
  3. Vérifie / etc / nologin et / var / run / nologin; s'il en existe un, il imprime le contenu et quitte (sauf root).
  4. Modifications à exécuter avec des privilèges utilisateur normaux.
  5. Configure l'environnement de base.
  6. Lit le fichier ~ / .ssh / environnement, s'il existe, et les utilisateurs sont autorisés à changer leur environnement. Voir l'option PermitUserEnvironment dans sshd_config (5).
  7. Modifications apportées au répertoire personnel de l'utilisateur.
  8. Si ~ / .ssh / rc existe, l'exécute; sinon si / etc / ssh / sshrc existe, l'exécute; sinon exécute xauth (1). Les fichiers `` rc '' reçoivent le protocole d'authentification X11 et le cookie en entrée standard. Voir CRSH, ci-dessous.
  9. Exécute le shell ou la commande de l'utilisateur.

https://www.freebsd.org/cgi/man.cgi?sshd(8)#LOGIN_PROCESS

Gerry
la source
0

Vous devriez généralement éviter d'utiliser ssh de cette manière car cela va à l'encontre de son objectif.
Faites un

ssh-add -l | grep "file_of_your_rsa_priv_key_here"

pour voir si votre clé est répertoriée dans le pool de sessions actives ssh ou bien ajoutez-la vous-même (avec ssh-add).

Kounavi
la source