Разница между 1.49 и текущей версией ОболочкаShell.
@@ -1,18 +1,15 @@
-- Оболочка shell
-
-
--- Кратко о программируемой оболочке
+= Оболочка shell
 
 Программируемая оболочка интерпретирует команду и выполняет её. Оболочка shell предназначена для манипуляции с:
 	1 данными — строчно-ориентированная обработка;
-	1 файлами — посредством многочисленных утилиты Unix;
+	1 файлами — посредством многочисленных утилит Unix;
 	1 программами — как инструментом «склеивания» разных программ друг с другом (конвеер, сопроцессы, асинхронный запуск и пр.)
 
 В Unix оболочка shell — обычная программа.
 Она не является частью ядра.
 Перечислим значимые особенности и возможности оболочки:
 	* Оболочка раскрывает шаблоны имён файлов. Shell находит совпадающие с шаблоном имена файлов, формирует из них список и выполняет подстановку в аргументы команды. Команды Unix, используемые в оболочке, не обязаны уметь раскрывать шаблоны, так как этим занимается сама оболочка.
-	* Перенаправление ввода-вывода. Любая программа, запускаемая в оболочке, может вводить данные из файлов и выводить их в файл, а не через терминал. Программы могут быть соединены посредством ''программных каналов'' (''pipes'') в конвеер;
+	* Оболочка организует перенаправление ввода-вывода. Любая программа, запускаемая в оболочке, может вводить данные из файлов и выводить их в файл, а не через терминал. Программы могут быть соединены посредством ''программных каналов'' (''pipes'') в конвеер;
 	* Оболочка предоставляет настраиваемые переменные окружения (environment variables), псевдонимы команд (alias) и возможность организовывать часто выполняемые последовательности команд в функции.
 
 Архитектура расширений языка в оболочке shell беспрецедентно проста и
@@ -31,7 +28,27 @@
 когда расходы на сами операции
 (ввод-вывод, вычисления) существенно превышают расходы на создание новых процессов.
 
--- Интерактивный и неинтерактивный режимы
+-- Среда запуска команд
+
+Запускаемые программы наследуют окружение оболочки, а именно:
+
+	1 Открытые файлы и режим доступа (чтение, запись, чтение/запись). Средствами оболочки осуществляется перенаправление ввода-вывода, открытие и закрытие файлов (команда ''exec'').
+	1 Текущий каталог. Любая программа в Unix имеет свой текущий каталог. Смена текущего каталога в оболочке выполняется командой ''cd''.
+	1 Маску режима доступа для новых файлов. Оболочка может изменить маску на произвольную командой ''umask''.
+	1 Игнорируемые сигналы. Маска игнорируемых сигналов наследуется программами запускаемыми в оболочке.
+	1 Переменные окружения. Переменные окружения унаследованные от оболочки доступны программе через функцию стандартной библиотеки Си ''getenv''(3).
+
+Через наследование окружения оболочка организует взаимодействие программ друг с другом.
+Таким образом в Unix была реализована парадигма компонентного программирования  и повторного использования (в ответ на кризис программного обеспечения) задолго до того,
+как к ней обнаружился интерес в академической среде и появились реализации популярных ООП-языков.
+К сожалению,
+подход к решению задач в основу которого положены программы-фильтры и конвеер был проигнорирован в академической среде в угоду парадигме ООП.
+
+Специализированные утилиты из набора инструментария Unix следует рассматривать как ортогональные компоненты,
+где каждая программа отвечает за свою отдельную чётко определённую задачу.
+Программируя в оболочке пользователь получает новые инструменты «склеивая» и комбинируя существующий компактный набор типовых компонентов-программ.
+
+- Интерактивный и неинтерактивный режимы
 
 В интерактивном режиме оболочка сигнализирует
 о готовности принимать команды приглашением — символом доллара ($).
@@ -45,7 +62,7 @@
  world
  $
 
-В приведённом выше примере оболочка ожидает продолжения ввода после `’hello`,
+В приведённом выше примере оболочка ожидает продолжения ввода после ``’hello``,
 т. к. символ апострофа (’) обозначает начало экранируемой строки,
 и строка считается незавершённой,
 пока оболочка не встретит парный апостроф.
@@ -69,7 +86,7 @@
  $
 
 Второй способ — добавить путь к интерпретатору в сам файл.
-Для этого нужно первой строкой в файле поместить `#!/bin/sh`
+Для этого нужно первой строкой в файле поместить ``#!/bin/sh``
 и добавить разрешение на исполнение файла:
 
  $ chmod +x hello
@@ -81,6 +98,8 @@
  world
  $
 
+- Запуск команд
+
 -- Простые команды
 
 Оболочка выполняет преобразования с командами,
@@ -93,8 +112,8 @@
 последующие слова передаются как аргументы команде.
 Для трассировки изменений,
 вносимых оболочкой в команды,
-включают режим трассировки командой `set -x`,
-а выключают трассировку командой `set +x`.
+включают режим трассировки командой ``set -x``,
+а выключают трассировку командой ``set +x``.
 Несколько команд можно ввести в одну строку через разделитель (;).
 
  $ '''echo hello; echo world'''
@@ -104,7 +123,56 @@
 
 Вторая команда выполняется сразу после первой, приглашения не выводятся.
 
--- Переменные
+-- Асинхронный запуск
+
+Команды в оболочке запускаются последовательно.
+Перед тем как запустить следующую команду оболочка дожидается завершения предыдущей.
+Существует способ запуска программ асинхронно, без ожидания завершения.
+Тогда говорят, что программа работает в ''фоновом режиме'' (''background'').
+В общем виде запуск списка асинхронных команд выглядит так:
+
+ cmd₁ & cmd₂ & … cmdₙ &
+
+Пусть пользователь желает выполнить какое-то длительное действие,
+например,
+распаковать большой архив.
+
+ $ '''tar xf archive.tar &'''
+ [1]+ 31408
+ $
+
+Оболочка немедленно готова к запуску следующей команды.
+Встроенная команда оболочки ''jobs'' выводит список команд, запущенных асинхронно.
+Такие команды называются ''заданиями'' (''jobs'').
+
+ $ '''jobs'''
+ [1]+  Running		  tar xf archive.tar
+ $
+
+Если добавить опцию '''-p''',
+то вместо идентификаторов заданий печатаются идентификаторы процессов (PID).
+
+ $ '''jobs -p'''
+ 31408
+ $
+
+Знак «+» после номера задания (в выводе ``jobs``) обозначает задание,
+на которое команды ''bg'' и ''fg'' действуют по умолчанию.
+В интерактивной оболочке любую команду,
+выполняющуюся интерактивно,
+можно перевести в фоновый режим последовательностью Сtrl+Z с клавиатуры терминала.
+Пользователь командами оболочки может перевести в фон (''bg'') или интерактивный режим (''fg'') любую команду из списка заданий.
+
+ $ '''jobs'''
+ [1]+ Running		  tar xf archive.tar
+ $ '''fg 1'''
+ tar xf archive.tar
+ <''Ctrl+Z''>
+ [1]+ Stopped		  tar xf archive.tar
+ $
+
+
+- Переменные
 
 Переменная — это именованый параметр, который хранит значение.
 Для раскрытия переменной в оболочке используется символ доллара ($),
@@ -116,6 +184,13 @@
  apple
  $
 
+Присвоить сразу нескольким переменным значения списком можно разделив их пробелами так:
+
+ $ '''name=Yuri surname=Gagarin'''
+ $ '''echo $name $surname'''
+ Yuri Gagarin
+ $
+
 Имя переменной в shell должно начинаться с буквы (строчной или прописной) или
 символа подчёркивания (_).
 После первого символа в имени переменой
@@ -136,145 +211,363 @@
  orange
  $
 
--- Перенаправление ввода-вывода
+-- Подробнее о переменных
 
-Большинство команд печатают вывод на терминал и читают ввод с его клавиатуры.
-В качестве устройства ввода и вывода в Unix может выступать любой файл.
-Оболочка может перенаправить вывод оператором перенаправления (>) в любой файл по желанию пользователя.
+Если рядом с раскрываемой переменной слитно без пробелов расположены другие символы, то раскрывать переменную безопаснее заключив её имя в фигурные скобки ({...}). В таком случае оболочка может определить где начинается и заканчивается её имя.
 
- $ '''echo "hello, world" >hello'''
- $ '''cat hello'''
- hello, world
+ $ suffix=new
+ $ mv myfile${suffix} myfileold
+
+Раскрываемая переменная может быть изменена ещё несколькими способами, перечислим их ниже:
+
+	``${parameter꞉-''word''}``  :  Использовать значение по умолчанию. Если переменная не установлена или пустая (null), то оболочка раскрывает ''word'' и подставляет его значение вместо переменной.
+	``${parameter꞉=''word''}``  :  Присвоить значение по умолчанию. Если переменная не установлена или пустая (null), то оболочка раскрывает ''word'' и присваивает его значение переменной. Результатом раскрытия всегда будет переменная.
+	``${parameter꞉?'''['''''word''''']'''}``  :  Напечатать ошибку и завершиться если переменная не установлена или пустая. Если переменная не установлена или пустая, то оболочка раскрывает ''word'' и печатает его на стандартный вывод ошибок а затем завершается (exit) с ненулевым кодом; иначе подставляется значение переменной. Здесь пара квадратных скобок «[…]» обозначает, что ''word'' может отсутствовать. Интерактивная оболочка не завершается.
+	``${parameter꞉+''word''}``  :  Использовать альтернативное значение. Если переменная не установлена или пустая, то подставляется пустая переменная; в противном случае оболочка раскрывает ''word'' и подставляет его.
+
+Если в раскрытии переменной двоеточие (:) используется, то в таком случае оболочка проверяет её и на существование и на пустое значение (null); если же двоеточие опустить, то проверяется только существование.
+
+Оболочка имеет некоторые встроенные средства для манипуляции со строками, перечислим их ниже:
+
+	``${#parameter}``  :  Длина строки. Длина в символах значения переменной.
+
+Следующие способы раскрытия переменной некоторым образом обрабатывают её с использованием ''шаблонов оболочки'' (''shell patterns''); нельзя их путать с регулярными выражениями.
+
+	``${parameter%''word''}``  :  Удаляет наименьшее из совпадений с шаблоном в конце строки. Оболочка раскрывает ''word'' и интерпретирует его как шаблон. Шаблон сопоставляется со значением переменной начиная с конца; наименьшая совпавшая часть удаляется.
+	``${parameter%%''word''}``  :  Удаляет наибольшее из совпадений с шаблоном в конце строки. Оболочка раскрывает ''word'' и интерпретирует его как шаблон. Шаблон сопоставляется со значением переменной начиная с конца; наибольшая совпавшая часть удаляется.
+	``${parameter#''word''}``  :  Удаляет наименьшее из совпадений с шаблоном в начале строки. Оболочка раскрывает ''word'' и интерпретирует его как шаблон. Шаблон сопоставляется со значением переменной начиная с первого символа; наименьшая совпавшая часть удаляется.
+	``${parameter##''word''}``  :  Удаляет наибольшее из совпадений с шаблоном в начале строки. Оболочка раскрывает ''word'' и интерпретирует его как шаблон. Шаблон сопоставляется со значением переменной начиная с первого символа; наибольшая совпавшая часть удаляется.
+
+Примеры удаления суффиксов:
+
+    $ '''f=src.c'''
+    $ '''echo ${f%.c}.o'''
+    src.o
+    $
+
+    $ '''dir=usr/src/lib'''
+    $ '''echo ${dir%%/*}'''
+    usr
+    $
+
+Примеры удаления префиксов:
+
+    $ '''dir=$TMPDIR/save/tape'''
+    $ '''echo ${dir#$TMPDIR}'''
+    /save/tape
+    $
+
+    $ '''dir=/very/long/path'''
+    $ '''echo ${dir##*/}'''
+    path
+    $
+
+-- Подстановка команд
+
+Команду заключённую в 
+
+ $(command)
+
+или
+
+ `command`
+
+оболочка заменяет на текст полученный со стандартного вывода команды.
+Например, если текущая дата это
+
+ $ '''date +%Y%m%d'''
+ 20150315
  $
 
-При перенаправлении shell удаляет старое содержимое из файла.
-Если нужно добавить вывод в конец к существующему содержимому,
-тогда используют оператор «>>», как в следующем примере:
+то команда
 
- $ '''echo "goodby, world" >> hello'''
- $ '''cat hello'''
- hello, world
- goodby, world
+ $ cp notes.log notes_$(date +%Y%m%d).log
+
+то же самое, что и
+
+ $ cp notes.log notes_20150315.log
+
+-- Арифметические подстановки
+
+Выражение заключённое в
+
+ $((expression))
+
+оболочка заменяет на значение выражения и подставляет его как текст.
+В выражении могут быть использованы арифметические, битовые и логические операторы,
+такие же как в языке Си.
+Внутреннее представление чисел — длинный тип со знаком (long int).
+Константы в выражении допускаются как десятичные так и 8- и 16-ричные.
+
+  i=0
+  while [ $i -lt 20 ]; do
+    printf '%d\n' $i
+    i=$((i+1))
+  done
+
+- Экранирование через "..." и '...'
+
+Разбиение строк на слова — полезная функция оболочки.
+Оболочка даёт возможность предотвратить разбиение,
+если у пользователя есть такая нужда.
+Предположим, переменной нужно присвоить значение с пробелом.
+Для этого придётся предотвратить разбиение,
+заключив присваиваемое значение в апострофы (’),
+иначе слово после пробела будет интерпретировано оболочкой как команда:
+
+ $ '''city=Saint Petersburg'''
+ Petersburg: command not found
+ $ '''city=’Saint Petersburg’'''
+ $ '''echo $city'''
+ Saint Petersburg
  $
 
--- Программные каналы
+В Unix имя файла может содержать любые символы, кроме
+слэша (/) и нулевого байта (NUL в ASCII).
+Если пользователь создал файл с именем ''my file'',
+то для его удаления тоже нужно предотвратить разбиение на слова:
+
+ $ '''rm my file'''
+ rm: cannot remove ‘my’: No such file or directory
+ rm: cannot remove ‘file’: No such file or directory
+ $ '''rm ’my file’'''
+ $
 
-Одно из главных достижений UNIX — программные каналы.
-Они позволяют подать вывод одной программы на вход другой без временных файлов.
-Несколько программ, соединённых таким способом, называют ''конвеером'' (''pipeline'').
+Переменная может содержать команду:
 
- $ who | sort -k 1d | cut -d’ ’ -f1 | uniq | wc -l
+ $ '''command=’echo Nice day!’'''
+ $ '''$command'''
+ Nice day!
+ $
 
-Ввод в программу тоже может быть получен из файла, а не из терминала:
+После раскрытия переменной оболочка разбивает её на слова,
+но повторно уже не раскрывает слова как переменные.
+Иногда нужно предотвратить разбиение на слова,
+но при этом выполнить раскрытия переменных.
+Для этого переменную заключают в двойные кавычки ("):
 
- $ '''ls -1 > files'''
- $ '''wc -l < files'''
- 42
+ $ '''fruit=’red'''
+ '''apple’'''
+ $ '''echo $fruit'''
+ red apple
+ $ '''echo ’$fruit’'''
+ $fruit
+ $ '''echo "$fruit"'''
+ red
+ apple
  $
 
-В последнем случае можно было обойтись и без временного файла,
-воспользовавшись конвеером:
+Весьма распространено заблуждение,
+что кавычки отделяют слова в оболочке.
+Это не так,
+потому что кавычки «склеивают» в одно слово строки,
+заключённые в них,
+если между ними нет пробелов.
 
- $ '''ls -1 | wc -l'''
- 42
+ $ '''echo ’It’"’"’s not my fault!’'''
+ It’s not my fault!
  $
 
-------
+- Перенаправление ввода-вывода
+
+Оболочка организует для каждой запускаемой программы три открытых файла с каждым из которых связан свой номер дескриптора:
+
+	0  :  стандартный ввод;
+	1  :  стандартный вывод;
+	2  :  стандартный вывод ошибок.
+
+Если операторы перенаправления не использовались и оболочка запущена интерактивно, то все три дескриптора связываются с терминалом пользователя, который в свою очередь является файлом устройства. Путь к файлу устройства текущего терминала всегда можно узнать командой ''tty''.
 
-На этой странице будут собраны и разбиты на разделы практические приёмы использования оболочки (shell). Так как сама по себе оболочка является всего лишь тонким «клеем» для объединения программ и файлов в новые инструменты (через конвеер и перенаправление ввода-вывода), в этот раздел будут помещены ссылки на другие вики-страницы, где описаны приёмы работы с прочими классическими утилитами Unix.
+ $ '''tty'''
+ /dev/pts/1
+ $ 
 
+Операторам перенаправления ввода-вывода номера дескрипторов могут быть указаны явно, но по умолчанию оболочка считает, что для операторов связанных с выводом используется дескриптор 1, а для операторов связанных с перенаправлением ввода используется дескриптор 0. Для перенаправления стандартного вывода ошибок номер приходится указывать явно.
 
+Большинство команд печатают на стандартный вывод и читают стандартный ввод с терминала.
+В ОС Unix и устройства (терминал, последовательный порт, программные каналы) и файлы (обычные файлы, именованные каналы) с точки зрения операций чтения-записи практически не отличаются.
 
--- Конвеер для работы с файлами
+Оболочка может перенаправить вывод оператором перенаправления вывода (>) в любой файл по желанию пользователя. Если файл не существует, то он будет создан оболочкой.
 
- $ find /etc -maxdepth 1 -type f | sort | ( echo cat ; cat ) | paste -s -d ' ' | sh >/tmp/all
+ $ '''echo "hello, world" >hello'''
+ $ '''cat hello'''
+ hello, world
+ $
+
+При перенаправлении shell удаляет старое содержимое из файла.
+Если нужно добавить вывод в конец к существующему содержимому,
+тогда используют оператор «>>», как в следующем примере:
+
+ $ '''echo "goodby, world" >>hello'''
+ $ '''cat hello'''
+ hello, world
+ goodby, world
+ $
 
------
+Ввод тоже можно перенаправить из файла. Для этого используют оператор перенаправления ввода (<). Для примера, предположим, мы вычисляем число π в калькуляторе ''bc'' интерактивно вводом с терминала.
 
-Я бы отдал предпочтение tr вместо paste, вот так:
+ $ '''bc -lq'''
+ '''scale=7; 4*a(1)'''⏎
+ 3.1415924
+ '''quit'''⏎
+ $
 
- $ find /etc -maxdepth 1 -type f | sort | { echo cat; cat; } | tr '\n' ' ' | sh >/tmp/all
+Мы можем поместить всё, что вводили с клавиатуры, в файл ''picalc.bc'' и перенаправить ввод из него.
 
-Здесь запуск подоболочки (subshell) заменён на блок (в фигурных скобках), так как преследовалась цель объединить последовательно вывод утилит echo и cat на стандартный вывод. Для этой цели подоболочку запускать расточительно.
+ $ '''echo 'scale=7; 4*a(1)' >picalc.bc'''
+ $ '''bc -lq <picalc.bc'''
+ 3.1415924
+ $
 
-Здесь есть ещё одна потенциальная проблема, она связана с тем, что в именаx файлов могут встречаться любые символы, кроме нулевого байта (NUL) и слеша (/). В имени файла может присутствовать символ новой строки (NL), в то же время find печатает список файлов, отделяя этим символом имена друг от друга. Если в имени файла содержится символ новой строки, тогда вывод find не отличим от двух файлов, следующих подряд.
+Конечно, ''bc'' может читать свои инструкции прямо из файлов, но нас интересовала возможность подмены клавиатурного ввода перенаправлением. Любая программа, которая читает со стандартного ввода, может получить его из файла через перенаправление, организованное средствами оболочки.
 
-Если используются утилиты GNU, то следует воспользоваться расширением, которое заменяет символ разделителя в списке файлов, выводимом find:
+Довольно часто встречается надобность (особенно в сценариях) в подавлении вывода чрезмерно болтливой команды. Для этого перенаправляют вывод в специальное устройство ''/dev/null''; любой байт записанный в него исчезает навсегда.
 
- $ find /etc -maxdepth 1 -type f -print0 | sort -z | xargs -0 cat >/tmp/all
+ $ grep '^root:' /etc/passwd >/dev/null
 
-Здесь find выводит имена файлов разделяя их не символом новой строки, а нулевым байтом (NUL). В этом случае все утилиты конвеера должны понимать это соглашение, например, GNU sort и GNU xargs умеют обрабатывать списки файлов с таким разделителем. -- СиткаревГригорий
-----
+- Дублирование дескрипторов ввода-вывода
 
--- Фильтр sed
+Дескрипторы открытых файлов могут дублироваться или закрываться средствами оболочки. Команда дублирования дескриптора файла ввода в общем виде выглядит так:
 
- $ echo "abcabc" | sed 's/\(.*\)\(\1\)/\1#\2/'
- abc#abc
+ [''n'']<&''word''
 
-В данном примере в регулярном выражении используется backreference. Регулярное выражение состоит из двух групп выделенных круглыми скобками. Первой группе соотвествует любой набор символов .*, во второй группе используется backreference \1 (отсыл на первое выражение), при чем эта группа выделит выражение идентичное первому. В выводе мы адресуем группы как \1 и \2 и разделяем их символом #.
+где ''n'' — номер дескриптора (может отсутствовать, тогда подразумевается 0) куда будет дублирован  дескриптор для ввода, указанный в ''word'' явно или как выражение, раскрываемое оболочкой (может быть переменной или подстановкой). Символ амперсанда (&) позволяет отличить номер дескриптора от файла с таким же именем. Если вместо номера дескриптора при раскрытии ''word'' получен «-», то тогда открытый файл, связанный с дескриптором ''n'', закрывается.
 
---- sed как язык программирования
+Точно так работает дублирование дескриптора для ввода.
 
-На сегодняшний день sed в основном испозуется для замены или выделения выражений из входных данных. Но этот инструмент намного мощнее. sed это небольшой язык программирования со своей средой исполнения.
+ [''n'']<&''word''
 
-Далее текст можно рассматривать как небольшое введение по программированию на sed.
+Идиоматическим приёмом в оболочке является полное подавление вывода команды путём перенаправления стандартного вывода (дескриптор 1) в ''/dev/null'' с последующим дублированием в дескриптор стандартного вывода ошибок (дескриптор 2).
 
-sed имеет два буфера, первый -- pattern буфер -- это входной буфер, он заполняется автоматически при обработке входных данных (или принудительно смотри команды n, N), второй -- hold буфер -- буфер хранения, данные в этот буфер могут попасть только по вызову специальной команды (смотри команды h, H). Пользователь может копировать, добавлять данные из одного буфера в другой, обменивать их содержимым друг с другом.
+ $ grep '^root:' /etc/passwd >/dev/null 2>&1
 
-Команды могут объединяться в группы фигурными скобками:
- { action1; action2... }
-а так же выполняться с условием, подобно ЯзыкAWK:
- condition { action }
+Перенаправление оболочка организует в том же порядке (слева направо) как это пользователь указал в команде, поэтому порядок операторов перенаправления важен.
 
-где условие (condition) может быть регулярным выражением, номером строки или диапазоном строк.
+Пользователь может закрыть, предположим, дескриптор 2 и запустить команду так:
 
-Напечатать на экран строки с 5-ой по 8-ую:
+ $ cat /tmp/xxx 2<&-
 
- $ sed -n '5,8p' < /etc/passwd
+Естественно, что никакого вывода об ошибках, даже если файл '/tmp/xxx' отсутствует, напечатано не будет, так как у запущенного ''cat'' дескриптор 2 будет закрыт и любая попытка записи в него приведёт к ошибке. Любопытным пользователям можно попробовать запустить эту команду через ''strace'' или любой другой трассировщик системных вызовов:
 
-''p'' -- печатает содержимое pattern буфера.
+ $ strace sh -c 'exec cat /tmp/xxx 2<&-'
 
-Напечатать на экран лог ошибки сервера Apache за определенный период:
+Очевидно, что закрывать любые из трёх стандартных дескрипторов не следует за исключением редких случаев, когда пользователь действительно понимает зачем он это делает.
 
- $ sed -n '/^\[.*Feb 08/,/^\[.*Feb 10/p' < /var/log/apache2/error.log
+- Программные каналы
 
-''/regexp1/,/regexp2/'' -- условие задается двумя регулярными выражениями -- начальной и конечной датой.
+Одно из главных достижений Unix — программные каналы.
+Они позволяют подать вывод одной программы на вход другой без временных файлов.
+Несколько программ, соединённых таким способом, называют ''конвеером'' (''pipeline'').
+Например, вывод программа может перенаправить в файл и получить через перенаправление из файла:
 
-Удалить все закоментированные и пустые строки:
+ $ '''ls -1 >files'''
+ $ '''wc -l <files'''
+ 42
+ $
 
- $ sed -e '/^ *#/d' -e '/^$/d' </etc/ssh/sshd_config
+В предыдущем примере файл ''files'' использовался для временного хранения ввода-вывода.
+Оболочка позволяет обойтись без временного файла,
+соединив программы конвеером:
 
-''d'' -- удаляет pattern буфер, если условие верно, /^ *#/ строка с коментариями, /^$/ пустая строка, переходит к следующему циклу чтения, все последующие команды '''игнорируются'''.
+ $ '''ls -1 | wc -l'''
+ 42
+ $
 
-Следующий пример будет сложнее:
+Конвеер может состоять из множества программ. Символ «|» фактически означает, что оболочка должна соединить стандартный вывод команды слева и стандартный ввод команды справа программным каналом (pipe). Команда расположенная справа в таком случае фильтрует вывод предыдущей команды, а потому её часто называют фильтром. Многие программы в Unix являются фильтрами, например, ''sed'', ''grep'', ''awk'', ''tr'' — фильтры.
 
- $ sed -n 'H;${x;s/\n/ /g;p}' < /etc/passwd
+По сути конвеер — способ организовать перенаправление ввода-вывода и
+его можно рассматривать как своеобразный оператор перенаправления,
+который действует на окружение команды до прочих операторов перенаправления,
+поэтому дублирование дескриптора программного канала делают так:
 
-''H'' -- добавляет все входные строки из pattern буфер к данным в hold буфер, таким образом, мы накапливаем все входные строки в буфере хранения;
+ $ ls -1 2>&1 | wc -l
 
-''${ ... }'' -- $ означает последнюю строку, т.е все действия в фигурных скобках выполняться только при обработке последней строки;
+Здесь в дескриптор стандартного вывода ошибок дублируется дескриптор программного канала, соединённый с ``wc -l``. Таким образом и стандартный вывод и стандартный вывод ошибок из ``ls -1`` попадёт в конвеер и будет передан следующей команде.
 
-''x'' -- обменивает содержимое hold буфера с содержимым pattern буфера, т.е все накопленные данные перемещаются из hold в ptatern буфер, а из pattern в hold буфер;
+- Группировка команд
 
-''s/\n/ /g'' -- команда замены в pattern буфере, где теперь находятся все наши строки, меняем символ переноса -- пробелом (g делаем это глобально, для всех \n);
+Команды в оболочке могут быть сгруппированы двумя способами:
 
-''p'' -- печатает pattern буфер. Все строки теперь объеденены в одну.
+ { cmd₁; cmd₂; ..., cmdₙ; }
 
-Слегка расширим предыдущий пример.
+или
 
- $ sed -n '1h;1!H;${x;s/\n/ /g;p}' < /etc/passwd
+ ( cmd₁; cmd₂; ..., cmdₙ )
 
-''1h'' -- первую строку копируем в hold буфер;
+В первом случае
+группировка предназначена для перенаправления вывода группы команд так как будто это одна команда.
 
-''1!H'' -- все входные строки кроме первой добавляем в hold буфер, т.е дописываем к уже имеющимся в нем данным, ! знак инвертирования условия, в нашем случаи оно выполняется для всех строк '''кроме''' первой.
+ $ { echo 'Header'; echo 'Body'; echo 'Footer'; } >output.txt
 
-В остальном скрипт повторяет предыдущий.
+Наличие знака «;» в конце списка команд обязательно,
+так как без него оболочка затрудняется определить где он заканчивается.
 
-Стоит отметить, что накопление значительных объемов данных может привести к '''переполнению''' внутренних буферов sed. Этого не должно произойти при использовании GNU sed.
+Во втором случае запуск команд происходит в ''подоболочке'' (''subshell'').
+Не смотря на то, что подоболочка является отдельным процессом,
+значение встроенной переменной ''$''
+хранящей идентификатор процесса (PID) будет совпадать с родительской.
 
--- Литература
+ $ '''echo $$'''
+ 1025
+ $ '''( echo $$ )'''
+ 1025
+ $
 
+Так как список команд в этом случае запускается в отдельном процессе,
+его окружение можно модифицировать как угодно без влияния на родительскую оболочку.
+Например,
+копирование иерархии каталогов из ''/home/user'' в ''/tmp/dump'' можно осуществить следующим образом:
+
+ $ ( cd /home/user; tar cf - . ) | ( cd /tmp/dump; tar xf - )
+
+Так как смена текущего каталога происходит в подоболочке,
+то она не затрагивает окружения основной оболочки,
+иначе пришлось бы сохранять текущий каталог до запуска копирования и восстанавливать его после.
+
+- Шаблоны имён файлов
+
+Символы «?», «*» и «\[» имеют специальное назначение.
+Когда оболочка встречает такие символы в аргументе команды (вне кавычек),
+то аргумент интерпретируются как шаблон имён файлов.
+Оболочка пытается найти подходящие под шаблон имена файлов (выполняет раскрытие шаблона),
+а затем подставляет список имён (через пробел) вместо него.
+Для отмены действия символа перед ним ставят обратный слэш (\).
+
+ 	``ls /etc/*.conf``  :  Вывести имена файлов из /etc, заканчивающиеся на «.conf».
+ 	``ls *.[ch]``  :  Вывести имена файлов, заканчивающиеся на «.c» и «.h».
+ 	``ls j?nk``  :  Вывести имена файлов с любым символом вместо ?.
+ 	``cat j\?nk``  :  Вывести на терминал файл с именем j?nk.
+ 	``ls /var/run/[!abc]*.pid``  :  Вывести имена файлов из /var/run, начинающиеся на любой символ, исключая символы abc, и заканчивающиеся на «.pid».
+
+Если файлы с именами, подходящими под шаблон, не существуют, то оболочка подставляет
+сам шаблон буквально.
+
+-- Замечания по раскрытию шаблонов
+
+Символ слэш (/) не может быть частью шаблона при раскрытии путей,
+потому что является ''разделителем пути'' (''path separator'').
+Если слэш присутствует в шаблоне,
+то он разделяет шаблон на части,
+где каждая часть задаёт шаблон для совпадения в дереве каталогов.
+Поиск файлов производится оболочкой только на явно указанной глубине дерева файловой системы.
+Если ни одного слэша в шаблоне нет,
+то оболочка ищет имена файлов только в текущем каталоге.
+
+Метасимвол «*» при раскрытии путей никогда не даёт совпадений с именами файлов,
+начинающихся с точки.
+Это связано с тем, что в Unix традиционно файлы,
+имя которых начиналось с точки, считались скрытыми.
+По этой причине они и не попадают в шаблон «*».
+Если такие файлы должны давать совпадение с шаблоном,
+тогда точку нужно указывать явно.
+В шаблон «.*» при раскрытии путей всегда попадут текущий и родительский каталоги.
+
+- Литература
+	1 Kernighan, B. W. Software tools in Pascal / B. W. Kernighan, P. J. Plauger. — Addison-Wesley Longman Publishing Co., Inc., 1981.
+	1 Bourne, S. R. An Introduction to the UNIX Shell / S. R. Bourne. — Bell Laboratories. Computing Science, 1978.
 	1 Peek, J. Unix Power Tools / Jerry Peek, Shelley Powers, Tim O'Reilly, Mike Loukides. — 3rd ed. — O'Reilly Media, October 2002.
+	1 Seebach, P. Beginning Portable Shell Scripting: From Novice to Professional / Peter Seebach. — Apress, 2008.
 	1 The Open Group Base Specifications Issue 7 [Электронный ресурс] : Shell Command Language / The IEEE and The Open Group. — IEEE Std 1003.1, 2013 Edition. — 2013. — Режим доступа: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html, свободный.
 
-# КатегорияОболочки | КатегорияЯзыкиПрограммирования
+
+# КатегорияЯзыкиПрограммирования | КатегорияОболочки