Nome do processo na outra extremidade de um pipe unix?

8

Se dois processos estiverem conectados por um tubo,

> cmd1 | cmd2

existe alguma maneira de cmd1descobrir o nome (ou PID) do processo do outro lado do pipe ( cmd2)?

Além disso, vice-versa, existe alguma maneira de cmd2obter o nome / PID de cmd1?

Eu sei que há isatty(3)para verificar se a saída vai para (ou a entrada vem) de um terminal, então me perguntei se existe uma maneira de descobrir um pouco mais sobre o outro lado.

shark.dp
fonte
1
Isso seria específico da plataforma, na melhor das hipóteses; onde você está tentando fazer isso?
Michael Homer
Eu ficaria bem com uma versão específica do Linux.
shark.dp
5
Em teoria, poderia haver mais de um processo na outra extremidade do tubo, se cmd2bifurcado.
Nate Eldredge
6
Embora isso seja possível, duvido muito que seja uma boa ideia; esta pergunta cheira a um problema XY.
Nate Eldredge
@NateEldredge De fato:cmd1 | (cmd2 & cmd3)
Barmar

Respostas:

14

Você pode ver o tubo /proc/$PID/fd. O descritor é um link simbólico para algo assim pipe:[188528098]. Com essas informações, você pode procurar o outro processo:

$ 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

Ou, se você quiser ter certeza (para processamento automático) de que o número é o soquete e não faz parte de um nome de arquivo:

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

Com lsof4.88 e acima, você também pode usar os sinalizadores -Eou +E:

Em combinação com -p <pid>, -d <descriptor>você pode obter as informações do terminal para um descritor específico de um determinado 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

Acima nos diz que fd0 de shé um tubo com fd 1 de sleepna outra extremidade. Se você mudar -Epara +E, também receberá as informações completas para esse código de 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

(veja como lsoftambém tem o tubo no seu stdin)

Hauke ​​Laging
fonte
6
Deve-se estar preparado para que isso falhe; por exemplo, se o processo do outro lado mudou os UIDs e você não tem permissão para lsofisso.
Nate Eldredge