412 votes

Le pseudo-terminal ne sera pas attribué car stdin n'est pas un terminal

J'essaie d'écrire un scipt de shell qui crée des répertoires sur un serveur distant, puis utilise scp pour copier des fichiers de mon ordinateur local sur la télécommande. Voici ce que j'ai jusqu'à présent:

 ssh -t user@server<<EOT
DEP_ROOT='/home/matthewr/releases'
datestamp=$(date +%Y%m%d%H%M%S)
REL_DIR=$DEP_ROOT"/"$datestamp
if [ ! -d "$DEP_ROOT" ]; then
    echo "creating the root directory"
    mkdir $DEP_ROOT
fi
mkdir $REL_DIR
exit
EOT

scp ./dir1 user@server:$REL_DIR
scp ./dir2 user@server:$REL_DIR
 

Chaque fois que je le lance, je reçois ce message:

 Pseudo-terminal will not be allocated because stdin is not a terminal.
 

Et le script se bloque pour toujours.

Ma clé publique est approuvée sur le serveur et je peux exécuter toutes les commandes en dehors du script. Des idées?

587voto

carok Points 1300

Essayez ssh -t -t pour forcer l'allocation de pseudo-tty même si stdin n'est pas un terminal.

Voir aussi: Terminer la session SSH exécutée par le script bash

225voto

Emil Bojda Points 101

Également avec l'option -T from manual

Désactiver l'allocation de pseudo-tty

102voto

Dejay Clayton Points 141

Voici une solution simple:

ssh user@server "$( cat <<'EOT'
echo "These commands will be run on: $( uname -a )"
EOT
)"

Par zanco de réponse, vous n'êtes pas fournir une commande à distance à l' ssh, compte tenu de la façon dont le shell analyse la ligne de commande.

La solution ci-dessus résout ce problème de la manière suivante:

  1. ssh user@server est analysée par bash, et est interprété à l' ssh de commande, suivi par un argument user@server à être passés à l' ssh commande

  2. " commence une interpolation de chaîne, qui, une fois terminé, sera composé d'un argument à l' ssh de commande, qui dans ce cas sera interprété par ssh à la commande à distance pour exécuter en tant que user@server

  3. $( commence une commande à exécuter, avec la sortie d'être capturé par les environs interpolation de chaîne

  4. cat est une commande pour une sortie le contenu de ce fichier suit. La sortie de l' cat sera renvoyé dans la capture d'interpolation de chaîne

  5. << commence un bash heredoc

  6. 'EOT' indique que le nom de la heredoc est EOT. Les apostrophes ' environnant EOT spécifie que le heredoc doit être analysé comme un nowdoc, qui est une forme spéciale de heredoc dont le contenu n'obtenez pas interpolées par bash, mais plutôt transmises dans le format littéral

  7. Tout contenu qui est rencontrée entre <<'EOT' et <newline>EOT<newline> sera ajouté à la nowdoc de sortie

  8. EOT met fin à la nowdoc, résultant en une nowdoc fichier temporaire créé et transmis à l'appelant cat commande. cat sorties de la nowdoc et passe à la sortie de retour à la capture d'interpolation de chaîne

  9. ) conclut la commande à exécuter

  10. " conclut la capture d'interpolation de chaîne. Le contenu de l'interpolation de chaîne seront transmises ssh comme un seul argument de ligne de commande, qui ssh s'interpréter comme la commande à distance pour exécuter en tant que user@server

67voto

Andrew Prock Points 1462

Je suis l'ajout de cette réponse, car il a résolu un autre problème que j'ai eu avec le même message d'erreur.

Problème: j'avais installé cygwin sous Windows et a été d'obtenir cette erreur: Pseudo-terminal will not be allocated because stdin is not a terminal

Résolution: Il s'avère que je n'avais pas installé le client openssh programme et les services publics. Parce que cygwin été en utilisant des Fenêtres de mise en œuvre de ssh, pas la version cygwin. La solution a été d'installer openssh environnement cygwin.

23voto

Henning Makholm Points 13132

Je ne sais pas d'où le blocage vient de la, mais la redirection (ou de la tuyauterie) des commandes en ssh interactif est en général une recette de problèmes. Il est plus robuste à utiliser la commande-pour-courir-comme-un-dernier-argument de style et de passer le script sur le ssh en ligne de commande:

ssh user@server 'DEP_ROOT="/home/matthewr/releases"
datestamp=$(date +%Y%m%d%H%M%S)
REL_DIR=$DEP_ROOT"/"$datestamp
if [ ! -d "$DEP_ROOT" ]; then
    echo "creating the root directory"
    mkdir $DEP_ROOT
fi
mkdir $REL_DIR'

(Tout en un géant de l' '-délimité multiligne argument de ligne de commande).

Le pseudo-terminal de message est à cause de votre -t qui demande ssh essayer de faire de l'environnement, il s'exécute sur l'ordinateur distant ressembler à un véritable terminal pour les programmes qui s'exécutent. Votre client ssh refuse de le faire parce que sa propre entrée standard n'est pas un terminal, de sorte qu'il n'a aucun moyen de passer le terminal spécial Api à partir de l'ordinateur distant vers votre terminal à l'.

Que cherchiez-vous à atteindre avec -t de toute façon?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X