Отправляет email-рассылки с помощью сервиса Sendsay

Программирование на shell и awk

  Все выпуски  

О пользе «кавычек»


Информационный Канал Subscribe.Ru

Выпуск #7

О пользе «кавычек»

Речь сегодня пойдет о «кавычках»: двойных ("), одинарных (') и обратных (`). Одинарные кавычки еще называют апострофами. Слово кавычки взято в «елочки» не случайно. О настоящих кавычках можно прочесть в § 62 ру/ководства А. Лебедева. На самом деле:
  • символ " обозначает дюймы;
  • символ ' обозначает минуты;
  • символ ` обозначает слабое ударение.
В выпуске #4 рассылки я рассказывал о том, какие действия выполняет shell над переданной ему командной строкой. Так вот, если последовательность символов заключена в апострофы, то ни одно из этих действий над ними производиться не будет. Если же мы помещаем что-нибудь в двойные кавычки, то внутри них выполняется подстановка переменных и результатов выполнения команд. Обратная косая внутри двойных кавычек имеет особый смысл, только если после нее идет один из следующих символов: $, `, ", \ или перевод строки.

Сравните результаты работы двух следующих команд:

$ echo 'PATH=$PATH'

PATH=$PATH

$ echo "PATH=$PATH"

PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin

                                                              Пример 7.1

и объясните мне, зачем в команде awk '{print $2,$1}' нужно указывать апострофы.

Следующий пример должен пояснить почему имена переменных нужно брать в двойные кавычки, если вы не хотите чтобы командный интерпретатор истолковывал ее содержимое как отдельные слова:

$ rem="Ivan Petroff, tel. 12-34"

$ grep $rem /etc/passwd #случай раз

grep: Petroff,: No such file or directory
grep: tel.: No such file or directory
grep: 12-34: No such file or directory
ipetrov:x:501:501:Ivan Petroff, tel. 12-34:/home/ipetrov:/bin/bash

$ grep "$rem" /etc/passwd #случай два

ipetrov:x:501:501:Ivan Petroff, tel. 12-34:/home/ipetrov:/bin/bash

                                                              Пример 7.2

В первом случае командный интерпретатор после осуществления подстановки значения переменной rem получает и выполняет команду:

grep Ivan Petroff, tel. 12-34 /etc/passwd

Команда grep воспринимает первый аргумент (Ivan) как строку для поиска, а все оставшиеся аргументы — как имена файлов, в которых эту строку следует искать. Неудивительно что grep не смогла обнаружить файлы: 12-34, tel. и Petroff, — мы в них искать ничего и не собирались.

Во втором случае тоже происходит подстановка значения переменной rem, но на этот раз оно оказывается внутри кавычек:

grep "Ivan Petroff, tel. 12-34" /etc/passwd

Теперь grep будет искать строку Ivan Petroff, tel. 12-34, т. к. shell представит ей содержимое кавычек как один аргумент. Более детальную информацию о утилите grep на русском можно найти на http://ln.com.ua/openxs/projects/man/solaris8/grep.html.

Сразу предупреждаю, что нет никакой возможности явно указать символ ' внутри одинарных кавычек. Экранирование с помощью обратного слэша (\') не поможет. Вас выручит только указание числового кода (047) этого символа:

$ echo -e '\047$PATH\047' # Если у вас не Linux опцию -e указывать не нужно

'$PATH'

                                                              Пример 7.3

Двойные же кавычки экранируются без проблем:

$ echo "\""

"

                                                              Пример 7.4

Обратные кавычки позволяют использовать результаты работы программ в качестве параметра:

$ whoami

root

$ echo You are user `whoami`

You are user root

                                                              Пример 7.5

Внутри обратных кавычек тоже выполняется подстановка переменных:

$ echo "usage: `basename $0` [options] [files]"

usage: -bash [options] [files]

                                                              Пример 7.6

А что делать в случае, когда необходимо использовать вложенные вызовы программ-параметров? Когда, например, необходимо результаты работы конвейера who|awk '{print $2,$1}' использовать как аргументы команды dialog, а ее вывод сохранить в переменной ttyname? Если вы запишете эту команду как

ttyname=`dialog --stdout --menu User 20 40 12 `who|awk '{print $2,$1}'``

то ничего хорошего вы не получете. Командный интерпретатор выполнит команду dialog --stdout --menu User 20 40 12 из первой пары обратных кавычек. Команда «ругнется», что ей не хватает аргументов, и на этом все закончится. Значение переменной ttyname не измениться. Однако, чтобы добиться желаемого результата, у нас в резерве есть альтернативная синтаксическая конструкция $(...), которая действует аналогично `...` :

ttyname=$(dialog --stdout --menu User 20 40 12 `who|awk '{print $2,$1}'`)


Если вам порядком поднадоели все эти компьютеры, если вам интересна фотография или изобразительное искусство, то рекомендую посетить «Иероглиф» (http://hiero.ru).
Ведущий рассылки Big Shadow

Архив рассылки находится на http://win.subscribe.ru/archive/comp.soft.prog.shellandawk/



http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу

В избранное