BashЯзык командного интерпретатора bash. Part 2. "Подстановки"

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

Подстановка параметров

Параметрам можно найти различное применение. Их можно использовать как имена, части имён или аргументы команд. Перед тем, как выполнить команду, bash заменит имя параметра его значением.
$ cwd=/home/istergul # присваиваем параметру cwd путь к домашнему каталогу
$ cd $cwd # переходим в домашний каталог, подставляя в команду cd параметр cwd

Вывести на экран файл readme из домашнего каталога теперь можно, введя команду (если конечно, данный файл существует):
$ more ${cwd}/readme

Здесь имя параметра взято в скобки. Это делать не обязательно, но это позволит отделить имя параметра от окружающих символов с целью его выделения.
Возможности bash позволяют производить подстановку команд, то есть заменять имя команды на результат её выполнения. Например:
$ cd ~
$ cwd=`pwd`

Или же так:
$ cwd=$(pwd)

Теперь переменная cwd будет содержать путь к вашему домашнему каталогу.
Вот ещё пример командной подстановки:
$ tar -czf /backup/$(date +%A).tgz /etc

Команда создаёт архив в директории /etc с названием /backup/<текущий день недели>.tgz.
В следующем примере команда добавляет в приглашение командной строки вывод последней строки из системного log-файла.
$ PS1="\$(tail -1 /var/log/messages)\n$PS1"

Производить подстановки можно не только с определёнными вами параметрами, но и с переменными окружения. Например, выведем поэкранно список всех процессов, запущенных от вашего имени:
$ ps –ef | grep $USER | less

Останавливаться на командах ps, grep и less не буду. Вы можете узнать о них, используя команду man.

Подстановка символов шаблонов

Механизм шаблонов имён файлов позволяет не перечислять похожие имена файлов и каталогов, а указать на группу имён, задав краткий образец (шаблон). Шаблоны указываются с помощью специальных символов, которые можно комбинировать в одной команде. Перечислим символы шаблонов:
* — произвольная строка символов, в том числе пустая. Следует заметить, что сюда не входят имена файлов, начинающиеся с ".", то есть скрытые файлы.
$ ls ./*.txt # все файлы в текущем каталоге с расширением txt

? – одиночный символ;
$ ls ./file?.txt # файлы в текущем каталоге с расширением txt, начинающиеся с file (такие как file1.txt, filex.txt и др.)

[mMx] – любой символ из перечисленных;
$ ls ./file[2N].txt # файлы в текущем каталоге, такие как file2.txt, fileN.txt

[a-zA-F] – любой символ из указанных интервалов;
$ ls ./file[3-49] # файлы в текущем каталоге, такие как file3, file4, file9

[^a-zxy] – любой символ, не указанный в скобках;
$ ls ./file[^0].txt # все файлы в текущем каталоге, кроме file0.txt

Для того чтобы символы шаблонов использовать как обычные символы, их нужно экранировать:
$ touch file\* # создать файл с именем file*


Другие подстановки

Подстановка тильды:
~ — заменяется на имя вашего домашнего каталога;
~+ — заменяется на путь к текущему каталогу;
~- — заменяется на путь к предыдущему каталогу;
~istergul/Desktop — заменяется на путь к папке Desktop в домашней папке istergul.

Раскрытие скобок:
name1{name2,name3}name4 – заменяется на name1name2name4 name1name3name4. Пробелы ставить внутри скобок не нужно! Данную функцию можно применять, когда нельзя составить общего шаблона. Например:
$ cat /home/istergul/{file1,name1,readme} > file


Подстановка арифметических выражений
$((выражение)) или $[выражение] – эквивалентные формы записи. Внутри выражения выполняются установки параметров. Приоритет арифметических операций можно посмотреть man bash в секции ARIFMETIC EVALUATION. Например, количество часов прошедшее с момента запуска оболочки, можно подсчитать следующим образом:
$ echo $(( $SECONDS/3600 ))


Надеюсь, было интересно и информативно :). В следующем посте я рассмотрю поддержку массивов в командном интерпретаторе bash.

UPD: Спасибо пользователю aonick за его замечания. Именно благодаря ему мои посты получаются ещё более актуальными.

Комментарии (10)

Оперативно =) Молодца!!!
Спасибо :)
Просто я так и планировал — в день по одному новому топику касательно данной темы.
Было бы очень здорово.
  • avatar
  • Dez
  • 08 июля 2009, 00:29
  • #
  • 1
Отлично! Thnx большой!!!
Жду продолжения…
Продолжение будет завтра :)
интересно и информативно, но…

Поправки:
1) Запись ./file[3-4,9] — означает что будут показаны следующие файлы(если они существуют) из текущей директории: «file3», «file4», «file9» и обращаю здесь внимание «file,». То есть заканчивающийся на «запятую». Вообщем правильнее было писать не [a-z,A-F], а [a-zA-F]. Пример подтверждающий:
$ touch file{1..9} file, 
$ ls file[1-3,5-8]
file,  file2  file5  file7
file1  file3  file6  file8


2) В шаблонах(wildcards) "*" — означает любые файлы, кроме тех которые начинаются с точки, т.е «ls ./*.txt» — точнее означает показать «все файлы в текущем каталоге с расширением txt, кроме тех что начинаются с точки». Пример подтверждающий:
$ touch .file.txt file.txt
$ ls ./*.txt
./file.txt

3) Командную подстановку удобнее использовать
вместо: cwd=`pwd`
так: cwd=$(pwd)
Просто потому, что удобно делать вложенные конструкции типа:
rpm -e $(rpm -qi $(which bluhbluhbluh))
— это просто, для примера, удаляется rpm-пакет из которого была установлена утилита bluhbluhbluh

Добавка:
~aonick/Desktop — заменяется на путь к папке Desktop в домашней папке aonick

Спасибо за ваши замечания. Внёс соответствующие поправки и дополнения.
Буду признателен, если и вы и дальше будете комментировать мои посты.
Пожалуйста.
Буду признателен. если и дальше будет, что комментировать :)
Простой пример командной постановки:
1)
tar -czf /backup/$(date +%A).tgz /etc

Создает архив директории /etc с названием(сегодня) /backup/Четверг.tgz, а если выполню завтра то будет /backup/Пятница.tgz

2)
PS1="\$(tail -1 /var/log/messages)\n$PS1"

В приглашении командной строки добавился вывод последней строки из системного log-файла

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.