Оболочка, если [[]] выдает синтаксическую ошибку при выполнении

#linux #shell

#linux #оболочка

Вопрос:

У меня есть сценарий оболочки, который используется if для проверки некоторых условий. Но по какой-то причине if оператор выдает мне синтаксическую ошибку.

 ./Sample.sh: line 82: conditional binary operator expected
./Sample.sh: line 82: syntax error near `${myId}'
./Sample.sh: line 82: `if [[ -v ${myId} ]]'
 

и мой сценарий оболочки выглядит так

 myId=${id}_CONTEXT
echo * ${myId}
if [[ -v ${myId} ]]
then
    
    echo * true
else
    echo * false
    envVarSuccess=false
fi
 

Что может быть причиной того же.?

Версия Linux Red Hat Enterprise Linux Server release 6.3 (Santiago) .

Версия оболочки

 GNU bash, version 4.1.2(1)-release (x86_64-unknown-linux-gnu)
Copyright (C) 2009 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.
 

Как я должен переписать свою оболочку?

Комментарии:

1. С какой оболочкой вы запускаете это (и с какой конкретной версией этой оболочки)? [[ является синтаксисом ksh и bash; sh не поддерживает его.

2. Кроме того, -v она еще менее переносима, чем [[ . Даже в bash я бы предложил [[ ${!myId} ]] вместо этого, если вы точно не знаете, что конкретная используемая версия поддерживает конструкцию.

3. @CharlesDuffy Тот же sh запускается на других серверах без ошибок. Обновлена версия оболочки.

4. sh не гарантирует, что он будет поддерживать все , чего нет в спецификации POSIX sh, и [[ не является частью этой спецификации. Поэтому при запуске sh somescript этот скрипт гарантированно будет работать только в том случае, если он использует только синтаксис POSIX, а не синтаксис bash, синтаксис ksh, синтаксис zsh и т.д. Это может сработать, если он использует другой синтаксис, в зависимости от того, какую оболочку предоставляет sh ваша система и какое подмножество функций она отключает в режиме совместимости, но никаких гарантий нет.

5.Обратите внимание, что bash --version это не говорит вам, что такое активная оболочка; это говорит вам, что такое первая копия bash в PATH , которая может быть чем-то другим. Если вы хотите знать, какая версия bash используется (если это на самом деле bash), запустите echo "$BASH_VERSION" внутри своего скрипта.

Ответ №1:

Возможно, ваша версия bash слишком старая. В терминале попробуйте

 help test
 

с моим

 bash -version
 

GNU bash, версия 5.1.0(1)-rc2 (x86_64-pc-linux-gnu)

Я получаю:

   ...

  Other operators:
    
      -o OPTION      True if the shell option OPTION is enabled.
      -v VAR         True if the shell variable VAR is set.
      -R VAR         True if the shell variable VAR is set and is a name
                     reference.

  ...
 

-> Вы видели «-v VAR» в вашем случае?

Согласно https://unix.stackexchange.com/a/212192/249463 эта функция доступна только для bash версии 4.2 и выше (ваша версия 4.1.1).

Также обратите внимание, что правильный синтаксис

  if [ -v myId ] ...
 

и не

  if [ -v ${myId} ] ...
 

Также, согласно приведенной ссылке, это

  if [ -n "${myId}" ] ...
 

возможно, это жизнеспособная альтернатива оболочкам, подобным Борну.

Надеюсь, что хотя бы одно из этих двух предложений сработает для вас.

Комментарии:

1. /bin/test (и его псевдоним /bin/[ ) никогда не поддерживается -v . Это невозможно, потому что только сама оболочка (а не внешние команды, которые вызывает оболочка) может видеть неэкспортированные переменные. Предоставляется test и [ часто предоставляется встроенными, но использование функциональности, которая исчезает всякий раз, когда команда используется в не встроенном контексте, является хрупким, и нет причин делать это вместо использования явно расширенной конструкции только для синтаксиса оболочки [[ .