printenv выходит с кодом ошибки 1 для несуществующего имени env

Я использую LinuxMint (тоже пробовал CentOS) и пытался использовать команду printenv для переменной среды, которая может существовать, а может и не существовать. Поэтому я хочу, чтобы он выводил значение этого имени, если оно присутствует, иначе ничего не печатает, кроме возврата с кодом выхода 0.

Однако, если я вызываю его с несуществующим именем среды, он выходит с кодом ошибки 1 Страницы руководства или справка по printenv ничего не говорят об этом поведении.

Вот как я это пробовал:

> /usr/bin/printenv foo

Это просто возвращается, затем я возвращаюсь:

> echo $?

что возвращает:

1

Версия 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.

Есть ли у кого-нибудь альтернативный способ достичь того, что я после? В конце концов, мне просто нужно установить переменную bash, которая будет содержать значение переменной среды, если эта переменная среды существует, иначе эта переменная bash пуста:

mybashv=`printenv foo`
0
01.12.2016, 16:10
2 ответа

В информационной документации для printenv говорится следующее о кодах выхода кодов:

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

Это соответствует тому, что вы наблюдали.

Если я правильно понял, вы хотите скрыть этот код состояния. Для любой команды это можно сделать, добавив || true, например:

$ var=`printenv foo || true`
$ echo $?
0
2
28.01.2020, 02:34

Возврат ненулевого статуса выхода (failure) при неудачной печати содержимого переменной окружения кажется мне правильным. Это соответствует поведению одноименной встроенной программы tcsh и историческим реализациям на BSD.

Если этого не сделать, то будет трудно отличить переменную, которая установлена в пустое значение, от переменной, которая не установлена.

Если вы хотите избежать эффекта set -e/set -o errexit, используйте:

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

Или:

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

Также обратите внимание, что все оболочки инициализируют переменные оболочки из соответствующих переменных окружения (для тех, которые могут быть отображены в переменные оболочки, а некоторые оболочки обрезают другие), поэтому вы можете использовать $VAR в вашем скрипте для ссылки на их значение (обратите внимание, однако, что в оболочках Bourne, csh или tcsh (единственные оболочки, в которых вы можете захотеть использовать эти `. ...` ваших), значения переменных shell и env var могут расходиться, если вы измените переменную shell без ее экспорта (или присвоите ее с помощью setenv для (t)csh)).

2
28.01.2020, 02:34

Теги

Похожие вопросы