[Linux] ssh, faire suivre tty *et* stdin
Arthur Pons
arthur.pons@::1
Sam 9 Nov 17:32:36 CET 2024
Salut tout le monde !
=======
La question :
Est-ce qu'il est possible de faire en sorte qu'ssh connecte la stdin
côté serveur sur un pipe local *et* la tty distante sur la tty locale
pour que le script distant puisse récupérer ce qui est lu depuis le pipe
*et* offrir de l'interactivité à la personne l'ayant lancé à distance
depuis son terminal ?
De préférence via une config ssh et/ou une modification du script
distant. Je tiens assez à la simplicité de "cat fichier | ssh
user@::1 'script'"
======
Si ce n'est pas clair, l'explication :
Je suis en train d'écrire un outil dont j'aimerais que l'interactivité
soit de la sorte :
J'ai en local un fichier avec du texte dedans.
J'ai à distance, sur un serveur sur lequel je peux ssh, un script qui
peut lire ce fichier dans stdin et en faire des trucs. Par ailleurs ce
script utilise parfois le built-in read pour lire la tty pour faire des
"pauses" dans le déroulement du script.
J'aimerais, dans l'idéal, pouvoir utiliser l'outil de cette manière :
cat fichier-local | ssh -t user@::1 'script'
Le script lira la stdin, fera ce qu'il faut avec et continuera. A un
moment il rencontrera
read continue < /dev/tty
ce qui devrait pauser son exécution. A ce moment je souhaite pouvoir
appuyer sur entrée et reprendre l'exécution.
Je crois (j'insiste sur le coire) que ce fonctionnement est assimilable
à cet exemple bidon :
echo "abcd" | ssh -t user@::1 'echo avant;read _;echo test'
En local aucun souci bien sûr. Aucun souci non plus si on lance la
commande ssh sans qu'elle lise dans un pipe du moment que l'on n'oublie
pas de renseigner -t (j'écris les moments de pause entre **) :
$ ssh -t user@::1 'echo avant;read _;echo après'
avant
*ici j'appuie sur entrée*
après
Mais si ssh lit depuis un pipe tout est déroulé d'un coup :
$ echo "abcd" | ssh -t user@::1 'cat > tmpf;read _;echo test'
*tmpf est bien créé*
test
Je crois comprendre que c'est parce que la stdin distante n'est plus mon
terminal mais le pipe. Un peu comme si en local j'écrivais :
$ : | (echo "avant"; read _; echo "après" )
avant
après
Que l'on pourrait régler en rebranchant read sur la tty à la main :
$ : | (echo "avant"; read _ < /dev/tty ; echo "après" )
avant
*pause*
après
mais via ssh on obtient une erreur :
$ : | ssh -t meso@::1 'echo "avant"; read _ < /dev/tty ; echo "après"'
Pseudo-terminal will not be allocated because stdin is not a terminal.
avant
après
zsh:1: aucun périphérique ou adresse: /dev/tty
En ayant l'intuition que ça n'allait pas résoudre mon problème j'ai tout
de même tenté l'option -tt :
$ : | ssh -tt meso@::1 'echo "avant"; read _ < /dev/tty ; echo "après"'
avant
qui bloque indéfiniment, impossible à interrompre autrement qu'avec un
ctrl+c.
=====
Je répète la question pour toute personne m'ayant lu jusqu'au bout :
Est-ce qu'il est possible de faire en sorte qu'ssh connecte la stdin
côté serveur sur le pipe local *et* la tty distante sur la tty locale
pour que le script distant puisse récupérer ce qui est lu depuis le pipe
*et* offrir de l'interactivité à la personne l'ayant lancé à distance
depuis son terminal ?
De préférence via une config ssh et/ou une modification du script
distant. Je tiens assez à la simplicité de "cat fichier | ssh
user@::1 'script'"
Est-ce que je pose la bonne question même ?
Sinon au pire je peux déjà transférer le script sur le serveur et
parvenir à mes fins en deux temps (< fichier ssh 'cat > fichier'; ssh -t
'< fichier script') mais j'aurais préféré le faire en une fois.
Si vous voulez voir l'outil c'est ici : http://arthur.bebou.netlib.re/qcm
Si jamais vous avez un moyen génial et simple de contourner ce problème
en l'abordant autrement je prends aussi.
Bon weekend :)
Arthur
Plus d'informations sur la liste de diffusion linux