Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

ssh avec 3 fd, possible ?

2 réponses
Avatar
Cyrille Lefevre
Bonjour,

j'ai besoin d'une connexion ssh avec 3 descripteurs de fichier en sortie.=
=2E.

une id=E9e sur la m=E9thode =E0 employer ?

l'id=E9e de d=E9part est d'avoir une 2eme sortie d'erreur redirig=E9e sur=
=20
stdout, mais distincte tout de m=EAme afin que les affectations de
variables ne soient pas pollu=E9es par les messages d'erreurs, genre :

(
exec 3>&1
x=3D$(echo x; echo ko >&2; echo ok >&3)
# x vaut bien x
) > messages_ok 2> messages_ko

pas de pb en local, mais via ssh, =E7a se complique...

ssh host "exec 3>&0; echo 1; echo 2 >&2; echo 3 >&3" 0>&3
ne marche pas car ssh ne sait pas =E9crire sur stdin :(

pour le moment, j'essaye une m=E9thode avec des fifos en faisant
passer les flux 2 et 3 sur stderr avec des marqueurs, mais c'est
trop lourd =E0 mon gout... sans parler du pb de d=E9synchronisation
dans la log de sortie du fait de la bufferisation de stdout.

PS : ksh88 uniquement :) pas de zsh, perl, et autres joyeuset=E9s...

Cordialement,

Cyrille Lefevre.
--=20
mailto:Cyrille.Lefevre-news%nospam@laposte.net.invalid
supprimer "%nospam% et ".invalid" pour me repondre.
remove "%nospam" and ".invalid" to answer me.

2 réponses

Avatar
LENHOF Jean-Yves
Le Mon, 28 Apr 2008 13:15:40 +0200, Cyrille Lefevre a écrit:

Bonjour,

j'ai besoin d'une connexion ssh avec 3 descripteurs de fichier en
sortie...

une idée sur la méthode à employer ?

l'idée de départ est d'avoir une 2eme sortie d'erreur redirigée sur
stdout, mais distincte tout de même afin que les affectations de
variables ne soient pas polluées par les messages d'erreurs, genre :

(
exec 3>&1
x=$(echo x; echo ko >&2; echo ok >&3) # x vaut bien x
) > messages_ok 2> messages_ko

pas de pb en local, mais via ssh, ça se complique...

ssh host "exec 3>&0; echo 1; echo 2 >&2; echo 3 >&3" 0>&3 ne marche pas
car ssh ne sait pas écrire sur stdin :(

pour le moment, j'essaye une méthode avec des fifos en faisant passer
les flux 2 et 3 sur stderr avec des marqueurs, mais c'est trop lourd à
mon gout... sans parler du pb de désynchronisation dans la log de sortie
du fait de la bufferisation de stdout.

PS : ksh88 uniquement :) pas de zsh, perl, et autres joyeusetés...

Cordialement,

Cyrille Lefevre.


Salut Cyrille,

Puisque ds une autre vie tu me parlais bcp de BSD, je me demandes si ce
lien ne pourrait pas t'aider, c'est à base des commandes "faucet", "hose"
et forwarding ssh



http://web.purplefrog.com/~thoth/netpipes/netpipes.html

Cordialement,

Jean-Yves

Avatar
Cyrille Lefevre
Salut Cyrille,


Salut Jean-Yves,

Puisque ds une autre vie tu me parlais bcp de BSD, je me demandes si ce


pour le moment, j'ai lâché le morceau, cela me prenait trop de temps...
sinon, toujours dans le noOord ? fait beau là bas ? :)

lien ne pourrait pas t'aider, c'est à base des commandes "faucet", "hose"
et forwarding ssh


effectivement, ce n'est pas mal... je met ça sous le coude.

http://web.purplefrog.com/~thoth/netpipes/netpipes.html


pour l'heure, j'utilise la saloperie ci-dessous et j'appelle ssh de la
façon suivante : PeuSshFilterLog ssh ... auparavant, j'ai un :
exec 3>&1, d'ou le test sur $_PEU_FD, ontrap le ferme : exec 3>&-

j'ai viré les trap USR1 et 2 ainsi que les kill -USR1 et -USR2 car, de
mémoire, il me manquait la ou les dernières lignes !

tout ce qui est trace qqc me permet d'activer les traces au besoin pour
une, plusieurs ou toutes fonctions. j'aurais pu faire plus simple en ksh
(typeset -ft), mais sous bash, c'est tout ou rien... en tous cas, pas
comme on veut... quelle merde ce shell ! pas que pour ça d'ailleurs. ..

pour autant, je crois même que ça marche sous bash, un exploit !

en fait, je suis en cours de validation ce que j'ai développé c es
derniers temps et c'est un point sur lequel je ne me suis pas encore
penché. à ce propos, c'est pour cela qu'il y a un 2nd pattern c ar je
crois qu'il y a un pb avec le 1er.

PS : l'idée de départ et de rediriger les messages d'erreur for matés
sur la sortie standard alors que cette sortie est utilisée pour
récupérer le résultat de commandes lancées via ssh. l es messages
formatés sont donc affichés sur la sortie 3 qui est une copie d e la
sortie 1, ce qui permet de faire var=$(foo ou ssh foo) sans avoir $var
pollué par les messages d'erreur formatés. ne me demandez pas p ourquoi,
c'est comme ça car les exploitants attendent ces messages sur la sor tie
1, la sortie 2 étant réservée aux traces (set -x)...

function PreSshFilterLog # none
{
set +x; eval $(trace -q 'PreSshFilterLog' "$@")

if [[ -t 1 && -t 2 ]]; then
set +x; eval ${trace}
return 0
fi

typeset
pattern='+([0-9])/+([0-9])/+([0-9])_+([0-9]):+([0-9]):+([0-9]) %
+([!(])(+([!)]))-[a-z]-*'
typeset pattern='* % *'
typeset logfile="${PEU_LOG}/${PEU_PROGNAME%.sh}.log.$$"
typeset outfifo="${PEU_TMP}/${PEU_PROGNAME%.sh}.out.$$"
typeset errfifo="${PEU_TMP}/${PEU_PROGNAME%.sh}.err.$$"
typeset line=

${_RM} -f "${logfile}"

${_RM} -f "${outfifo}"
${_MKFIFO} "${outfifo}"

(
: trap exit USR1
trap '${_RM} -f "${outfifo}"' EXIT
while read line; do
if [[ ${line} = ${pattern} ]]; then
print -r -- "3 ${line}"
else
print -r -- "1 ${line}"
fi
done < "${outfifo}" >> "${logfile}" 2> /dev/null
) &
_PEU_OUT_PID="$!"

${_RM} -f "${errfifo}"
${_MKFIFO} "${errfifo}"

(
: trap exit USR2
trap '${_RM} -f "${errfifo}"' EXIT
while read line; do
if [[ ${line} = ${pattern} ]]; then
print -r -- "3 ${line}"
else
print -r -- "2 ${line}"
fi
done < "${errfifo}" >> "${logfile}" 2> /dev/null
) &
_PEU_ERR_PID="$!"

exec 5>&1 4>&2 > "${outfifo}" 2> "${errfifo}"

set +x; eval ${trace}
return 0
}

function PeuSshFilterLog # cmd [arg...]
{
set +x; eval $(trace -q 'PeuSshFilterLog' "$@")
integer coderet=0

if [[ -z ${_PEU_FD} ]]; then
( "$@" )
coderet=$?
else
(
PreSshFilterLog
trap ontrap HUP INT QUIT TERM
trap PostSshFilterLog EXIT

( "$@" )
)
coderet=$?
fi

set +x; eval ${trace}
return ${coderet}
}

function PostSshFilterLog # none
{
set +x; eval $(trace -q 'PostSshFilterLog' "$@")

if [[ -z ${_PEU_OUT_PID} ]]; then
set +x; eval ${trace}
return 0
fi

typeset logfile="${PEU_LOG}/${PEU_PROGNAME%.sh}.log.$$"
typeset fd= rest=

exec 1>&5 2>&4 5>&- 4>&-

if [[ -n ${_PEU_OUT_PID} ]]; then
: kill -USR1 "${PEU_OUT_PID}"
wait "${PEU_OUT_PID}"
_PEU_OUT_PID=
fi

if [[ -n ${_PEU_ERR_PID} ]]; then
: kill -USR2 "${PEU_ERR_PID}"
wait "${PEU_ERR_PID}"
_PEU_ERR_PID=
fi

exec 5>&1 4>&2

while read fd rest; do
case ${fd} in
'1') print -r -- "${rest}" ;;
'2') print -ru2 -- "${rest}" ;;
'3') print -ru3 -- "${rest}" ;;
esac
done < "${logfile}"

exec 1>&5 2>&4 5>&- 4>&-

${_RM} -f "${logfile}"

set +x; eval ${trace}
return 0
}


Regards, Cordialement,

Cyrille Lefevre.
--
mailto:Cyrille.Lefevre-news%
supprimer "%nospam% et ".invalid" pour me repondre.
remove "%nospam" and ".invalid" to answer me.