die Pipe erscheint als Eintrag in der Liste der offenen Dateideskriptoren Ihres Prozesses:
% 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
Sie könnten auch so etwas verwenden wie:
% 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
Also, dann hast du den Inode der Pipe :) Du kannst jetzt jeden anderen Prozess unter /proc/
durchsuchen für dieses Rohr. dann haben Sie den Befehl, der zu Ihnen geleitet wird:
% lsof | grep 124149866
cat 29889 xyz 1w FIFO 0,6 124149866 pipe
sh 29890 xyz 0r FIFO 0,6 124149866 pipe
in diesem Beispiel cat
zu den Stationen sh
geleitet . in /proc/29889
finden Sie eine Datei namens cmdline
was dir sagt, was genau hieß:
% cat /proc/29889/cmdline
cat/dev/zero%
die Felder der Kommandozeile sind durch NUL getrennt, dadurch sieht es etwas hässlich aus :)
Akira schlug vor, lsof
zu verwenden .
So könnten Sie es skripten:
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
Ausführen:
$ tail -f /var/log/messages | ./whatpipe2.sh
tail -f /var/log/messages
^C
Eine andere Möglichkeit ist die Verwendung von Prozessgruppen.
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
Ausführen:
$ tail -f /var/log/messages | ./whatpipe1.sh
tail -f /var/log/messages
^C
Beachten Sie, dass beide nur funktionieren, wenn der Befehl auf der linken Seite der Pipe lange genug für ps
ausgeführt wird Es zu sehen. Sie sagten, Sie würden es mit tail -f
verwenden , daher bezweifle ich, dass dies ein Problem ist.
$ sleep 0 | ./whatpipe1.sh
$ sleep 1 | ./whatpipe1.sh
sleep 1