Redirecionando a saída para std output ou / dev / null dependendo do parâmetro opcional

1

Eu tenho um script onde você pode executá-lo assim ./myscript e a saída de alguns comandos chamados dentro do script estão escondidos, assim:

if mvn tomcat:deploy &> /dev/null; then

Mas se o script é executado assim ./myscript -v você pode ver a saída dos comandos, então seria apenas:

if mvn tomcat:deploy; then

Primeiro, qual é o valor da saída padrão para que eu possa armazenar esse valor ou /dev/null em uma variável para fazer a chamada assim:

if mvn tomcat:deploy &> $output; then

E qual é a melhor maneira de verificar os argumentos? Preciso literalmente checar se é igual a literal -v ou se há uma abordagem melhor (já que as opções são tão usadas, acho que existem diferentes mecanismos)?

    
por dabadaba 01.06.2014 / 17:59

2 respostas

0

Você pode nomear a saída padrão em um shell de script usando qualquer um dos seguintes:

  • 1
  • /dev/stdout
  • /proc/self/fd/1

Todos são apenas maneiras de dizer "descritor de arquivo # 1", que é o coletor de dados pré-aberto convencional para saída.

(Na verdade, a sintaxe de redirecionamento > apenas altera o fd pré-aberto para que, quando o subcomando tentar gravar no fd 1, ele realmente vá para outro arquivo ou dispositivo. >& faz o mesmo com ambos descritores 1 = stdout e 2 = stderr.)

Se você tiver apenas uma bandeira, não há nada errado em apenas verificar . Existem várias maneiras de fazer o processamento das opções de linha de comando, mas uma ferramenta poderosa é getopt . Para se familiarizar com isso, comece examinando /usr/share/doc/util-linux/examples/getopt-parse.bash .

    
por aschepler 01.06.2014 / 18:28
1

Eu definitivamente sugiro usar o getopts do bash para processar qualquer opção de linha de comando - há um tutorial de Small getopts no wiki. bash-hackers.org que eu achei muito útil.

Para o redirecionamento de saída, em vez de armazenar o (s) descritor (es) de arquivo, você pode redirecionar condicionalmente o (s) fluxo (s) antes do corpo do script ou (possivelmente de forma mais limpa), apenas fechar o (s) fluxo (s) usando exec n>&- onde n é o descritor de arquivo numérico do fluxo (1 = stdout, 2 = stderr).

IMHO, seria mais natural manter a saída quando o comando é executado sem argumentos, e ter uma opção -q (silenciosa) para despejar a saída para / dev / null - por exemplo

#!/bin/bash

while getopts ":q" opt; do
  case $opt in
    q) 
      quiet=1
      ;;
    \?)
      echo "Invalid option: -$OPTARG" >&2
      ;;
  esac
done

if [ "${quiet:-0}" -ne 0 ]; then
   exec 1>&- 2>&-
fi

#
# remainder of your script here
#

Se você está convencido de que quer fazer o oposto (ou seja, enviar stdout e stderr para / dev / null por padrão), então você pode inverter a lógica.

    
por steeldriver 01.06.2014 / 19:01