Determina se o processo está “conectado” a outro processo via pipes

4

Se eu fizer isso:

x | y

Existe alguma maneira de verificar, durante o tempo de execução de x, para ver se ele está conectado a y? Note que não sei o que é, e não sou responsável por iniciar y.

Especificamente, estou falando sobre o tempo de execução do Node.js, então talvez essa seja uma questão específica do Node.js. Mas, em última análise, estou me perguntando se é possível determinar qualquer tempo de execução. É possível e como?

É possível determinar se o stdout / stderr está ligado ao stdin de outro processo? Eu acho que é sobre isso que esta questão é.

    
por Alexander Mills 31.07.2017 / 06:21

4 respostas

2

Para verificar se a saída do programa está indo para um canal, com base no link , você deseja ligar para fs.fstat(FileDescriptor) e, em seguida, chame isFIFO() no objeto stat retornado (FIFO == first-in-first-out == um canal ou um pipe nomeado):

$ </dev/null node -e 'var fs=require("fs");
   fs.fstat(0,function(err,stats){ if(err) throw(err); console.log(stats.isFIFO()); });  ' 
  false
$  : | node -e 'var fs=require("fs");
   fs.fstat(0,function(err,stats){ if(err) throw(err); console.log(stats.isFIFO()); });  ' 
  true

Em C, você faria o fstat syscall e testaria o campo .st_mode do struct stat retornado usando a macro S_ISFIFO .

Se você gosta de desperdiçar ciclos de CPU e quiser usar um binário externo, pode executar test -p /dev/fd/$THE_FD para obter a resposta (ou invocar isso em um shell onde test será incorporado, ou executar stat , ou lançar algo mais capaz de determinar o tipo de arquivo).

    
por 01.08.2017 / 14:12
1

É possível, e bastante trivial, para um programa determinar se qualquer dado descritor de arquivo aberto em seu processo faz referência a um pipe ou a um FIFO. É um exercício simples no uso da função de biblioteca fstat() .

Você terá que descobrir como chamar fstat() em sua linguagem de programação preferida. Nas linguagens C ou C ++, uma função para fazer isso é bem simples:

#include <sys/types.h>  // no longer required by IEEE 1003.1:2008
#include <sys/stat.h>
#include <unistd.h>

/// \brief Check a file descriptor for being open and denoting a pipe/FIFO
extern inline
bool        /// \returns true if and only if the descriptor is open to a pipe/FIFO
is_fifo (
    int fd  ///< the file descriptor to test
) {
    struct stat s;
    return 0 <= fstat(fd, &s) && S_ISFIFO(s.st_mode);
}

A biblioteca libsystemd no systemd tem uma função de biblioteca sd_is_fifo() um pouco mais complicada.

    
por 01.08.2017 / 13:53
1

Testar se um descritor de arquivo é um canal é fácil e portátil . Descobrir o que está no outro lado do tubo não é.

Externamente, com versões recentes de lsof on Linux :

$ sleep 100 | sleep 200 &
[1] 15314 15315
$ lsof -ad0-1 -E -p 15314
COMMAND   PID     USER   FD   TYPE DEVICE SIZE/OFF     NODE NAME
sleep   15314 stephane    0u   CHR  136,1      0t0        4 /dev/pts/1
sleep   15314 stephane    1w  FIFO   0,10      0t0 17895049 pipe 15315,sleep,0r

Mostra que stdout de 15314 é a extremidade de gravação de um pipe que tem o stdin de 15315 na outra extremidade.

    
por 01.08.2017 / 14:25
0

Usando o Node.js, no tempo de execução em um sistema * nix, isso parece funcionar:

const isTTY = process.stdout.isTTY;

se verdadeiro, não está conectado a um canal de destino

se estiver indefinido, ele está conectado a um canal de destino

... pelo menos de acordo com meus testes até agora

    
por 20.09.2017 / 23:10

Tags