Каналы и перенаправление
Прежде чем заняться
подробностями программ командной
оболочки, необходимо сказать несколько
слов о возможностях перенаправленя
ввода и вывода программ(не только
программ командной оболочки) в ОС Linux.
Перенаправление ввода
вывода
Возможно, вы уже знакомы
с некоторыми видами перенаправления,
например, таким как:
ls -l> lsoutput.txt
сохраняющим вывод
команды ls в файле с именем lsoutput.txt.
Однако перенаправление
позволяет сделать гораздо больше, чем
демонстрирует этот простой пример. В
главе 3 вы узнаете больше о дескрипторах
стандартных файлов, а сейчас вам нужно
знать только то, что дескриптор файла
0 соответствует стандартному вводу
программы, дескриптор 1 — стандартному
выводу, а дескриптор файла 2 — стандартному
потоку ошибок. Каждый из этих файлов
можно перенаправлять независимо друг
от друга.
На самом деле можно
перенаправлять и другие дескрипторы
файлов, но, как правило, нет нужды
перенаправлять любые другие дескрипторы,
кроме стандартных:0, 1 и 2.
В предыдущем примере
стандартный вывод перенаправлен в файл
с помощью оператора >. По умолчанию,
если файл с заданным именем уже есть,
он будет перезаписан. Если вы хотите
изменить поведение по умолчанию, можно
применить команду set -o noclobber(или set -C),
которая устанавливает опцию noclobber, чтобы
помешать перезаписи или перенаправлении.
Отменить эту опцию можно с помощью
команды set +o noclobber. Позже в этой главе
будут приведены другие опции команды
set.
Для дозаписи в конец
файла используйте оператор >>.
Например, команда
ps >> lsoutput.txt
добавит вывод команды
ps в конец заданного файла.
Для перенаправления
стандартного потока ошибок перед
оператором > вставте номер дескриптора
файла, который хотите перенаправить.
Поскольку у стандартного потока ошибок
дескриптор файла 2, укажите оператор
2>. Часто бывает полезно стандартный
поток ошибок, запрещая вывод его на
экран.
Предположим, что вы
хотите применить команду kill для завершения
процесса из сценария. Всегда существует
небольшой риск, что процесс закончится
до того, как выполнится команда kill. Если
это произойдет, команда kill выведет
сообщение об ошибке в стандартный поток
ошибок, который по умолчанию появится
на экране. Перенаправив стандартный
вывод команды и ошибку, вы сможете
помешать команде kill выводить какой бы
то ни было текст на экран.
Команда
kill -HUP 1234 >killout.txt
2>killet.txt
поместит вывод и
информацию об ошибке в разные файлы.
Если вы предпочитаете
собрать оба набора выводимых данных в
одном файле,
можно применить оператор
>& для соединения двух выводных
потоков. Таким образом, команда
kill -l 1234 >killrtt.txt 2>&&1
поместит свой вывод и
стандартный поток ошибок в один и тот
же файл. Обратите внимание на порядок
следования операторов. Приведенный
пример читается как «перенаправить
стандартный вывод в файл killer.txt, а затем
перенаправить стандартный поток ошибок
туда же, куда и стандартный вывод». Если
вы нарушите порядок, перенаправление
выполнится не так, как вы ожидаете.
Поскольку обнаружить
результат выполнения команды kill можно
с помощью кода завершения(который будет
подробно обсуждаться далее в этой
главе), часто вам не потребуется сохранять
какой бы то ни было стандартный вывод
или стандартный поток ошибок. Для того
чтобы полностью отбросить любой вывод,
вы можете использовать универсальную
«мусорную корзину» Linux, /dev/null, сдледующим
образом:
kill -1 1234 >/dev/null 2>&1
Перенаправление ввода
Также как
вывод вы можете перенаправить ввод.
Например,
more <
killout.txt
Понятно,
что это тривиальнейший пример для ОС
linux; команда more в системе Linux в отличие
от своего эквивалента командной строки
в ОС Windows с радостью принимает имена
файлов в качестве параметров.
Каналы
Вы можете
соединять процессы с помощью оператора
канала ( | ) В ОС Linux, в отличие от MS-DOS,
процессы, соединенные каналами, могут
выполнятся одновременно и автоматически
переупорядочивать в соответствии с
потоками данных между ними. Как пример,
можно применить команду sort для сортировки
вывода ps.
Если применять
каналы, придется использовать несколько
шагов, подобных следующим:
ps > psout.txt
sort psout.txt >
pssort.out
Соединение
процессов каналом даст более элегантное
решение:
ps | sort >
pssort.out
Поскольку
вы, вероятно, захотите увидеть на экране
вывод, разделенный на страницы, мржно
подсоединить третий процесс, more, и все
это в одной командной строке:
ps | sort | more
Практически
нет ограничений на допустимое количество.
Предположим, что вы хотите видеть все
имена выполняющихся процессов, за
исключением командных оболочек. Можно
применить следующую командную строку:
ps -xo comm | sort
| uniq | grep -v sh | more
В ней берется
вывод команды ps, сортируется в алфавитном
порядке, из него извлекаются процессы
с помощью команды uniq, применяется утилита
grep -v sh для удаления процесса с именем
sh и в завершение полученный список
постранично выводится на экран.
Как видите,
это гораздо более элегантное решение,
чем строка из отдельных команд, каждая
со своими временными файлами. Но в этом
случае имейте в виду следующее. Если
строка из команд, файл вывода создается
или записывается сразу, как только
сформирован набор команд, поэтому в
строке из нескольких команд никогда не
используйте дважды одно и тоже имя
файла. Если вы попытаетесь сделать
что-то подобное:
cat mydata.txt |
sort | uniq > mydata.txt
то в результате
получите пустрой файл, т. к. вы
презапишите файл mydata.txt, прежде чем
прочитаете его.
|