O stdin ou os nomes de arquivos devem ser descartados se ambos forem fornecidos?

3

grep e sed ignoram stdin se você fornecer um parâmetro de nome de arquivo:

$ echo foo > test.txt
$ echo foobar | grep f test.txt 
foo
$ echo foobar | sed -e 's/foo/bar/' test.txt 
bar

Esta é a melhor prática estabelecida? Se sim, por quê?

    
por l0b0 29.12.2012 / 11:01

2 respostas

1

Um programa sabe se os arquivos são especificados em sua linha de comando. Ele não pode saber se existe alguma entrada disponível no stdin (além de tentar lê-lo) e, se houver entrada, não há como o programa saber se essa entrada foi planejada para ele. Portanto, a única opção sensata é ter uma regra clara, baseada em como o programa foi invocado (argumentos de linha de comando, variáveis de ambiente, arquivos de configuração,…), para decidir se ele lerá de stdin ou não.

Por exemplo, os utilitários de texto comuns ( cat , sort , grep , awk , perl -p ,…) lêem de stdin se nenhum arquivo é fornecido e lêem a partir do (s) arquivo (s) especificado (s) se houver algum. Os intérpretes obedecem a uma convenção semelhante, por exemplo, sh sem comandos de leitura de argumentos da entrada padrão, enquanto sh script_file_name lê os comandos do arquivo especificado (e deixa o stdin para ser lido pelo script, se quiser). Há também uma convenção comum que se - aparecer em uma posição onde o nome de um arquivo de entrada é esperado, o programa lerá de stdin.

Considere um snippet de shell como

somecommand | while read line; do
  process "$line"
done

Você precisa saber se process lê stdin ou não. Não existe algo como “testar se stdin é fornecido”: está lá, mas o usuário que invoca o programa sabe se ele quer que o stdin seja lido ou não.

    
por 30.12.2012 / 02:09
1

A resposta que encontrei é como ela é projetada. Se você quiser ler o stdin e o arquivo, use echo foobar | grep f - test.txt . de man grep

 grep  searches the named input FILEs (or standard input if no files are
 named, or if a single hyphen-minus (-) is given as file name) for lines
 containing  a  match to the given PATTERN.  By default, grep prints the
 matching lines.
    
por 29.12.2012 / 12:14