Piping dados para um fifo com EOFs a cada segundo

1

Estou tentando enviar alguns dados binários brutos para um fifo (out.pipe) e garantir que os EOFs sejam enviados em intervalos regulares. Eu não entendo porque a seguinte linha não vai fazer o que eu quero:

while true; do read -t 1 -N 128 line; echo -n $line > out.pipe; done

Parece que, quando ocorre o tempo limite, $line recebe um valor vazio e, mesmo quando isso não ocorre, todas as novas linhas são removidas da entrada. Este não é o meu entendimento do que deve acontecer de acordo com este documento :

-N nchars

read returns after reading exactly nchars characters rather than waiting for a complete line of input, unless EOF is encountered or read times out. Delimiter characters encountered in the input are not treated specially and do not cause read to return until nchars characters are read.

-t timeout

Cause read to time out and return failure if a complete line of input (or a specified number of characters) is not read within timeout seconds. timeout may be a decimal number with a fractional portion following the decimal point. This option is only effective if read is reading input from a terminal, pipe, or other special file; it has no effect when reading from regular files. If read times out, read saves any partial input read into the specified variable name. If timeout is 0, read returns immediately, without trying to read and data. The exit status is 0 if input is available on the specified file descriptor, non-zero otherwise. The exit status is greater than 128 if the timeout is exceeded.

Sem o parâmetro -N 128 no parâmetro read e -n no echo , isso é muito próximo do que desejo. O problema é que as novas linhas são tratadas como especiais e são enviadas mesmo quando não há dados disponíveis:

while true; do read -t 1 line; echo $line > out.pipe; done

Estou testando o que entra no meu canal com a seguinte linha:

while true; do cat out.pipe; done

Eu testei o envio de entrada por meio de stdin, além de enviar dados HTTP com echo -e "GET / HTTP/1.1\r\nHost: hostname\r\n\r\n" | nc localhost 80 | myreadcommand , o que foi muito confuso devido a caracteres solitários \r .

O que estou deixando de entender? Existe uma maneira muito melhor de fazer isso que estou perdendo?

    
por Nacht 06.06.2016 / 07:23

1 resposta

2

A página de manual do

read também diz:

The terminating <newline> (if any) shall be removed from the input and the results shall be split into fields as in the shell for the results of parameter expansion

Ele também documenta muitas exceções com base nos parâmetros que você passa para ele sobre como lidar com novas linhas. Ler toda a man page é necessário se tais exceções forem importantes para você.

Se você quiser ignorar certos caracteres, como \r , isso pode ser feito facilmente com sed :

echo "hi\r\nI am a script" | sed "s/\r//g"

Para tornar a substituição mais óbvia, você pode substituí-la por algo como:

echo "hi\r\nI am a script" | sed "s/\r/,/g"

Também é importante observar que usar o parâmetro -e para echo faz com que ele interprete as combinações de caracteres especiais invertidas que na verdade não correspondem a um caractere de alimentação de linha real presente na entrada.

    
por 06.06.2016 / 07:47

Tags