Você pode usar um pipe nomeado e conectar os dois processos manualmente. Inicie-os na ordem oposta, de modo que o lado esquerdo seja executado em primeiro plano e você obtenha o status de saída de $?
como de costume.
#!/bin/sh
dir=$(mktemp -d)
mkfifo "$dir/p"
cat < "$dir/p" > /dev/null &
( echo foo; exit 12; ) > "$dir/p"
echo "exit status: left: $?"
rm -r "$dir"
Ou, se você quiser os dois, obtenha o PID do processo em segundo plano de $!
e wait
para obter o status de saída.
#!/bin/sh
dir=$(mktemp -d)
mkfifo "$dir/p"
( echo foo; exit 12; ) > "$dir/p" & # left-hand side
pidleft=$!
( cat; exit 34; ) < "$dir/p" > /dev/null & # right-hand side
pidright=$!
wait "$pidleft"; exitleft=$?
wait "$pidright"; exitright=$?
echo "exit status: left: $exitleft right: $exitright"
rm -r "$dir"
Você ainda pode deixar a segunda parte do tubo em primeiro plano, eu só queria fazer simetricamente.
Você também pode, por exemplo armazene o status de saída para os arquivos e busque-os de lá:
#/bin/sh
( somecmd; echo "$?" > exit1 ) | ( cat; echo "$?" > exit2)
echo "exit status: left: $(cat exit1) right: $(cat exit2)"
Eu não acho que um pipe nomeado será de muita utilidade aqui, já que o status de saída é apenas um par de bytes. O shell aguardará a conclusão do pipeline antes de tentar ler exit1
e exit2
na segunda linha.
Se você quiser usar pipes nomeados, precisará colocar o pipeline em segundo plano, já que as gravações nos canais serão bloqueadas até que o lado da leitura seja aberto.
#/bin/sh
mkfifo exit1 exit2
( somecmd; echo "$?" > exit1 ) | ( cat; echo "$?" > exit2) &
echo "exit status: left: $(cat exit1) right: $(cat exit2)"
No entanto, se o cat
s ler os canais não for executado por algum motivo,
sub-submarinos escrevendo para eles serão bloqueados indefinidamente em segundo plano.