printenv sai com o código de erro 1 para nome de env inexistente

0

Estou no LinuxMint (experimentei o CentOS também) e tenho tentado usar o comando printenv para uma variável de ambiente que pode ou não existir. Então, quero que ele imprima o valor desse nome, se estiver presente, senão imprima nada, mas retorne com um código de saída 0.

No entanto, se eu invocá-lo com um nome de ambiente inexistente, ele sai com o código de erro 1. As man pages ou a ajuda de printenv não dizem nada sobre esse comportamento.

Veja como tentei:

> /usr/bin/printenv foo

Isso só retorna, então eu faço:

> echo $?

que retorna:

1

A versão do printenv é:

printenv (GNU coreutils) 8.25
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by David MacKenzie and Richard Mlynarik.

Alguém tem uma maneira alternativa de alcançar o que eu estou procurando? Em última análise, eu só preciso definir uma variável bash para conter o valor de uma variável de ambiente, se essa variável de ambiente existir, senão ter essa variável bash vazia:

mybashv='printenv foo'
    
por Watson 01.12.2016 / 14:50

2 respostas

1

A documentação info para printenv diz o seguinte sobre a saída códigos:

 0 if all variables specified were found
 1 if at least one specified variable was not found
 2 if a write error occurred

Isso parece consistente com o que você observou.

Se bem entendi, você quer esconder este código de status. Para qualquer comando, isso pode ser alcançado adicionando || true , por exemplo:

$ var='printenv foo || true'
$ echo $?
0
    
por 01.12.2016 / 14:57
1

Retornar um status de saída diferente de zero (falha) ao falhar na impressão do conteúdo de uma variável de ambiente parece a coisa certa a se fazer comigo. Isso corresponde ao comportamento do tcsh construído com o mesmo nome e de implementações históricas em BSDs.

Se isso não for feito, será difícil diferenciar entre uma variável definida como um valor vazio e outra que não esteja definida.

Se você quiser evitar o efeito de set -e / set -o errexit , use:

var=$(printenv VAR) || : Do not care if it fails

Ou:

if var=$(printenv VAR); then
  if [ -z "$var" ]; then
    echo "VAR is set but empty or consists only of newline characters"
  else
    echo "VAR is set and non-empty"
  fi
else
  echo "VAR is not in the environment"
fi

Observe também que todos os shells inicializam variáveis do shell a partir das variáveis de ambiente correspondentes (para aqueles que podem ser mapeados para variáveis do shell, e alguns shells excluem outros), assim você pode usar $VAR em seu script para se referir a eles value (note, porém, que nas shells Bourne, csh ou tcsh (as únicas shells em que alguém ainda pode querer usar esses '...' do seu), o valor do shell e env var pode divergir se você modificar a variável do shell sem exportar (ou atribuindo-o com setenv para (t) csh)).

    
por 01.12.2016 / 15:09