помещается в файл "file_4".
Средство, объединяющее стандартный выход одной команды со стандартным входом
другой, называется КОНВЕЙЕРОМ и обозначается вертикальной чертой "".
ls wc -l
список файлов текущего каталога будет направлен на вход команды "wc", которая на
экран выведет число строк каталога.
Конвейером можно объединять и более двух команд, когда все они, возможно кроме
первой и последней - фильтры:
cat file_1 grep -h result sort cat -b > file_2
Данный конвейер из файла "file_1" ("cat") выберет все строки, содержащие слово
"result" ("grep"), отсортирует ("sort") полученные строки, а затем пронумерует
("cat -b") и выведет результат в файл "file_2".
Поскольку устройства в ОС UNIX представлены специальными файлами, их можно
использовать при перенаправлениях. Специальные файлы находятся в каталоге
"/dev". Например, "lp" - печать; "console" - консоль; "ttyi" - i-ый терминал;
"null"- фиктивный (пустой) файл (устройство).
Тогда, например,
ls > /dev/lp
выведет содержимое текущего каталога на печать, а
file_1 < /dev/null
обнулит файл "file_1".
sort file_1 tee /dev/lp tail -20
В этом случае будет отсортирован файл "file_1" и передан на печать, а 20
последних строк также будут выданы на экран.
Вернемся к перенаправлению выхода. Стандартные файлы имеют номера:
0 - stdin,
1 - stdout
2 - stderr.
Если вам не желательно иметь на экране сообщение об ошибке, вы можете
перенаправить его с экрана в указанный вами файл (или вообще "выбросить",
перенаправив в файл "пустого устройства" - /dev/null). Например при выполнении
команды
cat file_1 file_2
которая должна выдать на экран последовательно содержимое файлов "file_1" и
"file_2", выдаст вам, например, следующее
111111 222222
cat: f2: No such file or directory
где 111111 222222 - содержимое файла "file_1", а файл "file_2" отсутствует, о
чем команда "cat" выдала сообщение в стандартный файл диагностики, по умолчанию,
как и стандартный выход, представленный экраном.
Если вам не желательно такое сообщение на экране, его можно перенаправить в
указанный вами файл:
cat file_1 file_2 2>f-err
сообщения об ошибках будут направляться (об этом говорит перенаправление "2>") в
файл "f-err". Кстати, вы можете всю информацию направлять в один файл "ff",
использовав в данном случае конструкцию
cat file_1 file_2 >>ff 2>ff
Можно указать не только какой из стандартных файлов перенаправлять, но и в какой
стандартный файл осуществить перенаправление.
cat file_1 file_2 2>>ff 1>&2
Здесь сначала "stderr" перенаправляется (в режиме добавления) в файл "ff", а
затем стандартный выход перенаправляется на "stderr", которым к этому моменту
является файл "ff". То есть результат будет аналогичен предыдущему.
Конструкция "1>&2" - означает, что кроме номера стандартного файла, в который
перенаправить, необходимо впереди ставить "&"; вся конструкция пишется без
пробелов.
<- закрывает стандартный ввод.
>- закрывает стандартный вывод.
2.4. Командные файлы.
Для того, чтобы текстовый файл можно было использовать как команду, существует
несколько возможностей.
Пусть с помощью редактора создан файл с именем "cmd", содержащий одну строку
следующего вида:
date; pwd; ls
Можно вызвать shell как команду, обозначаемую "sh", и передать ей файл "cmd",
как аргумент или как перенаправленный вход, т.е.
$ sh cmd
или
$ sh <cmd
В результате выполнения любой из этих команд будет выдана дата, затем имя
текущего каталога, а потом содержимое каталога.
Более интересный и удобный вариант работы с командным файлом - это превратить
его в выполняемый, т.е. просто сделать его командой, что достигается изменением
кода защиты. Для этого надо разрешить выполнение этого файла.
Например,
chmod 711 cmd
сделает код защиты "rwx__x__x". Тогда простой вызов
cmd
приведет к выполнению тех же трех команд.
Результат будет тот же, если файл с содержимым
date; pwd; ls
представлен в виде:
date
pwd
ls
так как переход на другую строку также является разделителем в
последовательности команд.
Таким образом, выполняемыми файлами могут быть не только файлы, полученные в
результате компиляции и сборки, но и файлы, написанные на языке shell. Их
выполнение происходит в режиме интерпретации с помощью shell-интерпретатора
2.5 Отладка командных файлов
В SHELL используются два механизма отладки командных файлов.
Первый из них: set -v выводит строки командного файла по мере их чтения. Этот
режим применяется при поиске синтаксических ошибок. Для его использования не
требуется производить модификацию командного файла, например:
sh -v proc... здесь proc - имя командного файла. Ключ -v может использоваться
вместе с ключом -n, предотвращающим выполнение следующих за ним команд (команда
set -n блокирует терминал до тех пор, пока не вводится признак конца файла EOF).
Команда set -х выводит команды по мере их выполнения, причём на терминал
выводятся строки программы и на место переменных подставляются их значения. Для
отмены ключей -x и -v можно воспользоваться командой set - а для установки -
присвоить соответствующее значение макропеременной.
3. СРЕДА SHELL (ПЕРЕМЕННЫЕ И ПАРАМЕТРЫ)
На языке shell можно писать командные файлы и с помощью команды "chmod" делать
их выполняемыми. После этого они ни чем не отличаются от прочих команд ОС UNIX.
3.1. shell-переменные
Имя shell-переменной - это начинающаяся с буквы последовательность букв, цифр и
подчеркиваний.
Значение shell-переменной - строка символов.
То, что в shell всего два типа данных: строка символов и текстовый файл, с одной
стороны, позволяет легко вовлекать в программирование конечных пользователей,
никогда ранее программированием не занимавшихся, а с другой стороны, вызывает
некий внутренний протест у многих программистов, привыкших к существенно
большему разнообразию и большей гибкости языковых средств.
Однако интересно наблюдать то, как высококлассные программисты, освоившись с
"правилами игры" shell, пишут на нем программы вомного раз быстрее, чем на Си,
но, что особенно интересно, в ряде случаев эти программы работают даже быстрее,
чем реализованные на Си.
Имя переменной аналогично традиционному представлению об идентификаторе, т.е.
именем может быть последовательность букв, цифр и подчеркиваний, начинающаяся с
буквы или подчеркивания.
Для присваивания значений переменным может использоваться оператор присваивания
"=".
var_1=13 - "13" - это не число, а строка из двух цифр.
var_2="ОС UNIX" - здесь двойные кавычки (" ") необходимы, так как в строке есть
пробел.
Возможны и иные способы присваивания значений shell-переменным. Так например
запись,
DAT=`date`
приводит к тому, что сначала выполняется команда "date" (обратные кавычки
говорят о том, что сначала должна быть выполнена заключенная в них команда), а
результат ее выполнения, вместо выдачи на стандартный выход, приписывается в
качестве значения переменной, в данном случае "DAT".
Можно присвоить значение переменной и с помощью команды "read", которая
обеспечивает прием значения переменной с (клавиатуры) дисплея в диалоговом
режиме. Обычно команде "read" в командном файле предшествует команда "echo",
которая позволяет предварительно выдать какое-то сообщение на экран. Например:
echo -n "Введите трехзначное число:"
read x
При выполнении этого фрагмента командного файла, после вывода на экран сообщения
Введите трехзначное число:
интерпретатор остановится и будет ждать ввода значения с клавиатуры. Если вы
ввели, скажем, "753" то это и станет значением переменной "x".
Одна команда "read" может прочитать (присвоить) значения сразу для нескольких
переменных. Если переменных в "read" больше, чем их введено (через пробелы),
оставшимся присваивается пустая строка. Если передаваемых значений больше, чем
переменных в команде "read", то лишние игнорируются.
При обращении к shell-переменной необходимо перед именем ставить символ "$". Так
команды
echo $var_2
echo var_2
выдадут на экран
ОС UNIX
var_2
3.2. Экранирование
Рассмотрим более подробно приемы экранирования, используемые в shell. В качестве
средств экранирования используются двойные кавычки (" "), одинарные кавычки ('
') и бэк-слэш (\).
Из примеров очевидно их действие:
Можно в одной строке записывать несколько приcваиваний.
x=22 y=33 z=$x
A="$x" B='$x' C=\$x
D="$x + $y + $z" E='$x + $y + $z' F=$x\ +\ $y\ +\ $z
(присваивание G=$x+$y не было бы выполнено из-за пробелов)
Тогда
echo A = $A B = $B C = $C
echo D = $D E = $E F = $F
eval echo evaluated A = $A
eval echo evaluated B = $B
eval echo evaluated C = $C
Выдадут на экран
A = 22 B = $x C = $x
D = 22 + 33 + 22 E = $x + $y + $z F = 22 + 33 + 22
evaluated A = 22
evaluated B = 22
evaluated C = 22
Приведем еще примеры, связанные с экранированием перевода строки. Пусть
переменной "string" присвоено значение "массива" 2x3:
abc
def
Обратим внимание, что для избежания присваивания лишних пробелов вторая строка
массива начата с первой позиции следующей строки:
string="abc
def"
Тогда три варианта записи переменной в команде "echo"
echo $string
echo '$string'
echo "$string"
дадут соответственно три различных результата:
abc def
$string
abc
def
а последовательность команд
echo "str_1
str_2" > file_1
echo 'str_1
str_2' > file_2
cat file_1 file_2
даст выдаст последовательно одинаковые файлы file_1 и file_2:
str_1
str_2
str_1
str_2
Заметим также, что бэк-слэш (\) не только экранирует следующий за ним символ,
что позволяет использовать специальные символы просто как символы,
представляющие сами себя (он может экранировать и сам себя - \), но в командном
файле бэк-слэш позволяет об'единять строки в одну (экранировать конец строки).