Какой краткий способ проверить, что переменные окружения установлены в сценарии оболочки Unix?

Сначала вы не можете определить пакеты в REPL. Причина этого в том, что ваши REPL-операторы фактически завернуты в object s. Вот почему ваша команда: load не работает. Вам нужно будет скомпилировать исходные файлы и добавить их в путь к классам, если вы хотите использовать пакеты.

При попытке разрешить импортируемый символ компилятор пытается найти его в вашей реальной области, то есть, когда вы пишете

import a._
import b._

, это будет импортировать все из package a и все от package a.b. Если вы находитесь внутри package a, то b уже находится в вашей области видимости, и второй импорт является достаточным. Компилятор также первоначально импортирует scala._, поэтому вы также можете использовать относительный импорт, например import xml._, чтобы импортировать scala.xml._.

Кроме того, есть функция, называемая вложенными пакетами, которая позволяет вам записать ваш B.scala

package a
package b
class B { /* .... */ }

, в результате чего все из package a импортируется в этот файл.

Если компилятор не может разрешить импорт относительного символа, он будет выглядеть в пакете по умолчанию ( _root_).

477
задан codeforester 16 May 2017 в 05:19
поделиться

7 ответов

Расширение параметра

очевидный ответ должно использовать одну из специальных форм расширения параметра:

: ${STATE?"Need to set STATE"}
: ${DEST:?"Need to set DEST non-empty"}

Или, лучше (см. раздел по 'Положению двойных кавычек' ниже):

: "${STATE?Need to set STATE}"
: "${DEST:?Need to set DEST non-empty}"

первый вариант (использующий всего ?) требует, чтобы СОСТОЯНИЕ было установлено, но СОСТОЯНИЕ = "" (пустая строка) в порядке — не точно, что Вы хотите, но альтернативная и более старая нотация.

второй вариант (использование :?) требует, чтобы DEST был установлен, и непустой.

, Если Вы не предоставляете сообщения, оболочка предоставляет сообщение по умолчанию.

Эти ${var?} конструкция является портативной спиной к UNIX Версии 7 и Оболочке Bourne (1978 или поблизости). Эти ${var:?} конструкция немного более свежа: Я думаю, что это были в Системе III UNIX приблизительно 1981, но это, возможно, было в UNIX PWB перед этим. Это находится поэтому в Shell Korn, и в оболочках POSIX, включая конкретно Bash.

Это обычно документируется в страницу справочника оболочки в разделе, названном Расширение Параметра . Например, bash в руководстве говорится:

${parameter:?word}

Ошибка Дисплея, если Пустой указатель или Сброс. Если параметр является пустым или сброс, расширение слова (или сообщение к тому эффекту, если слово не присутствует) записано в стандартную погрешность и оболочку, если это не является интерактивным, выходы. Иначе значением параметра заменяют.

Команда

Двоеточия я должен, вероятно, добавить, что команде двоеточия просто оценили ее аргументы и затем успешно выполняется. Это - исходная нотация комментария оболочки (перед' #' к концу строки). В течение долгого времени сценарии Оболочки Bourne имели двоеточие как первый символ. Оболочка C прочитала бы сценарий и использовала бы первый символ, чтобы определить, было ли это для Оболочки C (' #' хеш) или Оболочка Bourne (' :' двоеточие). Тогда ядро присоединилось и добавило поддержку' #!/path/to/program', и Оболочка Bourne добралась' #' комментарии, и соглашение двоеточия прошло мимо обочины. Но если Вы столкнетесь со сценарием, который запускается с двоеточия, теперь Вы будете знать почему.

<час>

Положение двойных кавычек

blong, который спрашивают в комментарий :

Какие-либо мысли об этом обсуждении? https://github.com/koalaman/shellcheck/issues/380#issuecomment-145872749

суть обсуждения:

†¦ В Однако, когда я shellcheck это (с версией 0.4.1), я получаю это сообщение:

In script.sh line 13:
: ${FOO:?"The environment variable 'FOO' must be set and non-empty"}
  ^-- SC2086: Double quote to prevent globbing and word splitting.

совет относительно того, что я должен сделать в этом случае?

короткий ответ, "делают, как shellcheck предполагает":

: "${STATE?Need to set STATE}"
: "${DEST:?Need to set DEST non-empty}"

Для иллюстрирования, почему изучите следующее. Обратите внимание, что эти : команда не повторяет свои аргументы (но оболочка действительно оценивает аргументы). Мы хотим видеть аргументы, таким образом, код ниже использования printf "%s\n" вместо [1 120].

$ mkdir junk
$ cd junk
$ > abc
$ > def
$ > ghi
$ 
$ x="*"
$ printf "%s\n" ${x:?You must set x}    # Careless; not recommended
abc
def
ghi
$ unset x
$ printf "%s\n" ${x:?You must set x}    # Careless; not recommended
bash: x: You must set x
$ printf "%s\n" "${x:?You must set x}"  # Careful: should be used
bash: x: You must set x
$ x="*"
$ printf "%s\n" "${x:?You must set x}"  # Careful: should be used
*
$ printf "%s\n" ${x:?"You must set x"}  # Not quite careful enough
abc
def
ghi
$ x=
$ printf "%s\n" ${x:?"You must set x"}  # Not quite careful enough
bash: x: You must set x
$ unset x
$ printf "%s\n" ${x:?"You must set x"}  # Not quite careful enough
bash: x: You must set x
$ 

Примечание, как значение в [1 121] расширено до первого * и затем список имен файлов, когда полное выражение не находится в двойных кавычках. Это - то, что shellcheck рекомендует, должен быть зафиксирован. Я не проверил, что это не возражает против формы, где выражение включается в двойные кавычки, но это - разумное предположение, что это было бы в порядке.

562
ответ дан Community 16 May 2017 в 05:19
поделиться

Я всегда использовал:

if [ "x$STATE" == "x" ]; then echo "Need to set State"; exit 1; fi

Не то, чтобы намного более краткий, я боюсь.

Под CSH у Вас есть $? СОСТОЯНИЕ.

14
ответ дан Mr.Ree 16 May 2017 в 05:19
поделиться
${MyVariable:=SomeDefault}

, Если MyVariable установлен и не пустой, это сбросит значение переменной (=, ничего не происходит).
Еще, MyVariable установлен на SomeDefault.

Вышеупомянутое попытается выполниться ${MyVariable}, поэтому если Вы просто захотите установить переменную, сделайте:

MyVariable=${MyVariable:=SomeDefault}
37
ответ дан bbarker 16 May 2017 в 05:19
поделиться

Ваш вопрос зависит от оболочки, которую Вы используете.

Оболочка Bourne уезжает очень мало в способе того, что Вы после.

, НО...

Это действительно работает, примерно везде.

Просто пытаются избегать csh. Это было хорошо для дополнительных свойств, которые это добавило, сравнил Оболочку Bourne, но это действительно скрипит теперь. Если Вы не верите мне, просто пытаетесь выделить STDERR в csh! (-:

здесь существует две возможности. Пример выше, а именно, с помощью:

${MyVariable:=SomeDefault}

впервые необходимо обратиться к $MyVariable. Это берет огибающий var MyVariable и, если он в настоящее время не устанавливается, присваивает значение SomeDefault к переменной для более позднего использования.

у Вас также есть возможность:

${MyVariable:-SomeDefault}

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

55
ответ дан Karusmeister 16 May 2017 в 05:19
поделиться

Попробуйте это:

[ -z "$STATE" ] && echo "Need to set STATE" && exit 1;
126
ответ дан David Schlosnagle 16 May 2017 в 05:19
поделиться

Это может быть слишком:

if (set -u; : $HOME) 2> /dev/null
...
...

http://unstableme.blogspot.com/2007/02/checks-whether-envvar-is-set-or-not.html

2
ответ дан Jonathan Leffler 16 May 2017 в 15:19
поделиться
  • 1
    Ну, C++ имеет изменяемое ключевое слово stackoverflow.com/questions/105014/c-mutable-keyword . Я соглашаюсь, хотя это, это станет сложным, если константа была добавлена, но я лично не должен был использовать изменяемое. Таким образом, сложность должна быть редкой. –  12 May 2010 в 10:00

Синтаксис $? довольно аккуратный:

if [ $?BLAH == 1 ]; then 
    echo "Exists"; 
else 
    echo "Does not exist"; 
fi
-7
ответ дан 22 November 2019 в 22:45
поделиться