Akira sugeriu usar lsof
.
Veja como você pode fazer o script:
whatpipe2.sh
#!/bin/bash
pid=$$
pgid=$(ps -o pgid= -p $pid)
lsofout=$(lsof -g $pgid)
pipenode=$(echo "$lsofout" | awk '$5 == "0r" { print $9 }')
otherpids=$(echo "$lsofout" | awk '$5 == "1w" { print $2 }')
for pid in $otherpids; do
if cmd=$(ps -o cmd= -p $pid 2>/dev/null); then
echo "$cmd"
break
fi
done
Executando:
$ tail -f /var/log/messages | ./whatpipe2.sh
tail -f /var/log/messages
^C
Outra maneira é usar grupos de processos.
whatpipe1.sh
#!/bin/bash
pid=$$
# ps output is nasty, can (and usually does) start with spaces
# to handle this, I don't quote the "if test $_pgrp = $pgrp" line below
pgrp=$(ps -o pgrp= -p $pid)
psout=$(ps -o pgrp= -o pid= -o cmd=)
echo "$psout" | while read _pgrp _pid _cmd; do
if test $_pgrp = $pgrp; then
if test $_pid != $pid; then
case $_cmd in
ps*)
# don't print the "ps" we ran to get this info
# XXX but this actually means we exclude any "ps" command :-(
;;
*)
echo "$_cmd"
;;
esac
fi
fi
done
Executando:
$ tail -f /var/log/messages | ./whatpipe1.sh
tail -f /var/log/messages
^C
Note que ambos funcionam apenas se o comando no lado esquerdo do canal for executado por tempo suficiente para que ps
o veja. Você disse que estava usando com tail -f
, então duvido que isso seja um problema.
$ sleep 0 | ./whatpipe1.sh
$ sleep 1 | ./whatpipe1.sh
sleep 1