Determinando se o processo vizinho no pipeline tem execve'd

1

Eu tenho uma seqüência de processos em um pipeline:

cat haystack | grep needle | my_process | less

Meu entendimento é que o shell bifurca e executa execve para cada comando simultaneamente.

No my_process, como eu poderia determinar se o grep e o menos foram totalmente iniciados (execve'd), assumindo que eu já determinei seus PIDs?

    
por ojb 17.01.2018 / 09:01

3 respostas

2

Bem, no Linux, você pode verificar /proc/PID/exe :

(p=$BASHPID; /bin/ls -l /proc/$p/exe; exec /bin/ls -l /proc/$p/exe)
... 0 Jan 17 10:34 /proc/17816/exe -> /bin/bash
... 0 Jan 17 10:34 /proc/17816/exe -> /bin/ls

Mas eu não consigo ver para que serve isso, o shell não vai ler / gravar no pipe antes do exec , então o pipeline funciona perfeitamente, mesmo que haja uma pequena janela de tempo antes do exec . E realmente, é uma janela de tempo pequena , eu não ficaria surpreso se o exec já tivesse acontecido quando você pudesse até mesmo chegar lá para verificar qual programa está sendo executado.

    
por 17.01.2018 / 09:37
2

É para isso que é inerente aos descritores de arquivos abertos.

Faça um FIFO. Abra um descritor de arquivo somente write-on-exec no shell pai. Todos os filhos fork() ed herdarão e, em seguida, os fecharão quando execve() . Abra um descritor de arquivo somente leitura para ele no processo que precisa detectar o execve() ou que esse processo herde um descritor de arquivo somente leitura e já aberto. Quando as extremidades somente de gravação forem fechadas pelo execve() , o final somente leitura retornará EOF.

Para detectar o execve() s individual, generalize para múltiplos FIFOs. Na verdade, nesse ponto, você não pode se incomodar com FIFOs e apenas usar um segundo conjunto de pipes , com seus descritores de arquivos de gravação configurados como close-on-exec.

Como você não explicou o que é isso para , descobrir como criar isso no que você está realmente tentando fazer é apenas sua tarefa.

    
por 17.01.2018 / 12:13
1

Apenas Linux e com zsh ,

$ autoload zsh/stat
$ (zstat +link /proc/*/fd/0(e'{[[ $REPLY -ef /proc/self/fd/1 ]] &&
    reply=$REPLY:h:h/exe}')) | cat
/bin/cat

Isso lhe dá o caminho do executável do (s) processo (s) que tem o mesmo pipe que o stdout desse subshell aberto em seu stdin. Então, acima, nesse ponto, cat já havia sido executado.

    
por 17.01.2018 / 16:09