#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
и[
часто предоставляется встроенными, но использование функциональности, которая исчезает всякий раз, когда команда используется в не встроенном контексте, является хрупким, и нет причин делать это вместо использования явно расширенной конструкции только для синтаксиса оболочки[[
.