[[...]]
- конструкция оболочки Korn, также поддерживаемая bash
и zsh
, но в остальном не стандартный sh
(и не поддерживается никакими другими оболочками).
busybox
sh
основан на ash
, который реализует подмножество спецификации POSIX sh
(в локали POSIX он по большей части совместим ) с очень небольшим количеством расширений, и, в частности, не с этим.
2019 редактировать . ограниченное подмножество ksh [[...]]
теперь также поддерживается в busybox ash при построении с помощью ASH_TEST
и ASH_BASH_COMPAT
и гораздо большего подмножества в яс
.
В любом случае при написании сценария sh
вы должны придерживаться спецификации POSIX sh
. Скрипты, использующие [[...]]
, должны явно вызывать ksh
, bash
или zsh
. bash
также в основном является оболочкой, совместимой с POSIX sh, но с гораздо большим количеством расширений (включая это).
Проверка того, что x непусто, а затем равняется production
, не имеет большого смысла. Если x == production
, то, очевидно, он не пустой.
Выполняйте сравнение строк с помощью оболочки и утилит POSIX, у вас есть несколько вариантов, наиболее очевидные в данном случае:
утилита [
, известная как test
, обычно встраивается в оболочку:
if ["$ var" = production]; затем
echo PROD
fi
case
конструкция:
case $ var in
production) echo PROD ;;
"") echo EMPTY ;;
*) echo non-PROD ;;
esac
Теперь вы можете проверить, что переменная установить (в отличие от непустого) перед разыменованием его, в случае, если была включена опция существительное
(с set -u
или set -o nounset
или с #! / Bin / sh -u
в качестве строки she-bang), иначе ["$ ENV" = production]
приведет к завершению работы оболочки, если $ ENV
не будет установлено. Для этого вы должны сделать:
if [ "${var+set}" = set ] && [ "$var" = production ]; then
echo PROD
fi
(вам следует избегать оператора -a
[
AND, поскольку он устарел и ненадежен).
Хотя лучший и более канонический способ сделать это:
if [ "${var-}" = production ]; then
echo PROD
fi
nounset
не запускается на $ {var + string}
или $ {var-string}
расширения. $ {var -}
расширяется до содержимого $ var
, если переменная установлена, или до пустой строки в противном случае.
Еще несколько примечаний:
$ ENV
- это специальная переменная для sh
. При запуске в интерактивном режиме он используется как путь к файлу для чтения инициализаций (эквивалент ~ / .bashrc
для bash
). Вы не должны использовать его для других целей.
Вы обнаружите, что в некоторых старых публикациях по сценариям оболочки Unix рекомендуется использовать ["x $ var" = xproduction]
или [production = "x $ var"]
для выполнения сравнение строк. Это было сделано для устранения ошибок в некоторых старых версиях утилиты [
и test
, которые сбивали с толку некоторыми значениями $ var
, например !
, (
или -n
. Это не нужно в современных системах, но кое-что нужно иметь в виду для очень старых систем. В любом случае, случай Конструкция
не имеет такой проблемы.
Другие утилиты POSIX, которые могут выполнять сравнение строк, включают expr
и awk
.
awk_equal() { awk 'BEGIN{exit(!(""ARGV[1] == ""ARGV[2]))}' "$1" "$2"; }
expr_equal() { expr "x $1" = "x $2" > /dev/null; }
if awk_equal "$var" production; then
echo PROD
fi
if expr_equal "$var" production; then
echo PROD
fi
Обратите внимание на необходимость добавления ""
к значениям с awk
, чтобы убедиться, что мы получим сравнение строк (в противном случае 1
будет считаться равным 01
или ] 1e0
) и x
в expr
по той же причине, но также для того, чтобы избежать проблем со значениями, являющимися операторами expr
.
С обоими awk
и expr
(по крайней мере, POSIXly), на самом деле они не являются операторами равенства , а являются проверкой того, имеют ли два операнда одинаковый порядок сортировки, что необязательно то же самое. для я Например, в системе May expr_equal ② ③
возвращает истину, потому что ни ②, ни ③ не имеют определенного порядка сортировки.Некоторые реализации awk
, такие как gawk
, mawk
и busybox awk
, игнорируют это требование POSIX и вместо этого выполняют простое побайтовое сравнение.
В любом случае,Я не могу придумать какой-либо веской причины, по которой вы бы предпочли их [
или случаю
здесь.
Заголовки, содержащие символы подчеркивания, считаются недействительными nginx
, поэтому по умолчанию они не будут передаваться. Поведение может быть переопределено директивой underscores_in_headers
. Например:
underscores_in_headers on;
Дополнительную информацию см. в этом документе .