[[email protected] ~]$ echo this is a test
this is a test
Все очень просто. echo выведет любой свой аргумент. Давайте попробуем другой пример:
[[email protected] ~]$ echo *
Desktop Documents ls-output.txt Music Pictures Public Templates Videos
Что это? Почему echo не вывела символ *? Как вы помните из опытов с групповыми символами, символ * означает «последовательность любых символов в имени файла», правда, в том обсуждении не рассказывалось, как командная оболочка делает это. На самом деле все просто: перед тем, как выполнить команду echo, оболочка замещает символ * чем-то другим (в данном случае именами файлов в текущем рабочем каталоге). После нажатия клавиши ENTER командная оболочка автоматически производит подстановку любых условных символов в командной строке, прежде чем выполнить ее, поэтому команда echo не увидела * — она получила уже готовый результат подстановки. Теперь вы понимаете, что в действительности echo действует в точности с нашими ожиданиями?
Подстановка путей
Механизм работы групповых символов называется подстановкой пути (pathname expansion). Если вернуться к некоторым приемам, продемонстрированным в предыдущих главах, мы увидим, что в действительности они основаны на подстановке. Допустим, содержимое домашнего каталога выглядит вот так:
[[email protected] ~]$ ls
Desktop ls-output.txt Pictures Templates
Documents Music Public Videos
Мы могли бы выполнить следующую подстановку:
[[email protected] ~]$ echo D*
Desktop Documents
или
[[email protected] ~]$ echo *s
Documents Pictures Templates Videos
или даже
[[email protected] ~]$ echo [[:upper:]]*
Desktop Documents Music Pictures Public Templates Videos
И заглянуть за пределы домашнего каталога:
[[email protected] ~]$ echo /usr/*/share
/usr/kerberos/share /usr/local/share
Подстановка тильды
Как вы помните из вводного обсуждения команды cd, символ тильды (~) имеет специальное значение. Если он используется в начале слова, то замещается именем домашнего каталога указанного пользователя или, если пользователь не указан, именем домашнего каталога текущего пользователя:
[[email protected] ~]$ echo ~
/home/me
Если в системе существует учетная запись пользователя foo, тогда
[[email protected] ~]$ echo ~foo
/home/foo
подстановка пути для скрытых файлов
Как мы знаем, файлы с именами, начинающимися с точки, считаются скрытыми. Механизм подстановки пути также учитывает это. Подстановка, такая как
echo *
не покажет скрытые файлы.
На первый взгляд кажется, что можно было бы включить скрытые файлы в подстановку, добавив в начало шаблона символ точки, например:
echo .*
Да, такой подход даст желаемое. Однако, если внимательно исследовать результаты, можно заметить, что в них также присутствуют имена . (точка) и .. (две точки). Так как эти имена соответствуют текущему рабочему каталогу и родительскому каталогу, применение такого шаблона может привести к неправильным результатам. Убедимся в этом с помощью команды
ls -d .* | less
Чтобы обеспечить правильную подстановку пути в такой ситуации, следует использовать специализированный шаблон. Следующий шаблон действует правильно:
ls -d .[!.]?*
Этот шаблон замещается именами файлов, начинающимися с точки, за которой следует хотя бы один символ, кроме точки, за которым в свою очередь может следовать любое количество других символов.
Подстановка результатов арифметических выражений
Командная оболочка поддерживает также подстановку результатов арифметических выражений. Это позволяет использовать командную строку как калькулятор:
[[email protected] ~]$ echo $((2 + 2))
4
Для подстановки арифметических выражений используется следующий формат:
$((выражение))
где выражение — это арифметическое выражение, состоящее из значений и арифметических операторов.
Механизм подстановки арифметических выражений позволяет использовать только целые числа (невещественные), зато поддерживает множество арифметических операций. В табл. 7.1 перечислены некоторые из поддерживаемых операторов.
Таблица 7.1. Арифметические операторы
Оператор
Описание
+
Сложение
-
Вычитание
*
Умножение
/
Деление (но помните: из-за того, что подстановка поддерживает только целочисленную арифметику, результатом будет целое число)
%
Деление по модулю или остаток от деления
**
Возведение в степень
Пробелы в арифметических выражениях не играют роли, а выражения могут содержать вложенные выражения. Например, умножение 52 на 3:
[[email protected] ~]$ echo $(($((5**2)) * 3))
75
Для группировки подвыражений допускается использование одиночных круглых скобок. С помощью этого приема выражение, приведенное выше, можно переписать, как показано ниже, и получить тот же результат, но при этом будет использоваться одна операция подстановки вместо двух:
[[email protected] ~]$ echo $(((5**2) * 3))
75
Следующий пример демонстрирует использование операторов деления и получения остатка. Обратите внимание, как действует целочисленное деление:
[[email protected] ~]$ echo Пять разделить на два будет $((5/2))
Пять разделить на два будет 2
[[email protected] ~]$ echo и $((5%2)) в остатке.
и 1 в остатке.
Подстановка результатов арифметических выражений подробнее будет рассматриваться в главе 34.
Подстановка фигурных скобок
Самым малопонятным, пожалуй, выглядит результат подстановки фигурных скобок. С помощью этого механизма из одного шаблона, содержащего фигурные скобки, создается множество текстовых строк. Например:
[[email protected] ~]$ echo Впереди-{A,B,C}-позади
Впереди-A-позади Впереди-B-позади Впереди-C-позади
Шаблоны с фигурными скобками могут содержать начальную часть, которая называется преамбулой, и заключительную часть, которая называется эпилогом. Внутри фигурных скобок находится список строк, разделенных запятыми, или диапазон целых чисел или одиночных символов. Использование пробелов внутри фигурных скобок не допускается. Ниже приводится пример с использованием диапазона целых чисел:
[[email protected] ~]$ echo Число_{1..5}
Число_1 Число_2 Число_3 Число_4 Число_5
В следующем примере используется диапазон символов в обратном порядке:
[[email protected] ~]$ echo {Z..A}
Z Y X W V U T S R Q P O N M L K J I H G F E D C B A
Допускается вложение фигурных скобок:
[[email protected] ~]$ echo a{A{1,2},B{3,4}}b
aA1b aA2b aB3b aB4b
Какую пользу можно извлечь из этого? Такая возможность может пригодиться для формирования списков файлов или каталогов, которые требуется создать. Например, фотограф, имеющий огромную коллекцию фотографий и желающий организовать ее по годам и месяцам, мог бы начать с создания группы каталогов с именами, состоящими из номера года и месяца. Благодаря этому имена каталогов будут отсортированы в хронологическом порядке. Можно было бы ввести полный список каталогов, но это обременительно и чревато ошибками. Вместо этого выполним следующую команду:
[[email protected] ~]$ mkdir Pics
[[email protected] ~]$ cd Pics
[[email protected] Pics]$ mkdir {2009..2011}-0{1..9} {2009..2011}-{10..12}
[[email protected] Pics]$ ls
2009-01 2009-07 2010-01 2010-07 2011-01 2011-07
2009-02 2009-08 2010-02 2010-08 2011-02 2011-08
2009-03 2009-09 2010-03 2010-09 2011-03 2011-09
2009-04 2009-10 2010-04 2010-10 2011-04 2011-10
2009-05 2009-11 2010-05 2010-11 2011-05 2011-11
2009-06 2009-12 2010-06 2010-12 2011-06 2011-12
Однако!
Подстановка параметров
В этой главе мы лишь кратко коснемся подстановки параметров, а детально обсудим ее позже. Эта возможность полезнее в сценариях на языке командной оболочки, чем непосредственно в командной строке. Многие из ее возможностей имеют отношение к способности системы хранить маленькие фрагменты данных и присваивать этим фрагментам имена. Многие такие фрагменты, правильнее их называть переменными, уже существуют и доступны для исследования. Например, переменная с именем USER хранит ваше имя пользователя. Подстановка параметра и получение содержимого переменной USER выполняется следующим образом:
[[email protected] ~]$ echo $USER
me
Чтобы увидеть список доступных переменных, выполните следующую команду:
[[email protected] ~]$ printenv | less
Возможно, вы обратили внимание, что если в других вариантах подстановки допустить ошибку в шаблоне, подстановка не будет выполнена и команда echo просто выведет ошибочный шаблон. В случае с подстановкой параметров все иначе: если ошибиться в имени переменной, подстановка все равно будет выполнена, но результатом будет пустая строка:
[[email protected] ~]$ echo $SUER
[[email protected] ~]$
Подстановка команд
Подстановка команд позволяет использовать поток вывода команд в качестве аргументов других команд:
[[email protected] ~]$ echo $(ls)
Desktop Documents ls-output.txt Music Pictures Public Templates Videos
Один из моих любимых вариантов выглядит так:
[[email protected] ~]$ ls -l $(which cp)
-rwxr-xr-x 1 root root 71516 2012-12-05 08:58 /bin/cp
Здесь результат команды which cp передается как аргумент команде ls, благодаря чему мы получаем информацию о программе cp, не зная полного пути к ней. Подстановка команд не ограничивается такими простыми командами. Можно использовать целые конвейеры (здесь показана только часть вывода):