как проверить существование переменных и сравнить со строкой в ​​busybox?

Я хочу использовать что-то подобное

if [[ ! -z "$ENV" && $ENV == 'production' ]]; then echo "production"; else echo "dev"; fi 

но в BusyBox это не работает 🙁

 sh: 1: [[: not found 

Похоже, что любая комбинация AND или OR не работает в IF-заявлении в busybox

    2 Solutions collect form web for “как проверить существование переменных и сравнить со строкой в ​​busybox?”

    Вы можете использовать более старый синтаксис

     if [ -n "$ENV" -a "$ENV" = 'production' ] 

    (обратите внимание, что я использовал -n а не ! -z потому что он читается легче, но это то же самое).

    Или мы можем упростить еще более старый синтаксис, заставив строку иметь значение:

     if [ "x$ENV" = 'xproduction' ] 

    Наконец, тест -n может не понадобиться, и вы можете просто сделать

     if [ "$ENV" = 'production' ] 

    [[...]] – это конструкция оболочки Korn, также поддерживаемая bash и zsh но в остальном не стандартная sh (и не поддерживается какой-либо другой оболочкой).

    busybox sh основан на ash которая реализует подмножество спецификации POSIX sh (в локали POSIX, она по большей части совместима) с очень небольшим количеством расширений и, в частности, не с этим.

    В любом случае при написании сценария sh вы должны придерживаться спецификации POSIX sh . Скрипты, которые используют [[...]] должны явно ссылаться на ksh , bash или zsh . bash также в основном совместима с POSIX sh, но с гораздо большим количеством расширений (включая этот).

    Тестирование для x непустое, а затем равное production имеет мало смысла. Если x == production , то, очевидно, оно не пустое.

    Выполняйте строковые сравнения с оболочкой POSIX и утилитами, у вас есть несколько вариантов, наиболее очевидными в этом случае являются:

    • [ утилита aka test , обычно встроенная в оболочку:

       if [ "$var" = production ]; then echo PROD fi 
    • конструкция case :

       case $var in production) echo PROD;; "") echo EMPTY;; *) echo non-PROD;; esac 

    Теперь вы можете проверить, что переменная установлена (в отличие от непустого), до разыменования ее, в случае, когда nounset опция nounsetset -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 like ! , ( или -n . Он не нужен в современных системах, но что-то нужно учитывать для очень старых систем. В любом case конструкция case не имеет такой проблемы.

    Другие утилиты 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), они не являются операторами равенства, а являются проверкой того, имеют ли два операнда одинаковый порядок сортировки, что необязательно может быть одним и тем же. Например, в expr_equal ② ③ system expr_equal ② ③ возвращает true, потому что ни ②, ни ③ не имеют определенного порядка сортировки. Некоторые awk реализации, такие как gawk , mawk и busybox awk игнорируют это требование POSIX и вместо этого выполняют простое сравнение между байтами.

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

    Interesting Posts

    Трафик не маршрутизируется через Cisco VPN

    Приостановить процесс, не убивая его

    Может ли p7zip создавать меньшие zip-файлы, чем winzip?

    «Не удалось подключиться к отображению» в одной учетной записи пользователя

    Загрузите с помощью wget в другой каталог, чем текущий каталог

    Вызовите sudo от Jenkins

    Gnome3: как добавить дополнительные параметры поиска

    Не удается удалить файл на разделе NTFS, событие с правами root

    Вывод последней даты изменения в другой файл?

    Ошибка файловой системы только для чтения при доступе к файлам на Ubuntu

    настройте ToggleShowDesktop в Openbox, чтобы действовать только на указанном уровне

    Разница между Oracle VM и Citrix XEN?

    Отправка последовательных команд с помощью сеанса echo vs screen

    Забыл пароль пользователя root для постоянного подключения USB

    JACK / Pulseaudio: выход аудио из источника JACK в наушники (как маршрутизировать различный звук на разные звуковые карты)

    Linux и Unix - лучшая ОС в мире.