Como detectar se a entrada é de argumento, arquivo ou terminal

7

No bash, existe uma maneira de saber se um determinado script foi chamado:

$ myscript.sh myfile

ou:

$ myscript.sh < myfile

Dentro de alguns scripts, sempre acessei o conteúdo de myfile com $1 , mas agora gostaria de alterar o comportamento como casos diferentes.

EDIT: Eu também gostaria de um terceiro caso quando invocado sem qualquer redirecionamento:

$ myscript.sh
    
por mschonaker 27.06.2011 / 09:08

2 respostas

12

EDIT : alterou -t para -t 0 , que detecta corretamente a entrada do terminal ou arquivo.

Acho que a chave aqui é saber se sua entrada está vindo de um terminal ou de um arquivo. Há um teste para isso ( man test , consulte -t ).

Supondo que você esteja executando um script básico:

if [ -t 0 ]; then
    echo "Input from terminal"
    if [ $# -eq 0 ]; then
        echo "No input files specified on command line.  Error." >&2
    else
        echo "Input file given on command line.  It is $1"
    fi
else
    echo "Input coming from stdin"
fi

Você pode manipular os diferentes cenários substituindo o código real pelas declarações de eco acima.

Atualizar, script de teste rápido:

#!/bin/bash
[ -t 0 ] && echo "t is true" || echo "t is false"

Em exibição:

$ test.sh testfile
t is true
$ test.sh < testfile
t is false
$
    
por 27.06.2011 / 09:20
6

Em geral, as expressões $1 , $2 , etc. expandem para o primeiro, segundo argumento fornecido na linha de comando do script.

Então, quando você invoca um script como:

myscript.sh myfile

, em seguida, $1 no script é expandido para myfile (e $2 , $3 , etc todos são a string vazia).

Quando você invoca um script como:

myscript < myfile

o redirecionamento de STDIN de myfile é feito pelo shell pai, então o script é realmente chamado com argumentos no e $1 expande para a string vazia.

    
por 27.06.2011 / 09:12