Форум русскоязычного сообщества Ubuntu


Увидели сообщение с непонятной ссылкой, спам, непристойность или оскорбление?
Воспользуйтесь ссылкой «Сообщить модератору» рядом с сообщением!

Автор Тема: О выделении кавычками имен переменных в POSIX shell  (Прочитано 872 раз)

0 Пользователей и 1 Гость просматривают эту тему.

andrey_p

  • Автор темы
  • Гость
Здравствуйте всем.

Поймал себя на том, что часто не использую двойные кавычки с переменными в 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. Кавычки не нужно использовать, когда переменная содержит в себе имя команды.

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

« Последнее редактирование: 03 Июня 2011, 14:30:38 от andrey_p »

Оффлайн aliftin

  • Старожил
  • *
  • Сообщений: 1398
    • Просмотр профиля
Забавно, никогда не думал когда их ставить, а когда нет. Просто делал то что нужно и все.
Если мы не можем до чего то дотянуться, мы виним в этом не свой рост, не отсутствие табуретки, а свою цель.

andrey_p

  • Автор темы
  • Гость
Ну да, конечно. С опытом приходит. Но, повторюсь, это zsh на меня влияет дурно (там переменные не расширяются по умолчанию нигде - если нужны массивы, то и используются массивы). В соседней ветке сначала посоветовал

cat log | while read a b; do
  echo `date  -d @$a --rfc-3339=date` $b
done

В результате строчки лога сплющивались. Потом

#!/bin/sh

specification='--rfc-3339=date'

while read a b; do
  echo `date  -d @$a $specification` "$b"
done <$1

Понятно, что если спецификация через % и включает пробелы, то этот скрипт тоже работать не будет. Ну и в своих скриптах обнаруживаю похожие проблемы.

Выключать эту фичу в zsh не хочется - 99 процентов работы с шеллом - в консоли и quick&dirty скрипты, а потому без особой нужды двумя мизинцами дергаться совсем не привлекает. Так что вот, составил для себя правила при написании неодноразовых скриптов.

 

Страница сгенерирована за 0.083 секунд. Запросов: 25.