Переадресация ввода-вывода с помощью дескрипторов файлов
Мы ранее уже говорили, что команда обычно направляет свой вывод в некоторый файл с дескриптором, равным 1 или 2. В языках типа Си можно связать вывод с любым дескриптором файла с помощью системной команды write (см. UNIX User's Reference). В Shell имеется свой собственный механизм создания выходного файла, связанного с конкретным дескриптором файла. Вводя :
fd1 >& fd2
где fd1 и fd2 - разрешенные дескрипторы файлов, можно направить вывод, который был связан с файлом с дескриптором fd1 в файл с дескриптором fd2. По умолчанию значения fd1 и fd2 равны 1. Если к моменту выполнения команды значение fd2 не определено, то переадресация отменяется. Наиболее часто этот механизм используется для переадресации стандартного вывода ошибок в файл стандартного вывода. Это делается так:
command 2>&1
Если вы хотите перенаправить и стандартный вывод и вывод ошибок в один и тот же файл file, введите:
command 1>file 2>&1
Порядок следования аргументов здесь важен: сначала дескриптор 1 связывается с файлом file, затем дескриптор 2 связывается с тем же файлом, т.к. он уже связан с дескриптором 1. Если порядок аргументов изменить, то вывод ошибок пойдет на терминал, а стандартный вывод пойдет в file, т.к. к моменту переадресации вывода ошибок дескриптор 1 будет связан с терминалом.
Этот механизм может быть обобщен для переадресации стандартного ввода. Если вы введете, например:
fda <&fdb
то оба дескриптора fda и fdb будут связаны с одним и тем же входным файлом. Если fda и fdb не указаны, то они принимаются равными 0. Такая переадресация ввода удобна для команд, которые используют несколько источников ввода.
Обычно Shell заменяет все вхождения переменной $variable значением, присвоенным этой переменной variable, если оно имеется. Однако, существует определенное ограничение на разрешение условной подстановки, зависящее от того, установлена эта переменная или нет. По определению, переменная считается установленной, если ей присвоено какое-либо непустое значение. Переменной может быть присвоена нулевая строка, одним из следующих способов:
A=
bcd=""
efg=''
set '' ""
Первые три примера присваивают нулевую строку соответствующей переменной Shell. Последний пример устанавливает первый и второй позиционные параметры равными нулевой строке. Следующие условные выражения зависят от того, присвоено ли переменной непустое значение или нет. Параметр подстановки может выступать либо цифрой, либо именем переменной:
${variable:-string} Если variable установлена и ненулевая, то вместо этого выражения подставляется значение переменной $variable. В противном случае выражение заменяется значением string. Помните, что значение variable при этом не изменяется.
${variable:=string} Если variable установлена и ненулевая, то вместо этого выражения подставляется значение переменной $variable. В противном случае переменная variable устанавливаетcя равной string и затем производится подстановка вместо выражения нового значения variable. Позиционные параметры установить таким способом нельзя.
${variable:?string} Если variable установлена и ненулевая, то вместо этого выражения подставляется значение переменной $variable. В противном случае печатается сообщение в виде:
variable: string
и происходит выход из текущей оболочки. Если вы находитесь в основном Shell'е, то выхода не происходит. Если string не указана, то сообщение будет выглядеть так:
variable: parameter null or not set
${variable:+string} Если variable установлена и ненулевая, то вместо этого выражения подставляется значение string. В противном случае выражение заменяется нулевой строкой. Помните, что значение variable при этом не изменяется.
Эти выражения можно также использовать без двоеточия. В этом случае Shell только проверяет, была ли установлена переменная или нет.
Следующие два примера показывают, как пользоваться этими средствами:
1. Пример явного присвоения значения переменной PATH:
PATH=${PATH:-':/bin:/usr/bin'}
Это означает, что если переменная PATH была установлена и ненулевая, то сохраняется ее текущее значение, в противном случае она устанавливается равной ":/bin:/usr/bin".
2. Пример автоматического присвоения значения переменной HOME:
cd ${HOME:='/usr/gas'}
Если HOME установлена и ненулевая, то происходит переход в этот каталог. В противном случае HOME присваивается указанное значение и затем выполняется команда.