De temps en temps je ferai quelque chose comme
ssh user@Host Sudo thing
et je me souviens que ssh n'alloue pas de pseudo-tty par défaut. Pourquoi pas? Quels avantages perdrais-je si j'aliasais ssh
à ssh -t
?
La principale différence est le concept d'interactivité . C'est similaire à exécuter des commandes localement à l'intérieur d'un script, par rapport à les taper vous-même. C'est différent car une commande à distance doit choisir une valeur par défaut, et non interactive est la plus sûre. (et généralement le plus honnête)
Ctrl-c
break entraînerait normalement la rupture immédiate d'une boucle de la commande ssh, vos séquences de contrôle seront plutôt envoyées au serveur distant. Il en résulte un besoin de "marteler" la frappe pour s'assurer qu'elle arrive lorsque le contrôle quitte la commande ssh, mais avant le début de la commande ssh suivante.Je vous déconseille d'utiliser ssh -t
dans des scripts sans assistance, tels que crons. Un shell non interactif demandant à une commande distante de se comporter de manière interactive pour la saisie demande toutes sortes de problèmes.
Vous pouvez également tester la présence d'un terminal dans vos propres scripts Shell. Pour tester STDIN avec des versions plus récentes de bash:
# fd 0 is STDIN
[ -t 0 ]; echo $?
ssh
vers ssh -t
, vous pouvez vous attendre à obtenir un retour chariot supplémentaire à la fin de votre ligne. Elle n'est peut-être pas visible pour vous, mais elle est là; il apparaîtra comme ^M
lorsqu'il est redirigé vers cat -e
. Vous devez ensuite déployer des efforts supplémentaires pour vous assurer que ce code de contrôle n'est pas affecté à vos variables, en particulier si vous allez insérer cette sortie dans une base de données.Voici le même test bash que précédemment, mais pour STDOUT:
# fd 1 is STDOUT
[ -t 1 ]; echo $?
Bien qu'il soit possible de contourner ces problèmes, vous allez inévitablement oublier de concevoir des scripts autour d'eux. Nous le faisons tous à un moment donné. Les membres de votre équipe peuvent également ne pas réaliser/se rappeler que cet alias est en place, ce qui, à son tour, vous posera des problèmes lorsque ils écrivent des scripts qui utilisent votre alias .
Alias ssh
vers ssh -t
est vraiment un cas où vous violerez le principe de conception de la moindre surprise ; les gens rencontreront des problèmes auxquels ils ne s'attendent pas et peuvent ne pas comprendre ce qui les cause.
Un avantage qui n'a pas été mentionné dans les autres réponses est que lors du fonctionnement sans pseudo-terminal , le SSH caractères d'échappement tels que ~C
ne sont pas non pris en charge ; cela permet aux programmes de transférer en toute sécurité des fichiers binaires pouvant contenir ces séquences.
Copiez un fichier binaire à l'aide d'un pseudo-terminal:
$ ssh -t anthony@remote_Host 'cat /usr/bin/free' > ~/free
Connection to remote_Host closed.
Copiez un fichier binaire sans utiliser de pseudo-terminal:
$ ssh anthony@remote_Host 'cat /usr/bin/free' > ~/free2
Les deux fichiers ne sont pas identiques:
$ diff ~/free*
Binary files /home/anthony/free and /home/anthony/free2 differ
Celui qui a été copié avec un pseudo-terminal est corrompu:
$ chmod +x ~/free*
$ ./free
Segmentation fault
tandis que l'autre n'est pas:
$ ./free2
total used free shared buffers cached
Mem: 2065496 1980876 84620 0 48264 1502444
-/+ buffers/cache: 430168 1635328
Swap: 4128760 112 4128648
Ceci est particulièrement important pour des programmes tels que scp
ou rsync
qui utilisent SSH pour le transfert de données. Ceci description détaillée du fonctionnement du protocole SCP explique comment le protocole SCP consiste en un mélange de messages de protocole textuels et de données de fichiers binaires.
Il convient de noter que même si le -t
est utilisé, le client OpenSSH ssh
refusera d'allouer un pseudo-terminal s'il détecte que son flux stdin
n'est pas un terminal:
$ echo testing | ssh -t anthony@remote_Host 'echo $TERM'
Pseudo-terminal will not be allocated because stdin is not a terminal.
dumb
Vous pouvez toujours forcer le client OpenSSH à allouer un pseudo-terminal avec -tt
:
$ echo testing | ssh -tt anthony@remote_Host 'echo $TERM'
xterm
Dans les deux cas, cela (sensiblement) ne se soucie pas si stdout
ou stderr
sont redirigés:
$ ssh -t anthony@remote_Host 'echo $TERM' >| ssh_output
Connection to remote_Host closed.
Sur l'hôte distant, nous devons faire avec ce paramètre:
/etc/sudoers
...
Defaults requiretty
Sans Sudo
$ ssh -T user@Host echo -e 'foo\\nbar' | cat -e
foo$
bar$
Et avec Sudo
$ ssh -T user@Host Sudo echo -e 'foo\\nbar' | cat -e
Sudo: sorry, you must have a tty to run Sudo
Avec Sudo, nous obtenons le retour chariot supplémentaire
$ ssh -t user@Host Sudo echo -e 'foo\\nbar' | cat -e
foo^M$
bar^M$
Connection to localhost closed.
La solution consiste à désactiver le traduire la nouvelle ligne en chariot retour-nouvelle ligne avec stty -onlcr
$ ssh -t user@Host stty -onlcr\; Sudo echo -e 'foo\\nbar' | cat -e
foo$
bar$
Connection to localhost closed.
Pensez à la compatibilité descendante.
Les 2 modes principaux de ssh sont la connexion interactive avec un tty et la commande spécifiée sans tty, car ce sont les capacités exactes de rlogin
et rsh
respectivement. ssh devait fournir un surensemble de fonctionnalités rlogin
/rsh
pour réussir le remplacement.
Les valeurs par défaut ont donc été décidées avant la naissance de ssh. Des combinaisons comme "Je veux spécifier une commande et obtenir un tty" devaient être accessibles avec de nouvelles options. Soyez heureux qu'au moins nous ayons cette option maintenant, contrairement à ce que nous utilisions rsh
. Nous n'avons pas échangé de fonctionnalités utiles pour obtenir des connexions cryptées. Nous avons des bonus!
De man ssh
:
-t Force pseudo-tty allocation. This can be used to execute arbi-
trary screen-based programs on a remote machine, which can be
very useful, e.g. when implementing menu services. Multiple -t
options force tty allocation, even if ssh has no local tty.
Cela vous permet d'obtenir une sorte de "Shell" sur le serveur distant. Pour les serveurs qui pas accordent l'accès Shell mais autorisent SSH (c'est-à-dire que Github est un exemple connu d'accès SFTP), l'utilisation de cet indicateur entraînera le serveur à rejeter votre connexion.
Le Shell a également toutes vos variables environnementales (comme $PATH
) donc l'exécution de scripts a généralement besoin d'un tty pour fonctionner.