Документ взят из кэша поисковой машины. Адрес оригинального документа : http://uneex.mithril.cs.msu.su/LecturesCMC/LinuxShell2008/02/02Redirect
Дата изменения: Unknown
Дата индексирования: Sun Apr 10 08:07:26 2016
Кодировка: UTF-8
LecturesCMC/LinuxShell2008/02/02Redirect - UNИX

Перенаправление ввода/вывода

Чтобы немного докончить тему с процессами и терминалами, рассмотрим несколько символов, которые управляют перенаправлением ввода-вывода.

Когда ОС запускает опр. программу, у этой программы сразу доступно три потока данных, одно на ввод и два на вывод. Есть стандартный ввод, stdin, поток данных номер 0; стандартный вывод? stdout --- поток данных 1; stderr --- 2. С ними можно работать как с файлами. Поскольку манипуляция с потоками данных есть наиболее ффективный способ организации работы программ, то шелл должен это уметь. Любая программа имеет три потока данных. Для тех, кто это проходил, не секрет, что три этих дескриптора прото налседуются, поскольку там случилса fork, потом exec. Но, слава богк, когда программа выполняется в активном режиме, все происходит не так: делается форк, получается два шелла, отличающиеся только результатом форка. Потомок запускает программу, в это время поток-папа выполняет wait(), и ждет завершения. Это не вполне похоже на то, как мы могли бы себе представить. Можно было бы подумать, что есть специальный вызов ?запустить программу?, но это было бы неудобно.

Далее, можно перенаправить вывод. Программа как будет раньше выводить в стандартный вывод, так и будет, и ей будет хорошо. А перенаправление сделает потомок. Как это сделать: ls > file. Это больше приводит к следующему: перед экзеком потомок закрывает-открывает файл. Можо написать перенаправление из файла в файл. Если >>, то это операця дописи в файл. Становится вопрос: зачем тогда вообще придумали stderr, если это тоже вывод, а второе --- как его перенаправить? Есть еще такая операция --- pipeline (|), в прошлый раз приводился пример cal | wc. При этом создается pipe, никакого файла не создается, только два файловых дескриптора. И все, что пишет cal, читает wc. можно создавать трубопровод: ls |sort -r | tail 10. Как перенаправить stderr? Использовать 2>.

cmd |& cmd --- перенаправить оба потока вывода на ввод первой команде.

Чтобы окончательно сбить с толку, лектор намекнет на то, что там еще десятки перенаправлений вывода. Например, есть такая штука: cmd > file1 > file2.

Задача: сформулировать выдачу из нескольких строк и посчитать количество слов. Первый выход:

 echo "ewfsfs
 snegdfsdfsdfs --- шелл будет считать, что это одни параметр
 dfsfs" | wc -c --- выведется некоторое количество символов

Есть другой вариант, воспользоваться

 wc -c
 ewfsfs
 snegdfsdfsdfs
 dfsfs

Есть вариант

 cmd <<< string

Мы добрались до второй части разговора, как манипулировать процессами. Это такая хитрая штука. В каждыцй момент времени могут выполняться сразу несколько задач, процессов. Каждый процесс имеет уникальный идентификатор, именуемый PID. Список всех процессов можно посмотреть командой ps -ef, или ps ax. Поскольку есть единственный способ породить процесс --- форк, то понятно, кто какой процесс породил. Кромеп того, каждый процесс имеет идентификатор папочки, ppid. Если папа умер, то PPID становится равен 1, это PID процесса init. Все это происходит на уровне ядра, и как-то на это воздействовать невозможно. Возвращаясь к перенаправлению ввода-вывода, можно сказать, что с терминалом в один момент может быть связан только один процесс. Вопрос, где взять столько терминалов? Помимо активных процессов есть фоновые процессы, которые могут быть связаны толко по выводу. Таких процессов может быть много. Можно вообще отвязать процесс, для этого есть nohup. Если написать команду и поставить ампервенд, то процесс будет запущен в фоне. Что можно с ним сделать? Можно ему послать сигнал. Всякие добрые шеллы пишут PID запущенного процесса, специально для таких целей. Есть команда kill, у которой есть необязательный параметр --- сигнал.

Когда лектор говорил, что процесс, запущенный в фоне, остается привязанным к терминалу, лектор говорил, что фоновый процесс можно сделать активный, а активный --- фоновым. Как это делается: этому процессу... Все процессы, запущенные из под данного шелла с помощью команды jobs можно посмотреть. Они нумеруются подряд. Активному процессу можно послать сигнал suspend (Z), после этого активным делается его папочка, шелл. После этого можно выдать команду bg (background), тогда шелл отвяжет его и переведет в бэкграунд. Точно также можно сказать fg, и процесс, первый попавшийся или специфицированный, перейдет в активную форму. Зачем все это делать. Ответ такой: управляющий символ. Если процесс привязан к терминалу, если процесс активен, то нажатие некоторых упраалвяющих клавиш приводит к передаче ему сигнала. Вместо kill можно перевести его в фореграунд и сказать C. Терминалом управляет stty, у нее есть команды для посылки сигналов. Если испортить терминал, то можно потом скачать stty sane ^J

Третье, работа с командной строкой. Тут есть два с половиной эшелона: первое --- stty, там есть erase. Тут можно сказать stty erase ^H. Второй эшелон состоит в следующем: точно такая же фигня, абсолютно отвязанная от терминала, заложана в БД терминал капабилитиес. Эта фигня должна соответствовать типу терминала, тому, что лежит в $TERM. Третий эшелон: многие программы, например, баш или вим, то там это пальцами прибито.

Вообще, лектор просит обратить внимание на команду stty.


Сведения о ресурсах

Готовность (%)

Продолжительность (ак. ч.)

Подготовка (календ. ч.)

Полный текст (раб. д.)

Предварительные знания

Level

Maintainer

Start date

End date

0

1

1

1

1

MaximByshevskiKonopko, GeorgeTarasov, MaximByshevskiKonopko


CategoryLectures CategoryCmc CategoryUneex

LecturesCMC/LinuxShell2008/02/02Redirect (последним исправлял пользователь eSyr 2008-07-24 22:12:50)