la tubería aparecerá como una entrada en la lista de descriptores de archivos abiertos de su proceso:
% ls -l /proc/PID/fd
lr-x------ 1 xyz xyz 64 Feb 11 08:05 0 -> pipe:[124149866]
lrwx------ 1 xyz xyz 64 Feb 11 08:05 1 -> /dev/pts/2
lrwx------ 1 xyz xyz 64 Feb 11 08:05 2 -> /dev/pts/2
lr-x------ 1 xyz xyz 64 Feb 11 08:05 10 -> /tmp/foo.sh
también podrías usar algo como:
% lsof -p PID
sh 29890 xyz cwd DIR 0,44 4096 77712070 /tmp
sh 29890 xyz rtd DIR 0,44 4096 74368803 /
sh 29890 xyz txt REG 0,44 83888 77597729 /bin/dash
sh 29890 xyz mem REG 0,44 1405508 79888619 /lib/tls/i686/cmov/libc-2.11.1.so
sh 29890 xyz mem REG 0,44 113964 79874782 /lib/ld-2.11.1.so
sh 29890 xyz 0r FIFO 0,6 124149866 pipe
sh 29890 xyz 1u CHR 136,2 4 /dev/pts/2
sh 29890 xyz 2u CHR 136,2 4 /dev/pts/2
sh 29890 xyz 10r REG 0,44 66 77712115 /tmp/foo.sh
Entonces, ahora tiene el inodo de la tubería :) ahora puede buscar cualquier otro proceso en /proc/
por esa pipa. entonces tendrás el comando que te está canalizando:
% lsof | grep 124149866
cat 29889 xyz 1w FIFO 0,6 124149866 pipe
sh 29890 xyz 0r FIFO 0,6 124149866 pipe
en este ejemplo, cat
canalizado a las salas sh
. en /proc/29889
puedes encontrar un archivo llamado cmdline
que te dice, cómo se llamaba exactamente:
% cat /proc/29889/cmdline
cat/dev/zero%
los campos de la línea de comando están separados por NUL, por lo que se ve un poco feo :)
Akira sugirió usar lsof
.
Así es como podría escribirlo:
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
Ejecutándolo:
$ tail -f /var/log/messages | ./whatpipe2.sh
tail -f /var/log/messages
^C
Otra forma es usar grupos de procesos.
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
Ejecutándolo:
$ tail -f /var/log/messages | ./whatpipe1.sh
tail -f /var/log/messages
^C
Tenga en cuenta que ambos solo funcionan si el comando en el lado izquierdo de la tubería se ejecuta durante el tiempo suficiente para ps
para verlo. Dijiste que lo estabas usando con tail -f
, así que dudo que esto sea un problema.
$ sleep 0 | ./whatpipe1.sh
$ sleep 1 | ./whatpipe1.sh
sleep 1