Условно для неинстанцированной переменной - PullRequest
0 голосов
/ 28 мая 2019

Я новичок в скриптах Bash, у меня гораздо больше опыта работы с языками C-типа.Я написал несколько сценариев с условным условием, которое проверяет значение неинстанцированной переменной и, если она не существует или соответствует значению, устанавливает переменную.Кроме того, все это в цикле for.Примерно так:

for i in ${!my_array[@]}; do 
   if [ "${my_array[i]}" = true ] 
   then
      #do something
   else
      my_array[i]=true;
   fi
done

Это может произойти из-за нулевого указателя в Java, так как my_array [i] не создается до тех пор, пока он не будет проверен.Это хорошая практика в Bash?Мой сценарий работает так, как я задумал, но я понял, что тот факт, что kluge работает сейчас, не означает, что он будет работать в будущем.

Спасибо!

Ответы [ 2 ]

1 голос
/ 28 мая 2019

Вы найдете эту страницу о расширении параметров полезной, а также эту об условных.

Простой способ проверить переменную - это проверить еедля ненулевой длины.

if [[ -n "$var" ]]
then : do stuff ...

Я также хотел бы сделать фатальным доступ к несуществующей переменной;это означает дополнительную работу, но лучшую безопасность.

set -u # unset vars are fatal to access without exception handling
if [[ -n "${var:-}" ]] # handles unset during check
then : do stuff ...
0 голосов
/ 28 мая 2019

По умолчанию ссылка на неопределенные (или «неустановленные») имена переменных в сценариях оболочки просто дает пустую строку. Но есть исключение: если оболочка запускается с опцией -u или set -u, в ней выполняются расширения неустановленных переменных, которые рассматриваются как ошибки и (если оболочка не является интерактивной) приводит к ее завершению. Bash также применяет этот принцип к элементам массива:

$ array=(zero one two)
$ echo "${array[3]}"

$ echo "array[3] = '${array[3]}'"
array[3] = ''
$ set -u
$ echo "array[3] = '${array[3]}'"
-bash: array[3]: unbound variable

Существуют также модификаторы, которые можно использовать для управления действиями расширений, если переменная (или элемент массива) не определена и / или пуста (определяется как пустая строка):

$ array=(zero one '')
$ echo "array[2] is ${array[2]-unset}, array[3] is ${array[3]-unset}"
array[2] is , array[3] is unset
$ echo "array[2] is ${array[2]:-unset or empty}, array[3] is ${array[3]:-unset or empty}"
array[2] is unset or empty, array[3] is unset or empty

Существует множество других вариантов, см. стандарт синтаксиса оболочки POSIX , раздел 2.6.2 (расширение параметров).

Кстати, вам нужно использовать фигурные скобки (как я делал выше) вокруг всего, кроме простой ссылки на переменную. $name[2] - это ссылка на обычную переменную name (или элемент 0, если это массив), за которой следует строка "[2]"; ${name[2]}, с другой стороны, является ссылкой на элемент 2 массива name. Кроме того, вы почти всегда хотите заключать ссылки на переменные в двойные кавычки (или включать их в строки в двойных кавычках), чтобы предотвратить «полезное» разбиение оболочки на слова и / или развертывание их в списки соответствующих файлов. Например, этот тест:

if [ $my_array[i] = true ]

(в основном) эквивалентно:

if [ ${my_array[0]}[i] = true ]

... это совсем не то, что вы хотите. Но вот этот:

if [ ${my_array[i]} = true ]

по-прежнему не работает, потому что если my_array[i] не установлено (или пусто), оно расширится до эквивалента:

if [ = true ]

... неверный синтаксис тестового выражения. Вы хотите это:

if [ "${my_array[i]}" = true ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...