7

If two processes are connected by a pipe,

> cmd1 | cmd2

is there any way for cmd1 to find out the name (or PID) of the process on the other side of the pipe (cmd2)?

Also, vice versa, is there any way for cmd2 to get the name/PID of cmd1?

I know that there is isatty(3) to check if the output goes to (or the input comes from) a terminal, so I wondered if there is a way to find out a little bit more about the other hand side.

  • 1
    This would be platform-specific at best; where are you trying to do it? – Michael Homer Nov 18 '17 at 21:07
  • I'd be fine with a Linux-specific version. – shark.dp Nov 18 '17 at 21:09
  • 5
    In theory there could be more than one process on the other end of the pipe, if cmd2 forked. – Nate Eldredge Nov 19 '17 at 0:16
  • 6
    Although this may be possible, I really doubt that it's a good idea; this question smells like an XY problem. – Nate Eldredge Nov 19 '17 at 0:25
  • @NateEldredge Indeed: cmd1 | (cmd2 & cmd3) – Barmar Nov 22 '17 at 17:40
13

You can see the pipe in /proc/$PID/fd. The descriptor is a symlink to something like pipe:[188528098]. With that information you can search for the other process:

$ lsof -n | grep -w 188528098
sleep      1565   hl    1w     FIFO    0,12     0t0  188528098 pipe
sleep      1566   hl    0r     FIFO    0,12     0t0  188528098 pipe

Or, if you want to be sure (for automatic processing) that the number is the socket and not part of a file name:

$ lsof -n | awk 'NF==9 && $5=="FIFO" && $9=="pipe" && $8==188528098'

With lsof 4.88 and above, you can also use the -E or +E flags:

In combination with -p <pid>, -d <descriptor>, you can get the endpoint information for a specific descriptor of a given pid.

$ sleep 1 | sh -c 'lsof -E -ap "$$" -d 0; exit'
COMMAND   PID     USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
sh      27176 chazelas    0r  FIFO   0,10      0t0 2609460 pipe 27175,sleep,1w

Above telling us that fd 0 of sh is a pipe with fd 1 of sleep at the other end. If you change -E to +E, you also get the full information for that fd of sleep:

$ sleep 1 | sh -c 'lsof +E -ap "$$" -d 0; exit'
COMMAND   PID     USER   FD   TYPE DEVICE SIZE/OFF    NODE NAME
sleep   27066 chazelas    1w  FIFO   0,10      0t0 2586272 pipe 27067,sh,0r 27068,lsof,0r
sh      27067 chazelas    0r  FIFO   0,10      0t0 2586272 pipe 27066,sleep,1w

(see how lsof also has the pipe on its stdin)

  • 6
    One should be prepared for this to fail; e.g. if the process on the other end has changed UIDs and you don't have permission to lsof it. – Nate Eldredge Nov 19 '17 at 0:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.