Рубрики
Uncategorized

Вот почему вы должны процитировать свои переменные в Bash

Технически вам не нужно размещать цитаты вокруг ваших переменных, но если вы игнорируете это, вы можете столкнуться с неожиданными результатами. Tagged с Bash, новичками, DevOps, Linux.

Эта статья была первоначально размещена 2 октября 2018 года по адресу: https://nickjanetakis.com/blog/here-is-why-you-should-quote-your-variables-in-bash

Работая над завершением следующего курса, я заканчивал Ansible Роль для выпуска сертификатов SSL с использованием acme.sh Анкет

Роль поддерживает выдачу сертификатов с одним доменом, многодоменом и подстановочными знаками с использованием API V2 Encrypt. Все это обрабатывается acme.sh , но я сделал судебный звонок, чтобы создать имя файла сертификата на диске, чтобы соответствовать первому сертификату, переданному в Acme.sh.

С точки зрения, это похоже на это:

acme_sh_domain:
  - domains: ["*.example.com", "example.com"]

Когда все заканчивается, вы получите *.Example.com.Key и *.Example.com.pem Сертификаты для использования с NGINX или чем -то еще читают ваши СЕРТ.

Обычно я не сталкиваюсь с файлами, которые начинаются с * , так что это приведет к веселью . Я неустанно цитирую переменные, поэтому у меня не было слишком много проблем, но когда я играю на терминале, испытывая роль, которую я забыл процитировать MV командование один раз И вот мы.

Демонстрируя проблему

Если у вас есть Unix-подобная среда, чтобы проверить это на (macos, linux или wsl должны работать), не стесняйтесь следить за этим:

Заказ того, как вы создаете каталоги, имеет значение:
mkdir -p /tmp/demoproblem
cd /tmp/demoproblem

mkdir test.example.com
mkdir *.example.com
# mkdir: cannot create directory 'test.example.com': File exists

rm -rf *

mkdir *.example.com
mkdir test.example.com

ls -la
# drwxr-xr-x 1 nick nick 4096 Sep 29 15:15 *.example.com
# drwxr-xr-x 1 nick nick 4096 Sep 29 15:15 test.example.com

На WSL ls Командные издают окружающие отдельные кавычки вокруг *.Example.com . На истинной системе Unix вы бы в конечном итоге увидели '*.Example.com' Но это только разница в презентации с ls Анкет

Случайно удаление неожиданных каталогов:
rm -rf *.example.com

ls -la
# drwxr-xr-x 1 nick nick 4096 Sep 29 15:19 .
# drwxrwxrwt 1 root root 4096 Sep 29 14:59 ..

Если вы только хотели удалить *.Example.com (Одна папка) Тогда вы находитесь в мире обиды, потому что она удаляла каждый каталог, который соответствовал шаблону.

Защита от удаления всего, что соответствует звездочке:
mkdir *.example.com test.example.com

rm -rf "*.example.com"

ls -la
drwxr-xr-x 1 nick nick 4096 Sep 29 15:20 .
drwxrwxrwt 1 root root 4096 Sep 29 14:59 ..
drwxr-xr-x 1 nick nick 4096 Sep 29 15:20 test.example.com

Там мы идем, с цитатами все работает как задумано. Вы могли бы также избежать звездочки с rm -rf \*. example.com вместо.

Двойная проверка, чтобы убедиться, что он работает с Mkdir:
mkdir "*.example.com"

ls -la
drwxr-xr-x 1 nick nick 4096 Sep 29 15:23 *.example.com
drwxr-xr-x 1 nick nick 4096 Sep 29 15:23 test.example.com

Как мы видим, цитирование также позволяет нам создавать *.Example.com даже если test.example.com существуют.

Так почему вы должны цитировать свои переменные?

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

Это могло бы повлиять на несколько проектов, и это могло бы легко подкрасться к производству незамеченным, если бы вы никогда не выпустили сертификат подстановочного знака, потому что 20 раз вы выпустили сертификат, он работал нормально, поэтому вы думали, что находились в ясном виде.

Вот пример сценария, не работающего в соответствии с пропущенными цитатами:
DOMAIN_DIR=*.example.com
[ -d $DOMAIN_DIR ] && echo "Directory found" || echo "Directory not found"
# bash: [: *.example.com: binary operator expected
# Directory not found

Теперь как это для безумия. На этом этапе у нас есть *.Example.com и test.example.com В нашем каталоге, но теперь беги mkdir aaa.example.com к Создайте третий каталог.

DOMAIN_DIR=*.example.com
[ -d $DOMAIN_DIR ] && echo "Directory found" || echo "Directory not found"
# bash: [: too many arguments
# Directory not found

Теперь мы получаем другую ошибку.

А вот и та же настройка, но цитируя Domain_DIR во время назначения:
DOMAIN_DIR="*.example.com"
[ -d $DOMAIN_DIR ] && echo "Directory found" || echo "Directory not found"
# bash: [: too many arguments
# Directory not found

Это все еще не помогает нам.

Вот тот же сценарий, но цитируя только переменную:
DOMAIN_DIR=*.example.com
[ -d "$DOMAIN_DIR" ] && echo "Directory found" || echo "Directory not found"
# Directory found

Это сработало, но мы все равно должны процитировать задание, чтобы быть в безопасности.

Пока мы находимся в этом, давайте процитируем как назначение, так и переменную и используем долларовые крики:
DOMAIN_DIR="*.example.com"
[ -d "${DOMAIN_DIR}" ] && echo "Directory found" || echo "Directory not found"
# Directory found

В случае сомнений, процитируйте свои задания и используйте цитаты + долларовые курки вместе при ссылке на переменные. Да, это более многословно, но еще несколько персонажей намного лучше, чем пробуждение к работе Cron, которая удаляла каждый сертификат на вашем сервере в середине ночи, или вызвало некоторые другие странные побочные эффекты в вашем сценарии.

Только не просто используйте долларовые кудри (даже с цитированным заданием):
DOMAIN_DIR="*.example.com"
[ -d ${DOMAIN_DIR} ] && echo "Directory found" || echo "Directory not found"
# bash: [: too many arguments
# Directory not found

Этого не достаточно.

Использование инструментов, которые помогут нам вспомнить наши цитаты

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

Я настоятельно рекомендую вам установить Shellcheck Анкет Это отличный инструмент для сценария сценария оболочки, который поймает и предупредит вас о куче потенциальных проблем (включая отсутствующие цитаты). Есть даже Расширение VSCODE Для этого тоже.

Вы когда -нибудь были поражены ошибками, связанными с пропущенными цитатами Bash? Дайте мне знать ниже!

Оригинал: «https://dev.to/nickjj/heres-why-you-should-quote-your-variables-in-bash-53o0»