Управление потоком, расширение и парсинг

Темы управления потоком, расширения и парсинга могут казаться несколько разрозненными, но они тесно связаны в контексте сценариев Оболочки Bourne.

В частности из-за маркерных правил разделения парсинг и расширение, наиболее вероятно, будут иметь поведенческое значение в контексте, проверяют утверждения (if, while, и т.д.).

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

Из-за сложного отношения между этими темами они описаны вместе в единственной главе.

Основные операторы управления

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

Если Оператор

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

Первое различие то, что тест, выполняемый if оператор является фактически выполнением команды. Когда оболочка встречается if оператор, это выполняет оператор, сразу следующий за ним. В зависимости от возвращаемого значения это выполнит то, что следует then оператор. Иначе, это выполнит то, что еще следует оператор.

Второе различие - то, что в сценариях оболочки, многими вещами, которые похожи на ключевые слова языка, являются фактически программы. Например, следующий код выполняется /bin/true и /bin/false.

# always execute
if true; then
    ls
else
    echo "true is false."
fi
# never execute
if false; then
    ls
fi

В обоих из этих случаев исполнимая программа выполняется — в частности, /bin/true и /bin/false. Любая исполнимая программа могла использоваться здесь.

Возврат нуля (0) считается верным (успех), и любое другое значение считается ложным (отказ). Таким образом, если исполнимая программа возвращает нуль (0), команды после then оператор будет выполняться. Иначе, операторы после else пункт (если Вы существуете) будет выполняться.

Причина этого по-видимому назад определение true и false это большая часть выхода инструментов UNIX со статусом выхода нуля на успех и ненулевым статусом выхода при отказе, с положительными числами, обычно указывающими пользовательскую ошибку и отрицательные числа, обычно указывающие более серьезный отказ некоторого вида. Таким образом можно легко протестировать, чтобы видеть, завершилась ли программа успешно путем наблюдения, совпадает ли статус выхода со статусом выхода true.

Один связанный оператор, с которым необходимо быть знакомы, elif. Этот оператор подобен высказыванию else if за исключением того, что это не требует дополнительного fi в конце условного выражения, и таким образом приводит к большему количеству читаемого кода.

Например:

#/bin/sh
 
read A
if [ "$A" = "foo" ] ; then
    echo "Foo"
elif [ "$A" = "bar" ] ; then
    echo "Bar"
else
    echo "Other"
fi

Этот пример читает строку из стандартного ввода и распечатывает одну из трех вещей, в зависимости от того, ввели ли Вы «foo», “панель’ или что-либо еще. (Синтаксис скобки, используемый в этом примере, объяснен в следующем разделе, тестовой Нотации Команды и Скобки.)

Тестовая Нотация Команды и Скобки

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

Поскольку if оператор выполняет команду для использования if оператор этим способом, Вам будет нужна программа для выполнения, который выполняет желаемое сравнение. К счастью, каждый встроен в OS: test. (Для получения дополнительной информации об использовании других команд с if оператор, посмотрите Работу с Кодами Результата.)

test исполнимая программа редко выполняется непосредственно, как бы то ни было. Обычно это вызывается путем выполнения [, который является просто символьной ссылкой или жесткой ссылкой на /bin/test.

В этой форме, синтаксисе if оператор более близко напоминает другие языки. Рассмотрите следующий пример:

#!/bin/sh
 
FIRST_ARGUMENT="$1"
if [ "$FIRST_ARGUMENT" = "Silly" ] ; then
    echo "Silly human, scripts are for kiddies."
else
    echo "Hello, world $FIRST_ARGUMENT!"
fi

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

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

При рассмотрении более старого кода можно также видеть пустую переменную проблему, решенную в другом отношении:

if [ x$VARIABLE = x ] ; then
    echo "Empty variable \$VARIABLE"
fi

В этом более старом стиле этим двум параметрам сравнению предшествует ‘x’ (и в этом примере, на правой стороне, ‘x’ ничему не предшествует, таким образом сравнивая значение с пустой строкой).

Причина это необходимо, состоит в том, потому что подстановка переменных происходит, прежде чем этот оператор выполняется. Если Вы опускаете ‘x’ на левой стороне и значении в $VARIABLE пусто, тогда этот оператор оценивает к “if [ = x ]”, который является явной синтаксической ошибкой.

Этот стиль не рекомендуется для нового кода. Это не обрабатывает пробелы в переменных и обеспечивает значительный вектор атаки для произвольной инжекции кода. См. Безопасность Сценария оболочки для получения дополнительной информации.

test команда может также использоваться для различных других тестов, включая тестирование на существование файла, основных числовых сравнений, проверка ли точки контура к каталогу, исполнимой программе или символьной ссылке, и т.д. Например, -d отметьте проверки, является ли его параметром каталог, как показано в этом отрывке:

if [ -d "/System/Library/Frameworks" ] ; then
    echo "/System/Library/Frameworks is a directory."
fi

Полный список флагов и операторов, поддерживаемых тестовой командой, может быть найден в странице справочника test.

В то время как Оператор

В дополнение к if оператор, Оболочка Bourne также поддерживает a while оператор. Его синтаксис подобен.

while true; do
    ls
done

Как if оператор then и fi, в то время как оператор заключается в скобки do и done. Во многом как if оператор, в то время как оператор берет отдельный аргумент, содержащий команду для выполнения. Когда статус выхода этой команды является (ненулевой) ложью, цикл завершается.

Как с if оператор, наиболее распространенная команда, используемая для управления цикличным выполнением, является командой скобки (как описано в тестовой Нотации Команды и Скобки).

Например:

while [ "x$FOO" != "x" ] ; do
    FOO="$(cat)";
done

Конечно, это - довольно глупый пример. Однако это действительно демонстрирует одну из более мощных функций на языке сценариев Оболочки Bourne: $() оператор, вставляющий вывод одной команды в середину оператора. В случае выше, cat команда выполняется, и ее стандартный вывод сохранен в переменной FOO. Этот метод описан больше во Встроенном Выполнении.

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

Например, рассмотрите следующие утверждения:

break 2
continue 2

Первый оператор выше (break 2) убегает не только из верхнего уровня while цикл, но также и while или for цикл, содержащий его. Второй оператор выше (continue 2) не только заставляет остаток от текущего цикла быть пропущенным, но также и вызывает остаток от цикла, включающего его, чтобы быть пропущенным.

Для оператора

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

В стандартной Оболочке Bourne, for оператор в сценариях оболочки абсолютно непохож на свой эквивалент C (который требует числового вычисления, как описано в Краске Числами), и фактически ведет себя во многом как foreach оператор на различных языках.

В некоторых современных вариантах Оболочки Bourne можно также сделать числовую версию для цикла. Синтаксис почти идентичен синтаксису C для для циклов.

Эти два синтаксиса покрыты следующими разделами.

Стандарт для циклов

for оператор в сценариях Оболочки Bourne выполняет итерации через элементы в списке. Для каждого элемента это устанавливает переменную цикла в элемент, затем выполняет серию операторов.

В следующем примере список *.JPG. Когда оболочка выполняет globbing на этом (см. Специальные символы, Объясненные для получения дополнительной информации), это заменяет *.JPG со списком файлов в текущем каталоге тот конец в .JPG.

Без того, чтобы сообщать подробности о синтаксисе регулярного выражения, используемом sed команда (этот синтаксис описан более подробно в Освобожденных Регулярных выражениях), следующий сценарий переименовывает каждый файл в текущем каталоге, заканчивающемся .JPG закончиться в .jpg.

#!/bin/sh
for i in *.JPG ; do
    mv "$i" "$(echo $i | sed 's/\.JPG$/.x/')"
    mv "$(echo $i | sed 's/\.JPG$/.x/')" "$(echo $i | sed 's/\.JPG$/.jpg/')"
done

for оператор (по умолчанию) разделяет список файлов на неупомянутых пробелах. Например, следующий сценарий распечатает буквы и «b» на отдельных строках, затем распечатает “c d” на третьей строке:

#!/bin/sh
for i in a b c\ d ; do
    echo $i
done

При определенных обстоятельствах можно изменить путь который for оператор разделяет списки путем изменения содержания переменной IFS. Подробные данные того, когда это делает и не работает, описаны в Переменном Расширении и Разделителях полей.

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

Например, рассмотрите следующие утверждения:

break 2
continue 2

Первый оператор выше (break 2) убегает не только из верхнего уровня for цикл, но также и while или for цикл, содержащий его. Второй оператор выше (continue 2) не только заставляет остаток от текущего цикла быть пропущенным, но также и вызывает остаток от цикла, включающего его, чтобы быть пропущенным.

Расширенный для циклов

Большинство современных Оболочек Bourne (включая BASH) обеспечивает расширение для числового для циклов с помощью варианта встроенного математического оператора (двойные круглые скобки). Вы видите этот стиль for цикл в следующем сценарии. Это берет отдельный аргумент и количества от 1 до числа, указанного в том параметре. Для демонстрации понятия максимально кратко это не предпринимает попытки проверить ее ввод. Однако, необходимо всегда делать так в сценариях.

#!/bin/bash
 
# This is an extension that is supported in
# bash, zsh, and many other recent sh variants,
# but is not always valid.
#
# Usage: for5.sh <number>
 
for (( i = 1 ; i <= $1 ; i++ )) ; do
        echo "I is $i"
done

Для максимальной мобильности, однако, необходимо использовать a while цикл, как показано ниже:

i=1
while [ $i -le $1 ] ; do
    echo "I is $i"
    i=`expr $i '+' 1`
done

Оператор выбора

Финал проверяет утверждение в этой главе, case оператор. case оператор в сценариях оболочки подобен C switch оператор. Это позволяет Вам выполнять многократные команды в зависимости от значения переменной. Синтаксис следующие:

case expression in
    [(] value | value | value | ... ) command; command; ... ;;
    [(] value | value | value | ... ) command; command; ... ;;
    ...
esac

Необходимо заметить три вещи об этом синтаксисе. Во-первых, каждый случай завершается двойной точкой с запятой. Во-вторых, вводная круглая скобка является дополнительной и часто отбрасывается авторами сценария. В-третьих, единственный набор команд может быть применен к любому числу значений, разделенных каналом (вертикальная панель) символ (|).

Например, следующий пример кода распечатывает английские имена для номеров 0-9, затем распечатывает их снова.

#!/bin/sh
 
LOOP=0
 
while [ $LOOP -lt 20 ] ; do
        # The next line is explained in the
        # math chapter.
        VAL=`expr $LOOP % 10`
 
        case "$VAL" in
                ( 0 ) echo "ZERO" ;;
                ( 1 ) echo "ONE" ;;
                ( 2 ) echo "TWO" ;;
                ( 3 ) echo "THREE" ;;
                ( 4 ) echo "FOUR" ;;
                ( 5 ) echo "FIVE" ;;
                ( 6 ) echo "SIX" ;;
                ( 7 ) echo "SEVEN" ;;
                ( 8 ) echo "EIGHT" ;;
                ( 9 ) echo "NINE" ;;
                ( * ) echo "This shouldn't happen." ;;
        esac
 
        # The next line is explained in the
        # math chapter.
        LOOP=$((LOOP + 1))
done

Необходимо заметить ( * ) случай в конце. Это эквивалентно default случай в C. В то время как тот случай никогда не будет достигаться в этом примере при изменении значения модуля от 10 до какого-либо большего значения Вы будете видеть, что этот случай выполняется, когда никакой предыдущий случай не соответствует значение выражения.

expr Команда

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

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

expr "This is a test" '<' "I am a person"

Следующая версия перестала работать скудно, потому что оболочка интерпретирует меньше знак как перенаправление и попытки читать из файла, вызванного, “Я - лицо”:

expr "This is a test" < "I am a person"

Подробные данные заключения в кавычки описаны далее в Парсинге, Переменном Расширении и Заключении в кавычки.

expr команда поддерживает обычное дополнение сравнений строк (равенство, неравенство, меньше, больше - чем, меньше чем или равный, и больше, чем или равный).

В дополнение к этим сравнениям, expr команда может сделать несколько других тестов: логическое «или» оператор, логическое «и» оператор, и (справедливо ограниченный) основной оператор соответствия регулярного выражения.

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

#!/bin/sh
 
NAME=`expr "$1" '|' "Untitled"`
echo "The chosen name was $NAME"

«Или» оператор (|) распечатывает значение первого выражения ("$1" в этом примере), если это непусто и содержит что-то другое, чем нуль (0) числа. Иначе, если вторая строка непуста и содержит что-то другое, чем нуль числа, она распечатывает второе выражение ("Untitled" в этом примере). Если обе строки пусты или нуль, он распечатывает нуль числа. Если обе строки пусты или нуль, статус выхода команды является нулем на успехе, тот.

«И» оператор (&) подобно, возвращая любого первая строка (если обе строки непусты), или нуль (если любая строка пуста).

Наконец, expr команда может работать с основными регулярными выражениями (не расширенные регулярные выражения) до ограниченного уровня.

Для подсчета числа символов с начала строки (все выражения неявно привязываются на запуске строки) до и включая последнюю букву 'я' Вы могли записать выражение как это:

STRING="This is a test"
expr "$STRING" : ".*i"

Строка к правой стороне двоеточия является относительно простым регулярным выражением. Символ точки соответствует отдельный символ. Звездочка изменяет поведение периода так, чтобы это соответствовало нуль или больше символов. (Считайте Регулярные выражения, Освобожденные для дальнейшего объяснения.), Если строка не соответствует выражение, expr команда возвращает нуль (0), соответствующий числу соответствующих символов.

Наиболее популярный способ использования этого синтаксиса получает длину строки, как показано в этом отрывке:

STRING="This is a test"
expr "$STRING" : ".*"

Этот тот же синтаксис может использоваться для возврата текста, полученного первым набором круглых скобок в основном регулярном выражении. Например, для печати этих четырех символов сразу до последнего вхождения «оценки» Вы могли записать выражение как этот:

STRING="This is a test" expr "$STRING" : '.*\(....\)est'

Если первая строка не соответствует выражение, поскольку это выражение содержит круглые скобки получения expr команда распечатывает пустую строку.

Для получения дополнительной информации о записи основных регулярных выражений, считайте Освобожденные Регулярные выражения.

Парсинг, переменное расширение и заключение в кавычки

И в Оболочке Bourne и в оболочке C, строки кода обрабатываются в многократных передачах. Первая передача является передачей парсинга, в которой извлечена базовая структура строки кода. В этой передаче кавычки служат разделителями между отдельными данными. Например, можно сразу распечатать букву после содержания переменной без пространства путем закрытия (и повторного открытия если необходимый) двойные кавычки включения сразу после имени переменной.

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

Наконец, третья передача является передачей выполнения. В этой передаче фактически выполняется код.

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

Переменное расширение и разделители полей

В сценариях Оболочки Bourne две операции затронуты значением IFS (внутренние разделители полей), окружают переменную: read оператор и переменное расширение. Эффект на read оператор описан отдельно во Вводе и выводе Сценария оболочки Используя printf и считан.

Каждый раз, когда оболочка разворачивает переменную, значение IFS играет роль. Например, следующий сценарий распечатает и «b» на отдельных строках, тогда “c d” на третьей строке:

#!/bin/sh
 
IFS=":"
LIST="a:b:c d"
for i in $LIST ; do
        echo $i
done

Это происходит только потому, что значение на правой стороне for оператор содержит переменную (LIST) это расширено оболочкой. Когда оболочка разворачивает переменную, она заменяет двоеточие пространством и заключает любые пробелы в кавычки в исходной строке. В действительности, к этому времени for оператор видит значения, правая сторона для оператора содержит a b c\ d, так же, как в примере, показанном в для Оператора.

Если Вы вставляете точное содержание LIST на правой стороне переменной этот сценарий вместо этого распечатает «a:b:c» на одной строке и «d» на другом. Это демонстрирует, почему очень важно выбрать разделители записей правильно.

Объясненные специальные символы

В сценариях оболочки существует несколько специальных символов: знак доллара ($), звездочка (*), вопросительный знак (?), изогнутые фигурные скобки ({ и }), квадратные скобки ([ и ]), круглые скобки (( и )), метки одинарной и двойной кавычки (' и "), метка обратной галочки (`, иногда называемый левой меткой одинарной кавычки), и наклонная черта влево (\). Эти символы обрабатываются по-другому оболочкой.

Большинство этих специальных символов используется в расширении имени файла, также известном как globbing. Символы Globbing соблюдают различные правила расширения, чем другие символы.

Символы ведут себя следующим образом:

  • Знак доллара ($) — первый символ в переменном расширении, окружите встроенную математику и встройте выполнение. Имена переменной, начинающиеся со знака доллара, расширены независимо от того, появляются ли они в двойных кавычках. Если используется за пределами двойных кавычек, любые globbing символы в содержании переменной также расширены. Имена переменной в содержании не расширены, как бы то ни было.

  • Звездочка (*) — подстановочный символ, соответствующий любое число символов в имени файла. Например, ls *.jpg соответствия все файлы, заканчивающиеся расширением .jpg. Звездочка используется в globbing.

  • Вопросительный знак (?) — подстановочный символ, соответствующий отдельный символ в имени файла. Например, ls a?t.jpg соответствия оба ant.jpg и art.jpg. Вопросительный знак используется в globbing.

  • Изогнутые фигурные скобки — соответствуют любую серию опций в имени файла. Например, ls *.{jpg,gif} соответствует каждый файл, заканчивающийся также .jpg или .gif. Изогнутые фигурные скобки используются в globbing.

  • Квадратные скобки — соответствуют любую серию символов в имени файла. Например, ls a[rn]t.jpg соответствия art.jpg и ant.jpg, но не соответствует aft.jpg. Если первый символ является каре (^), это соответствует каждый символ за исключением перечисленных символов.

    Синтаксис этих классов символов подобен классам символов в регулярных выражениях, но существует много тонких различий. Для получения дополнительной информации посмотрите страницу Open Group на нотации сопоставления с образцом в http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_13.

    Квадратные скобки используются в globbing.

  • Круглые скобки — эти символы служат многократным целям, в зависимости от контекста:

  • Метки двойной кавычки — отключают разделение параметра на границах слова (пробелы) и расширение оболочки наиболее специальных символов в метках кавычки за немногим исключением:

    • Переменные расширены в метках двойной кавычки. Содержание переменных, однако, не расширено всегда, даже если они содержат globbing символы.

    • Встроенное выполнение также расширено в метках двойной кавычки.

    • Символ наклонной черты влево все еще функционирует в метках двойной кавычки в Оболочке Bourne и вариантах этого, но не в вариантах оболочки C.

  • Метки одинарной кавычки — отключают разделение параметра на границах слова (пробелы) и отключают все расширение оболочки (включая переменные). Наклонная черта влево обрабатывается точно так же, как любой другой буквенный символ, когда это появляется в одинарных кавычках. Например, '\"' строка, содержащая наклонную черту влево и метку двойной кавычки.

  • Метки обратной галочки — примерно эквивалентный $(), они используются для разграничивания кода для встроенного выполнения. Этот метод описан во Встроенном Выполнении.

  • Наклонная черта влево — заставляет следующий символ быть обработанным как буквенный символ, переопределяя специальные способы поведения, объясненные в этом разделе. Этот метод описан далее в Заключении в кавычки Специальных символов.

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

#!/bin/sh
echo "Filename?"
read NAME
ls $NAME
ls "$NAME"

Если пользователь вводит *.jpg при подсказке, первые списки команд все файлы, заканчивающиеся в .jpg потому что переменная расширена сначала, и затем выражение в ней расширено. Вторые списки команд единственный файл (или печать ошибка, если Вам не называли файл *.jpg).

Заключение в кавычки специальных символов

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

Если строка, которую Вы хотите заключить в кавычки, не в метках кавычки, это, вероятно, должно быть. Иначе, необходимо иметь дело со всеми специальными символами оболочки (описанный в Объясненных Специальных символах) плюс любые новые специальные символы, которые могли бы быть добавлены в будущем. Защита от специальных символов особенно важна, если Ваш сценарий берет произвольный ввод данных пользователем и передает его как параметр команде.

Однако, если Ваш сценарий не обрабатывает ввод данных пользователем, можно заключить отдельный символ в кавычки путем простого предшествования ему с наклонной чертой влево (\). Это говорит оболочке обрабатывать его как буквенный символ вместо того, чтобы обычно интерпретировать его. Например, следующий пример кода распечатывает слово «Hello», включенное в двойные кавычки.

echo \"Hello\"

Если символ, который Вы хотите заключить в кавычки, в двойных кавычках, те же правила применяются. Единственная разница - то, что за исключением знаков доллара и самих меток двойной кавычки, Вы не должны заключать специальные символы в кавычки в этом контексте. Например, для печати имени переменной, сопровождаемой ее значением, Вы могли записать оператор как следующий, распечатывающий “Значение $VAR, 3” (без кавычек):

VAR=3
echo "The value of \$VAR is $VAR"

Точно так же можно заключить наклонную черту влево в кавычки с другой наклонной чертой влево, если необходимо распечатать ее. Например, печать следующего утверждения “Это \является наклонной чертой влево “. (снова, без кавычек):

echo "This \\ is a backslash."

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

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

Например, следующие строки кода оба распечатывают популярную фразу от американского детского телешоу:

echo 'It'\''s a beautiful day in the neighborhood.'
echo 'Won'"'"'t you be my neighbor?'

Встроенное выполнение

Оболочка Bourne предоставляет двум операторам для выполнения команды и размещения ее вывода посреди другой команды или строки. Эти операторы $() оператор и обратная галочка (`) оператор (чтобы не быть перепутанным с нормальной одинарной кавычкой).

Эти операторы часто используются с командами, генерирующими список имен файлов для передачи их как списка аргументов к другой команде. Например, grep команда, когда передано -l флаг, возвращает список файлов то соответствие. Этот метод часто объединяется с -r флаг, делающий поиск grep рекурсивно файлов в любых каталогах, с которыми это встречается в его списке файлов. Таким образом, если Вы хотите отредактировать какие-либо файлы, содержание которых содержит слово»myname«с vi, например, Вы могли сделать это как это:

vi $(grep -rl myname directory_of_files)

Можно, однако, использовать это для выполнения любой команды. Существует один маленький протест, о котором необходимо знать, как бы то ни было. Оператор обратной галочки не может быть вложен. Например, следующая команда производит ошибку:

FOO=1; BAR=3
echo "Try this command: `echo $FOO + "`expr $BAR + 1`"`"

Это перестало работать, потому что команда эха заканчивается во второй обратной галочке. Таким образом выполняемая команда echo $FOO + ". Если необходимо вложить встроенное выполнение, можно использовать $() оператор для вложенной команды. Например, предыдущий пример может быть записан правильно следующим образом:

FOO=1; BAR=3
echo "Try this command: `echo $FOO + "$(expr $BAR + 1)"`"

Необходимо заметить, что двойные кавычки могут быть безопасно вложены в команде, включенной или обратными галочками или $() оператор.