Разница между 1.93 и текущей версией ОболочкаShell.
@@ -1,6 +1,4 @@
-- Оболочка shell
-
--- Кратко о программируемой оболочке
+= Оболочка shell
 
 Программируемая оболочка интерпретирует команду и выполняет её. Оболочка shell предназначена для манипуляции с:
 	1 данными — строчно-ориентированная обработка;
@@ -11,7 +9,7 @@
 Она не является частью ядра.
 Перечислим значимые особенности и возможности оболочки:
 	* Оболочка раскрывает шаблоны имён файлов. Shell находит совпадающие с шаблоном имена файлов, формирует из них список и выполняет подстановку в аргументы команды. Команды Unix, используемые в оболочке, не обязаны уметь раскрывать шаблоны, так как этим занимается сама оболочка.
-	* Оболлочка организует перенаправление ввода-вывода. Любая программа, запускаемая в оболочке, может вводить данные из файлов и выводить их в файл, а не через терминал. Программы могут быть соединены посредством ''программных каналов'' (''pipes'') в конвеер;
+	* Оболочка организует перенаправление ввода-вывода. Любая программа, запускаемая в оболочке, может вводить данные из файлов и выводить их в файл, а не через терминал. Программы могут быть соединены посредством ''программных каналов'' (''pipes'') в конвеер;
 	* Оболочка предоставляет настраиваемые переменные окружения (environment variables), псевдонимы команд (alias) и возможность организовывать часто выполняемые последовательности команд в функции.
 
 Архитектура расширений языка в оболочке shell беспрецедентно проста и
@@ -30,7 +28,27 @@
 когда расходы на сами операции
 (ввод-вывод, вычисления) существенно превышают расходы на создание новых процессов.
 
--- Интерактивный и неинтерактивный режимы
+-- Среда запуска команд
+
+Запускаемые программы наследуют окружение оболочки, а именно:
+
+	1 Открытые файлы и режим доступа (чтение, запись, чтение/запись). Средствами оболочки осуществляется перенаправление ввода-вывода, открытие и закрытие файлов (команда ''exec'').
+	1 Текущий каталог. Любая программа в Unix имеет свой текущий каталог. Смена текущего каталога в оболочке выполняется командой ''cd''.
+	1 Маску режима доступа для новых файлов. Оболочка может изменить маску на произвольную командой ''umask''.
+	1 Игнорируемые сигналы. Маска игнорируемых сигналов наследуется программами запускаемыми в оболочке.
+	1 Переменные окружения. Переменные окружения унаследованные от оболочки доступны программе через функцию стандартной библиотеки Си ''getenv''(3).
+
+Через наследование окружения оболочка организует взаимодействие программ друг с другом.
+Таким образом в Unix была реализована парадигма компонентного программирования  и повторного использования (в ответ на кризис программного обеспечения) задолго до того,
+как к ней обнаружился интерес в академической среде и появились реализации популярных ООП-языков.
+К сожалению,
+подход к решению задач в основу которого положены программы-фильтры и конвеер был проигнорирован в академической среде в угоду парадигме ООП.
+
+Специализированные утилиты из набора инструментария Unix следует рассматривать как ортогональные компоненты,
+где каждая программа отвечает за свою отдельную чётко определённую задачу.
+Программируя в оболочке пользователь получает новые инструменты «склеивая» и комбинируя существующий компактный набор типовых компонентов-программ.
+
+- Интерактивный и неинтерактивный режимы
 
 В интерактивном режиме оболочка сигнализирует
 о готовности принимать команды приглашением — символом доллара ($).
@@ -44,7 +62,7 @@
  world
  $
 
-В приведённом выше примере оболочка ожидает продолжения ввода после `’hello`,
+В приведённом выше примере оболочка ожидает продолжения ввода после ``’hello``,
 т. к. символ апострофа (’) обозначает начало экранируемой строки,
 и строка считается незавершённой,
 пока оболочка не встретит парный апостроф.
@@ -68,7 +86,7 @@
  $
 
 Второй способ — добавить путь к интерпретатору в сам файл.
-Для этого нужно первой строкой в файле поместить `#!/bin/sh`
+Для этого нужно первой строкой в файле поместить ``#!/bin/sh``
 и добавить разрешение на исполнение файла:
 
  $ chmod +x hello
@@ -80,6 +98,8 @@
  world
  $
 
+- Запуск команд
+
 -- Простые команды
 
 Оболочка выполняет преобразования с командами,
@@ -92,8 +112,8 @@
 последующие слова передаются как аргументы команде.
 Для трассировки изменений,
 вносимых оболочкой в команды,
-включают режим трассировки командой `set -x`,
-а выключают трассировку командой `set +x`.
+включают режим трассировки командой ``set -x``,
+а выключают трассировку командой ``set +x``.
 Несколько команд можно ввести в одну строку через разделитель (;).
 
  $ '''echo hello; echo world'''
@@ -103,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
+ $
+
+
+- Переменные
 
 Переменная — это именованый параметр, который хранит значение.
 Для раскрытия переменной в оболочке используется символ доллара ($),
@@ -142,21 +211,101 @@
  orange
  $
 
---- Подробнее о переменных
+-- Подробнее о переменных
 
 Если рядом с раскрываемой переменной слитно без пробелов расположены другие символы, то раскрывать переменную безопаснее заключив её имя в фигурные скобки ({...}). В таком случае оболочка может определить где начинается и заканчивается её имя.
 
  $ suffix=new
- $ mv myfile${suffix} myfile${suffix}old
+ $ mv myfile${suffix} myfileold
 
 Раскрываемая переменная может быть изменена ещё несколькими способами, перечислим их ниже:
 
-	`${param꞉-''word''}`: Использовать значение по умолчанию. Если переменная не установлена или пустая (null), то оболочка раскрывает ''word'' и подставляет его значение вместо переменной.
-	`${param꞉=word}`: Присвоить значение по умолчанию. Если переменная не установлена или пустая (null), то оболочка раскрывает ''word'' и присваивает его значение переменной. Результатом раскрытия всегда будет переменная.
-	`${param꞉?'''['''''word''''']'''}`: Напечатать ошибку и завершиться если переменная не установлена или пустая.  Если переменная не установлена или пустая, то оболочка раскрывает ''word'' и печатает его на стандартный вывод ошибок а затем завершается (exit) с ненулевым кодом. Иначе подставляется значение переменной. Интерактивная оболочка не завершается.
-	`${param꞉+word}`: Использовать альтернативное значение. Если переменная не установлена или пустая, то подставляется пустая переменная; в противном случае оболочка раскрывает ''word'' и подставляет его.
+	``${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
+ $
+
+то команда
+
+ $ 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
+
+- Экранирование через "..." и '...'
 
 Разбиение строк на слова — полезная функция оболочки.
 Оболочка даёт возможность предотвратить разбиение,
@@ -219,13 +368,13 @@
  It’s not my fault!
  $
 
--- Перенаправление ввода-вывода
+- Перенаправление ввода-вывода
 
 Оболочка организует для каждой запускаемой программы три открытых файла с каждым из которых связан свой номер дескриптора:
 
-	0 : стандартный ввод;
-	 1 : стандартный вывод;
-	2 : стандартный вывод ошибок.
+	0  :  стандартный ввод;
+	1  :  стандартный вывод;
+	2  :  стандартный вывод ошибок.
 
 Если операторы перенаправления не использовались и оболочка запущена интерактивно, то все три дескриптора связываются с терминалом пользователя, который в свою очередь является файлом устройства. Путь к файлу устройства текущего терминала всегда можно узнать командой ''tty''.
 
@@ -276,7 +425,7 @@
 
  $ grep '^root:' /etc/passwd >/dev/null
 
--- Дублирование дескрипторов ввода-вывода
+- Дублирование дескрипторов ввода-вывода
 
 Дескрипторы открытых файлов могут дублироваться или закрываться средствами оболочки. Команда дублирования дескриптора файла ввода в общем виде выглядит так:
 
@@ -304,7 +453,7 @@
 
 Очевидно, что закрывать любые из трёх стандартных дескрипторов не следует за исключением редких случаев, когда пользователь действительно понимает зачем он это делает.
 
--- Программные каналы
+- Программные каналы
 
 Одно из главных достижений Unix — программные каналы.
 Они позволяют подать вывод одной программы на вход другой без временных файлов.
@@ -333,9 +482,9 @@
 
  $ ls -1 2>&1 | wc -l
 
-Здесь в дескриптор стандартного вывода ошибок дублируется дескриптор программного канала, соединённый с `wc -l`. Таким образом и стандартный вывод и стандартный вывод ошибок из `ls -1` попадёт в конвеер и будет передан следующей команде.
+Здесь в дескриптор стандартного вывода ошибок дублируется дескриптор программного канала, соединённый с ``wc -l``. Таким образом и стандартный вывод и стандартный вывод ошибок из ``ls -1`` попадёт в конвеер и будет передан следующей команде.
 
--- Группировка команд
+- Группировка команд
 
 Команды в оболочке могут быть сгруппированы двумя способами:
 
@@ -375,25 +524,25 @@
 то она не затрагивает окружения основной оболочки,
 иначе пришлось бы сохранять текущий каталог до запуска копирования и восстанавливать его после.
 
--- Шаблоны имён файлов
+- Шаблоны имён файлов
 
-Символы «?», «*» и «[» имеют специальное назначение.
+Символы «?», «*» и «\[» имеют специальное назначение.
 Когда оболочка встречает такие символы в аргументе команды (вне кавычек),
 то аргумент интерпретируются как шаблон имён файлов.
 Оболочка пытается найти подходящие под шаблон имена файлов (выполняет раскрытие шаблона),
 а затем подставляет список имён (через пробел) вместо него.
 Для отмены действия символа перед ним ставят обратный слэш (\).
 
- 	`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».
+ 	``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'').
@@ -413,107 +562,12 @@
 тогда точку нужно указывать явно.
 В шаблон «.*» при раскрытии путей всегда попадут текущий и родительский каталоги.
 
--- Литература
+- Литература
+	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, свободный.
 
 
-
-
-
-
-----
-На этой странице будут собраны и разбиты на разделы практические приёмы использования оболочки (shell). Так как сама по себе оболочка является всего лишь тонким «клеем» для объединения программ и файлов в новые инструменты (через конвеер и перенаправление ввода-вывода), в этот раздел будут помещены ссылки на другие вики-страницы, где описаны приёмы работы с прочими классическими утилитами Unix.
-
-
-
--- Конвеер для работы с файлами
-
- $ find /etc -maxdepth 1 -type f | sort | ( echo cat ; cat ) | paste -s -d ' ' | sh >/tmp/all
-
------
-
-Я бы отдал предпочтение tr вместо paste, вот так:
-
- $ find /etc -maxdepth 1 -type f | sort | { echo cat; cat; } | tr '\n' ' ' | sh >/tmp/all
-
-Здесь запуск подоболочки (subshell) заменён на блок (в фигурных скобках), так как преследовалась цель объединить последовательно вывод утилит echo и cat на стандартный вывод. Для этой цели подоболочку запускать расточительно.
-
-Здесь есть ещё одна потенциальная проблема, она связана с тем, что в именаx файлов могут встречаться любые символы, кроме нулевого байта (NUL) и слеша (/). В имени файла может присутствовать символ новой строки (NL), в то же время find печатает список файлов, отделяя этим символом имена друг от друга. Если в имени файла содержится символ новой строки, тогда вывод find не отличим от двух файлов, следующих подряд.
-
-Если используются утилиты GNU, то следует воспользоваться расширением, которое заменяет символ разделителя в списке файлов, выводимом find:
-
- $ find /etc -maxdepth 1 -type f -print0 | sort -z | xargs -0 cat >/tmp/all
-
-Здесь find выводит имена файлов разделяя их не символом новой строки, а нулевым байтом (NUL). В этом случае все утилиты конвеера должны понимать это соглашение, например, GNU sort и GNU xargs умеют обрабатывать списки файлов с таким разделителем. -- СиткаревГригорий
-----
-
--- Фильтр sed
-
- $ echo "abcabc" | sed 's/\(.*\)\(\1\)/\1#\2/'
- abc#abc
-
-В данном примере в регулярном выражении используется backreference. Регулярное выражение состоит из двух групп выделенных круглыми скобками. Первой группе соотвествует любой набор символов .*, во второй группе используется backreference \1 (отсыл на первое выражение), при чем эта группа выделит выражение идентичное первому. В выводе мы адресуем группы как \1 и \2 и разделяем их символом #.
-
---- sed как язык программирования
-
-На сегодняшний день sed в основном испозуется для замены или выделения выражений из входных данных. Но этот инструмент намного мощнее. sed это небольшой язык программирования со своей средой исполнения.
-
-Далее текст можно рассматривать как небольшое введение по программированию на sed.
-
-sed имеет два буфера, первый -- pattern буфер -- это входной буфер, он заполняется автоматически при обработке входных данных (или принудительно смотри команды n, N), второй -- hold буфер -- буфер хранения, данные в этот буфер могут попасть только по вызову специальной команды (смотри команды h, H). Пользователь может копировать, добавлять данные из одного буфера в другой, обменивать их содержимым друг с другом.
-
-Команды могут объединяться в группы фигурными скобками:
- { action1; action2... }
-а так же выполняться с условием, подобно ЯзыкAWK:
- condition { action }
-
-где условие (condition) может быть регулярным выражением, номером строки или диапазоном строк.
-
-Напечатать на экран строки с 5-ой по 8-ую:
-
- $ sed -n '5,8p' < /etc/passwd
-
-''p'' -- печатает содержимое pattern буфера.
-
-Напечатать на экран лог ошибки сервера Apache за определенный период:
-
- $ sed -n '/^\[.*Feb 08/,/^\[.*Feb 10/p' < /var/log/apache2/error.log
-
-''/regexp1/,/regexp2/'' -- условие задается двумя регулярными выражениями -- начальной и конечной датой.
-
-Удалить все закоментированные и пустые строки:
-
- $ sed -e '/^ *#/d' -e '/^$/d' </etc/ssh/sshd_config
-
-''d'' -- удаляет pattern буфер, если условие верно, /^ *#/ строка с коментариями, /^$/ пустая строка, переходит к следующему циклу чтения, все последующие команды '''игнорируются'''.
-
-Следующий пример будет сложнее:
-
- $ sed -n 'H;${x;s/\n/ /g;p}' < /etc/passwd
-
-''H'' -- добавляет все входные строки из pattern буфер к данным в hold буфер, таким образом, мы накапливаем все входные строки в буфере хранения;
-
-''${ ... }'' -- $ означает последнюю строку, т.е все действия в фигурных скобках выполняться только при обработке последней строки;
-
-''x'' -- обменивает содержимое hold буфера с содержимым pattern буфера, т.е все накопленные данные перемещаются из hold в ptatern буфер, а из pattern в hold буфер;
-
-''s/\n/ /g'' -- команда замены в pattern буфере, где теперь находятся все наши строки, меняем символ переноса -- пробелом (g делаем это глобально, для всех \n);
-
-''p'' -- печатает pattern буфер. Все строки теперь объеденены в одну.
-
-Слегка расширим предыдущий пример.
-
- $ sed -n '1h;1!H;${x;s/\n/ /g;p}' < /etc/passwd
-
-''1h'' -- первую строку копируем в hold буфер;
-
-''1!H'' -- все входные строки кроме первой добавляем в hold буфер, т.е дописываем к уже имеющимся в нем данным, ! знак инвертирования условия, в нашем случаи оно выполняется для всех строк '''кроме''' первой.
-
-В остальном скрипт повторяет предыдущий.
-
-Стоит отметить, что накопление значительных объе�
-
-Продолжение следует ...
+# КатегорияЯзыкиПрограммирования | КатегорияОболочки