Здравствуйте всем.
Поймал себя на том, что часто не использую двойные кавычки с переменными в shell скрипах. Это объяснимо - использую zsh, где кавычки "расставляются автоматически". Объяснение есть, оправдания нет.
Простое решение - всегда использовать кавычки неправильно, поскольку во многих случаях они не нужны никогда (и иногда выглядят глупо), а в других просто нельзя их использовать.
Речь идет о POSIX shell (a не о "классической" sh, и не о bash, ksh, zsh) поскольку, по моему мнению, именно на ней и стоит писать "неодноразовые" скрипты. В любом случае sh в Debian-производных дистрибутивах (dash) - это POSIX shell.
Набросал для себя правила - то что знаю, но shell имеет достаточное количество темных уголков, так что наверняка что-то упустил, а что-то неправильно сформулировал. Поэтому, если есть замечания - пожалуйста.
---
1. Кавычки нужно использовать всегда, когда переменная является аргументом (или частью аргумента) команды. Выборочное использование приводит к ошибкам.
2. Кавычки ненужно использовать в некоторых синтаксических конструкциях:
- при присваивании:
a='q w'
b=$a
echo "$b"
- в арифметической конструкции $(())
- в шаблонах case
a=' w '
case 'q w e' in
q${a}e) echo matched ;;
*) echo no ;;
esac
3. Кавычки нельзя использовать, когда переменная имитирует массив:
a='1 2 3'
for i in $a; do
echo "$i"
done
a='q w e'
echo $a | read a1 a2 a3 && echo "$a2"
a=`head -1 /etc/passwd`
old_ifs=$IFS
IFS=:
set $a
IFS=$old_ifs
echo "$7"
4. Специальные переменные. Вокруг позициональных ($1, $2 ...) и $@ кавычки нужно ставить всегда, вокруг $* в зависимости от конкретной ситуации (фактически можно считать, что $* и "$*" - это разные переменные), вокруг остальных ненужно.
===
PS1. Кавычки не нужно использовать, когда переменная содержит в себе имя команды.
Кавычки нельзя использовать, когда в переменной хранится набор аргументов, включая, возможно, и саму команду. Впрочем это подпадает под имитацию массива.