Я использую 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`
В информационной документации для 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
Возврат ненулевого статуса выхода (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)).