Путаница в отношении 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,

Другие вопросы по тегам