Testando um script que está aguardando stdin

6

Existe uma maneira de determinar se um script está aguardando stdin e fazer o comando sair se detectado?

Aqui está um exemplo, o comando que estou executando demora muito para ser executado, mas também solicitará entrada antes de iniciar sem um prompt. Eu quero saber que o comando está realmente fazendo alguma coisa e não apenas esperando.

Forneceu o seguinte script chamado ./demo

#!/bin/bash

read

Existe uma maneira de detectar que a leitura está aguardando stdin? Algo como

failifwaitingonstdin | ./demo

O qual retornaria imediatamente assim que o comando de leitura fosse detectado.

Atualizado:

As pessoas sugeriram programas como esperar e sim. Depois de analisar sim, vejo como eles podem suportar esse estilo de interação. Eles estão constantemente usando fputs para escrever 'y' para stdout. Em vez de fazer isso infinitamente, posso simplesmente retornar um erro assim que o fputs retorna em uma gravação para o stdout.

    
por Noah Campbell 01.07.2010 / 00:04

4 respostas

12

Isso realmente ajudaria se você fosse muito mais específico sobre seu script e / ou comando. Mas caso você queira testar de onde o stdin está vindo, este script de exemplo demonstrará isso para você:

#!/bin/bash
if [[ -p /dev/stdin ]]
then
    echo "stdin is coming from a pipe"
fi
if [[ -t 0 ]]
then
    echo "stdin is coming from the terminal"
fi
if [[ ! -t 0 && ! -p /dev/stdin ]]
then
    echo "stdin is redirected"
fi
read
echo "$REPLY"

Exemplo é executado:

$ echo "hi" | ./demo
stdin is coming from a pipe
$ ./demo
[press ctrl-d]
stdin is coming from the terminal
$ ./demo < inputfile
stdin is redirected
$ ./demo <<< hello
stdin is redirected
$ ./demo <<EOF
goodbye
EOF
stdin is redirected
    
por 01.07.2010 / 02:46
2

Se você estiver no Linux, você pode usar strace para ver se o processo está tentando ler de stdin. Outras plataformas têm programas semelhantes (por exemplo, dtrace , ktrace ou truss ).

Você pode evitar completamente o problema alimentando a saída de yes com o comando em questão.

    
por 01.07.2010 / 02:10
2

Se você estiver escrevendo os scripts: read builtin de bash usa uma opção de tempo limite:

read -p prompt -t 5 var # 5s timeout

Se não, você pode usar expect ou apenas yes para falsificar a interação do usuário.

    
por 01.07.2010 / 09:44
1

Sem saber o que você está tentando fazer, eu diria que você deveria estar escrevendo o roteiro para que você sempre saiba se ele vai pedir stdin ou não. Ou isso ou algo no comando que é provável que esteja querendo algo de stdin, mas isso provavelmente não é a melhor idéia.

    
por 01.07.2010 / 00:10