Eu faria um uso mais pesado de redirecionamento de E / S :
#!/bin/bash
[[ $1 ]] && [[ ! -f $1 ]] && echo "file $1 dne" && exit 1
[[ $1 ]] && exec 3<$1 || exec 3<&0
[[ $2 ]] && exec 4>$2 || exec 4>&1
fgrep -v "stuff" <&3 >&4
Explicação
-
[[ $1 ]] && [[ ! -f $1 ]] && echo "file $1 dne" && exit 1Teste se um arquivo de entrada foi especificado como um argumento de linha de comando e se o arquivo existe.
-
[[ $1 ]] && exec 3<$1 || exec 3<&0Se
$1estiver definido, ou seja, um arquivo de entrada tiver sido especificado, o arquivo especificado será aberto no descritor de arquivo3, caso contrário,stdinserá duplicado no descritor de arquivo3. -
[[ $2 ]] && exec 4>$2 || exec 4>&1Da mesma forma, se o
$2estiver definido, ou seja, um arquivo de saída tiver sido especificado, o arquivo especificado será aberto no descritor de arquivo4, caso contrário,stdoutserá duplicado no descritor de arquivo4. -
fgrep -v "stuff" <&3 >&4Por fim,
fgrepé invocado, redirecionando seusstdinestdoutpara os descritores de arquivos previamente definidos3e4, respectivamente.
Reabertura de entrada e saída padrão
Se você preferir não abrir descritores de arquivos intermediários, uma alternativa é substituir os descritores de arquivo correspondentes a stdin e stdout diretamente aos arquivos de entrada e saída especificados:
#!/bin/bash
[[ $1 ]] && [[ ! -f $1 ]] && echo "file $1 dne" && exit 1
[[ $1 ]] && exec 0<$1
[[ $2 ]] && exec 1>$2
fgrep -v "stuff"
Uma desvantagem dessa abordagem é que você perde a capacidade de diferenciar a saída do próprio script da saída do comando que é o destino do redirecionamento. Na abordagem original, você pode direcionar a saída do script para os stdin e stdout não modificados, que, por sua vez, podem ter sido redirecionados pelo responsável pela chamada do script. Os arquivos de entrada e saída especificados ainda podem ser acessados por meio dos descritores de arquivos correspondentes, que são distintos do script stdin e stdout .