> On me rappelle que ssh n'alloue pas de psuedo-tty. Que se passe-t-il? Cela enrichirait la question de comprendre quel est le problème.
Air
5
@Air Il n'y a pas un problème que j'essayais de résoudre. J'avais essayé de comprendre comment SSH était implémenté. La question est très claire et la réponse d’Andrew B répond bien à la question. La réponse peut être résumée ainsi: courir ssh -ttoujours est mauvais parce que certaines commandes peuvent se briser de manière étrange. Tandis que l'exécution d'une commande nécessitant un PTY sans aucun résultat génère un message d'erreur indiquant que vous avez besoin d'un terminal.
Chas. Owens
Réponses:
73
La principale différence est le concept d' interactivité . Cela ressemble à l'exécution de commandes localement dans un script, par opposition à leur saisie par vous-même. C'est différent en ce sens qu'une commande à distance doit choisir une valeur par défaut et que la non-interactive est la plus sûre. (et généralement le plus honnête)
STDIN
Si un PTY est alloué, les applications peuvent le détecter et savoir qu’il est prudent d’inviter l’utilisateur à fournir des informations supplémentaires sans casser des choses. Il existe de nombreux programmes qui ignorent l'étape consistant à inviter l'utilisateur à entrer si aucun terminal n'est présent, et c'est une bonne chose. Sinon, les scripts se bloqueraient inutilement.
Votre entrée sera envoyée au serveur distant pour la durée de la commande. Cela inclut les séquences de contrôle. Alors qu'une Ctrl-cpause provoquerait 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. Cela entraîne la nécessité de "marteler" la frappe afin de 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 ssh -tdéconseille d' utiliser des scripts non surveillés, tels que crons. Un shell non interactif demandant à une commande distante de se comporter de manière interactive pour une entrée est une source de problèmes.
Vous pouvez également tester la présence d'un terminal dans vos propres scripts shell. Pour tester STDIN avec les nouvelles versions de bash:
# fd 0 is STDIN
[ -t 0 ]; echo $?
STDOUT
Lorsque vous aliasez sshsur ssh -t, vous pouvez vous attendre à obtenir un retour chariot supplémentaire à la fin de votre ligne. Ce n'est peut-être pas visible pour vous, mais c'est là; il apparaîtra comme ^Mlorsqu'il est connecté à cat -e. Vous devez ensuite déployer tous les 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.
Il y a également le risque que les programmes supposent qu'ils peuvent rendre une sortie qui n'est pas conviviale pour la redirection de fichier. Normalement, si vous redirigiez STDOUT vers un fichier, le programme reconnaîtrait que votre STDOUT n'est pas un terminal et omettra les codes de couleur. Si la redirection STDOUT provient de la sortie du client ssh et qu'un PTY est associé à l'extrémité distante du client, les programmes distants ne peuvent pas faire une telle distinction et vous allez vous retrouver avec des ordures dans votre fichier de sortie. La redirection de la sortie vers un fichier situé à l' extrémité distante de la connexion doit toujours fonctionner comme prévu.
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 de ces problèmes. Nous le faisons tous à un moment donné. Les membres de l' équipe peuvent également ne pas se rendre compte / se rappeler que cet alias est en place, qui à son tour créer des problèmes pour vous quand ils écrivent des scripts qui utilisent votre alias.
Le pseudonyme sshde ssh -test 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.
On a presque l'impression d'avoir travaillé dans une équipe qui a fait cela ...
Andrew B
À la portée couverte par cette réponse, c'est un super. Mais la question avait une portée plus large, voulant essentiellement connaître TOUTES les différences (à quoi s'attendre). Informations supplémentaires: Au niveau du processus, -t allouera FIRST un tty, puis exécutera un shell (en cours de chemin, en recherchant / etc / profile et ~ / .bash_profile), puis ENSUIVANT la commande. Sans -t, ssh INSTEAD générera différents fichiers env (/etc/bash.bashrc, puis ~ / .bashrc), puis EXÉCUTERA votre commande. Cela signifie que vous pouvez voir des comportements très différents dans chacun: $ PATH plus court, peut-être une erreur 'unary' bash parce que la variable ENV que vous supposez ne s'y trouve pas ...
Scott Prive
@Crossfit Nous avons abordé le sujet des coquilles de connexion par rapport aux non dans les commentaires d'une autre réponse, mais nous n'avons pas détaillé les différences environnementales car le PO avait déjà examiné la question pour répondre à ses besoins particuliers. S'il vous plaît, n'hésitez pas à ajouter des détails là où vous voyez la possibilité de le faire, car cela pourrait aider d'autres personnes qui tombent sur cette question / réponse
Andrew B
33
Caractères d'échappement SSH et transfert de fichiers binaires
Un autre avantage qui n’a pas été mentionné dans les autres réponses est que, lorsqu’ils fonctionnent sans pseudo-terminal , les caractères d’échappement SSH tels que ne~C sont pas pris en charge ; Cela permet aux programmes de transférer des fichiers binaires pouvant contenir ces séquences en toute sécurité.
Preuve de concept
Copier un fichier binaire en utilisant un pseudo-terminal:
Ceci est particulièrement important pour les programmes tels que scpou rsyncutilisant SSH pour le transfert de données. Cette description détaillée du fonctionnement du protocole SCP explique en quoi celui-ci consiste en un mélange de messages de protocole textuels et de données de fichier binaires.
OpenSSH vous aide à vous protéger de vous-même
Il est à noter que même si l' -tindicateur est utilisé, le sshclient OpenSSH refusera d'allouer un pseudo-terminal s'il détecte que son stdinflux 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:
Bien, mais la sortie est en retrait /: Est-ce que vous savez si vous pouvez le renvoyer automatiquement (genre Unix)?
Boop
1
Pensez à la compatibilité ascendante.
Les 2 modes principaux de ssh sont: login-interactive avec tty et commande-spécifiée sans tty, car c’étaient les capacités exactes de rloginet rshrespectivement. SSH devait fournir un sur-ensemble de rlogin/ rshfonctionnalités pour réussir son remplacement.
Donc, les valeurs par défaut ont été décidées avant la naissance de ssh. Des combinaisons telles que "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 échangé aucune fonctionnalité utile pour obtenir des connexions cryptées. Nous avons des bonus!
-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 un "shell" sur le serveur distant. Pour les serveurs qui n'accordent pas d' accès shell mais autorisent SSH (Github est un exemple connu d'accès SFTP), l'utilisation de cet indicateur entraîne le rejet de votre connexion par le serveur.
Le shell contient également toutes vos variables d'environnement (comme $PATH), de sorte que l'exécution de scripts nécessite généralement l'utilisation d'un terminal.
Cela ne répond pas à la question. Je sais déjà comment allouer un pseudo-tty. Je veux savoir pourquoi je ne devrais pas toujours en attribuer un.
Chas. Owens
1
@ Chas.Owens Parce que, comme je l’ai souligné dans la réponse, certains serveurs SSH n’autorisent pas l’ accès au tty et la connexion sera coupée si vous en demandez une au serveur.
Nathan C
5
Je pense que vous êtes peut-être en train de confondre une partie de votre terminologie. Ce n'est pas un shell simplement parce qu'un PTY y est associé. Il y a généralement trois types de coque: non-interactive, interactiveet login. loginest une caractéristique supplémentaire des deux autres types de coque. Les permutations de ces trois fichiers déterminent quels fichiers sont générés lors de la connexion, ce qui influence à son tour la façon dont l'environnement sera initialisé. (variables, comme vous l'avez mentionné)
Andrew B
3
@ AndrewB Vous avez raison ... J'ai aussi appris quelque chose de cette question. :)
ssh -t
toujours est mauvais parce que certaines commandes peuvent se briser de manière étrange. Tandis que l'exécution d'une commande nécessitant un PTY sans aucun résultat génère un message d'erreur indiquant que vous avez besoin d'un terminal.Réponses:
La principale différence est le concept d' interactivité . Cela ressemble à l'exécution de commandes localement dans un script, par opposition à leur saisie par vous-même. C'est différent en ce sens qu'une commande à distance doit choisir une valeur par défaut et que la non-interactive est la plus sûre. (et généralement le plus honnête)
STDIN
Ctrl-c
pause provoquerait 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. Cela entraîne la nécessité de "marteler" la frappe afin de 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
ssh -t
déconseille d' utiliser des scripts non surveillés, tels que crons. Un shell non interactif demandant à une commande distante de se comporter de manière interactive pour une entrée est une source de problèmes.Vous pouvez également tester la présence d'un terminal dans vos propres scripts shell. Pour tester STDIN avec les nouvelles versions de bash:
STDOUT
ssh
surssh -t
, vous pouvez vous attendre à obtenir un retour chariot supplémentaire à la fin de votre ligne. Ce n'est peut-être pas visible pour vous, mais c'est là; il apparaîtra comme^M
lorsqu'il est connecté àcat -e
. Vous devez ensuite déployer tous les 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:
Bien qu'il soit possible de contourner ces problèmes, vous allez inévitablement oublier de concevoir des scripts autour de ces problèmes. Nous le faisons tous à un moment donné. Les membres de l' équipe peuvent également ne pas se rendre compte / se rappeler que cet alias est en place, qui à son tour créer des problèmes pour vous quand ils écrivent des scripts qui utilisent votre alias.
Le pseudonyme
ssh
dessh -t
est 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.la source
Caractères d'échappement SSH et transfert de fichiers binaires
Un autre avantage qui n’a pas été mentionné dans les autres réponses est que, lorsqu’ils fonctionnent sans pseudo-terminal , les caractères d’échappement SSH tels que ne
~C
sont pas pris en charge ; Cela permet aux programmes de transférer des fichiers binaires pouvant contenir ces séquences en toute sécurité.Preuve de concept
Copier un fichier binaire en utilisant un pseudo-terminal:
Copier un fichier binaire sans utiliser de pseudo-terminal:
Les deux fichiers ne sont pas identiques:
Celui qui a été copié avec un pseudo-terminal est corrompu:
tandis que l'autre n'est pas:
Transfert de fichiers sur SSH
Ceci est particulièrement important pour les programmes tels que
scp
oursync
utilisant SSH pour le transfert de données. Cette description détaillée du fonctionnement du protocole SCP explique en quoi celui-ci consiste en un mélange de messages de protocole textuels et de données de fichier binaires.OpenSSH vous aide à vous protéger de vous-même
Il est à noter que même si l'
-t
indicateur est utilisé, lessh
client OpenSSH refusera d'allouer un pseudo-terminal s'il détecte que sonstdin
flux n'est pas un terminal:Vous pouvez toujours forcer le client OpenSSH à allouer un pseudo-terminal avec
-tt
:Dans les deux cas, peu importe la raison (sensuellement)
stdout
oustderr
sont redirigés:la source
Sur l'hôte distant, nous devons faire avec ce paramètre:
Sans sudo
Et avec sudo
Avec sudo nous obtenons le retour supplémentaire
La solution consiste à désactiver la nouvelle ligne à traduire en chariot retour-nouvelle ligne avec
stty -onlcr
la source
Pensez à la compatibilité ascendante.
Les 2 modes principaux de ssh sont: login-interactive avec tty et commande-spécifiée sans tty, car c’étaient les capacités exactes de
rlogin
etrsh
respectivement. SSH devait fournir un sur-ensemble derlogin
/rsh
fonctionnalités pour réussir son remplacement.Donc, les valeurs par défaut ont été décidées avant la naissance de ssh. Des combinaisons telles que "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 échangé aucune fonctionnalité utile pour obtenir des connexions cryptées. Nous avons des bonus!la source
De
man ssh
:Cela vous permet d’obtenir un "shell" sur le serveur distant. Pour les serveurs qui n'accordent pas d' accès shell mais autorisent SSH (Github est un exemple connu d'accès SFTP), l'utilisation de cet indicateur entraîne le rejet de votre connexion par le serveur.
Le shell contient également toutes vos variables d'environnement (comme
$PATH
), de sorte que l'exécution de scripts nécessite généralement l'utilisation d'un terminal.la source
non-interactive
,interactive
etlogin
.login
est une caractéristique supplémentaire des deux autres types de coque. Les permutations de ces trois fichiers déterminent quels fichiers sont générés lors de la connexion, ce qui influence à son tour la façon dont l'environnement sera initialisé. (variables, comme vous l'avez mentionné)