Перенаправление ввода/вывода
Чтобы немного докончить тему с процессами и терминалами, рассмотрим несколько символов, которые управляют перенаправлением ввода-вывода.
Когда ОС запускает опр. программу, у этой программы сразу доступно три потока данных, одно на ввод и два на вывод. Есть стандартный ввод, 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 |
1 |
1 |
1 |
|
1 |