PS команда и grep

8

Почему ps -ef | grep $$показывает grepкоманду в списке процессов? Разве grepказненный после того, psкак он закончил свою работу?

Маллиган
источник
Это называется трубопровод ...
Ipor Sircer
Если бы он дождался завершения первой команды, как конвейеры будут работать с командами, которые не останавливаются сами по себе, например tail -f filename | grep pattern?
Бармар

Ответы:

11

При передаче команд все процессы запускаются одновременно, и они просто спят (блокируются) до тех пор, пока I / O не войдет / не выйдет из них. Оболочка не буферизует вывод и не удерживает его до завершения одного процесса, а затем передает его другому процессу.

Например:

mtak@rubiks:~$ tar -zcvf test.tgz /lib/ | grep bla | grep foo | grep bar

Результаты в:

mtak 28813 28799  0 12:35 pts/17   00:00:00 tar -zcvf test.tgz /lib/
mtak 28814 28799  0 12:35 pts/17   00:00:00 grep --color=auto bla
mtak 28815 28799  0 12:35 pts/17   00:00:00 grep --color=auto foo
mtak 28816 28799  0 12:35 pts/17   00:00:00 grep --color=auto bar

Вы можете увидеть состояние процесса grep в дереве / proc:

mtak@rubiks:~$ grep State /proc/28814/status
State:  S (sleeping)

Также видно, что оба greps подключены к одному и тому же конвейеру (id 57573438) и что STDOUT ( 1) первого процесса подключен к STDIN ( 0) второго процесса.

root@rubiks:~# ls -l /proc/28815/fd
total 0
lr-x------ 1 mtak mtak 64 dec  1 12:35 0 -> pipe:[57573437]
l-wx------ 1 mtak mtak 64 dec  1 12:35 1 -> pipe:[57573438]
lrwx------ 1 mtak mtak 64 dec  1 12:35 2 -> /dev/pts/17

root@rubiks:~# ls -l /proc/28816/fd
total 0
lr-x------ 1 mtak mtak 64 dec  1 12:35 0 -> pipe:[57573438]
lrwx------ 1 mtak mtak 64 dec  1 12:35 1 -> /dev/pts/17
lrwx------ 1 mtak mtak 64 dec  1 12:35 2 -> /dev/pts/17
mtak
источник
Это немного сложный пример, хотя сказать, что они спят, а затем ввести команду сна, потому что тогда, когда он говорит, что сон, это ваша команда сна, а не что-то, что делается оболочкой
barlop
Я просто добавил туда команду сна, чтобы ввести некоторую задержку, чтобы я мог осмотреть систему. Команда sleep не влияет на grep, стоящий за ней, за исключением того, что grep не получает никакого ввода. Если это делает вас счастливым, вы можете сделать то же самое с tar: $ tar -zcvf test.tgz /lib/ | grep foo | grep barи затем проверить grep:$ cat status Name: grep State: S (sleeping)
mtak
Уже отредактировал, чтобы было понятнее.
mtak