[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