Путаница в отношении ls, dir и tee
Я знаю это tee
будет читать из STDIN и создать новый файл. Но когда это приходит с ls
какой процесс происходит первым?
Например:
➤ ls
12 123 1234
➤ ls | tee hello
12
123
1234
hello # ls catch hello
➤ ls | tee 000
12
123
1234
hello # ls didn't get 000
➤ ls | tee 0
000
12
123
1234
hello # ls didn't get 0
➤ ls | tee 00000
0
000
00000 # ls did get 00000
12
123
1234
hello
➤
но когда дело доходит до dir
:
➤ ls
12 123 1234
➤ dir | tee hello
12 123 1234 hello # get hello
➤ dir | tee 000
000 12 123 1234 hello
➤ dir | tee 0
0 000 12 123 1234 hello #get 0
➤ dir | tee 000000
0 000 12 123 1234 hello # didn't get 00000
➤ dir | tee 01
0 000 000000 01 12 123 1234 hello
➤ dir | tee 000000000000000000000000
0 000 000000 000000000000000000000000 01 12 123 1234 hello #get 00000000..000
➤
ЗАЧЕМ? Что происходит первым? tee
создать новый файл или ls
/dir
выход?
2 ответа
Это на самом деле имеет место условие состязания процессов на ресурсе каталога, так как два процесса выполняются параллельно.
Каждая команда в конвейере выполняется как отдельный процесс (т. Е. В под-оболочке).
Идея конвейера заключается в том, что output
из процесса A, связанного с исполняемым файлом exec_A, перенаправляется в процесс B, связанный с исполняемым файлом exec_B:
exec_A | exec_B
То, как это делается, в значительной степени зависит от реализации, но с учетом прагматических ограничений операционной системе придется создать буфер для размещения вывода A и заставить B читать из этого буфера. Это происходит до запуска процессов.
Так что происходит, что-то вроде:
exec_A &> buf ; exec_B < buf &
Что процессы делают внутренне с данными, которые они получают или записывают, зависит от реализации процесса. В этом случае tee создает файл, который будет записываться при запуске процесса, что абсолютно логично, так как необходимо добавлять входящие данные.
Учитывая это, это зависит от того, если процесс A (т.е. ls
/dir
) завершает трансляцию своего каталога, прежде чем процесс B откроет файл. Что на самом деле зависит от того, кто получает блокировку на родительском ресурсе.
Вы действительно можете наблюдать, что ls
почти всегда будет выводить ресурс, который создан как таковой:
ls * | tee subdir/0
потому что он получает блокировку на subdir
поздно.
Обе программы работают одновременно. Пока процесс в левой части канала записывает выходные данные в канал, процесс в правой части канала читает из него.
tee
создаст выходной файл сразу после запуска, перед чтением из ввода. Вот почему иногда вы можете (!) Увидеть файл в выводе ls
и в выводе dir
, Тем не менее, нет никаких гарантий для этого. Как правило, это зависит от того, когда каждый процесс войдет в / ЦП и сколько циклов, как долго tee
нужно подождать чтобы открыть файл и тд.
На самом деле в моей тестовой системе файл почти всегда обнаруживался, либо с ls
или же dir
, Но иногда файл отсутствовал в списке снова с обоими ls
или же dir
,