redireciona stdout e stderr em um script bash

3

Eu tenho o seguinte script (a numeração de linhas é para referência):

#!/bin/bash

1-  for version in 'ls -al ./atk/ | grep ^d | grep -Ev '\.$' | awk -F' ' '{print $8}''
2-      do
3-          grep $version ./atk/versions #&>/dev/null <--(first ran with this comment out)
4-          if [ $? -ne 0 ]
5-              then
6-                  printf '%-15s\n' "$version"
7-          fi
8-      done

se eu executar como está, a linha 1 enviará o seguinte para a tela: (Eu realmente não quero isso, gostaria stdout / stderr para ir para /dev/null , mas mais sobre isso mais tarde)

aaaaa--------
bbbbb       |
ccccc       |
ddddd       |------------ wil be stored in the version variable
eeeee       |
fffff       |
ggggg--------

a linha 2 procurará $version em um arquivo "versões" que contenha o seguinte:

12345
aaaaa
67890
ccccc
09876
fffff

se $version não for encontrado no arquivo "versões", em seguida, imprima $ versions no stdout.

A saída

deve ser a seguinte:

bbbbb
ddddd
eeeee
ggggg

como obtenho a linha 1 para enviar sua saída para /dev/null e enviar a linha 3? sua saída de volta para stdout e stderr?

Curiosamente, se eu descomentar o final da linha 3, tudo funciona bem, apesar de do redirecionamento de stdout e stderr para /dev/null !

Eu tentei o seguinte:

for version in 'ls -al ./atk/ | grep ^d &>/dev/null | grep -Ev '\.$' | awk -F' ' '{print $8}'' &>/dev/null

não apenas suprimiu a saída que eu não queria ver da linha 1, mas também a saída da linha 3 que eu queria ver mesmo depois de modificar o código como tal:

for version in 'ls -al ./atk/ | grep ^d | grep -Ev '\.$' | awk -F' ' '{print $8}'' &>/dev/null
    do
        exec &>/dev/tty  ++++++++++++++ trying to reset stdout and stderr back to the origal setting
        grep $version ./atk/versions #&>/dev/null

novamente, por que a linha 3 sem o comentário funciona quando estou pedindo explicitamente para enviar todas as saídas para /dev/null ?

    
por linuxbox099 22.02.2017 / 18:50

1 resposta

2

Na linha 1, o comando em backticks envia seu stdout para o loop for... . Ele não grava nada na tela a menos que haja um erro de um dos comandos (por exemplo, ls pode reclamar da falta do caminho do diretório).

O grep na linha 3 escreve para stdout . Talvez você queira o sinalizador -q para o modo silencioso.

Estou tentando entender o que você está realmente tentando fazer, porque acho que provavelmente ele pode ser tratado de maneira muito mais simples:

for item in atk/*
do
    test -d "$item" && echo "${item/*\/}" | grep -Fvf atk/versions
done

Como um aparte, o uso de backticks para interpolação de comando não é mais considerado um bom estilo de codificação. Você usaria melhor a construção $( ... ) . Como for version in $( ls ... awk )

    
por 22.02.2017 / 19:06