2016-01-19 12 views
1

Я знаю, что tee будет читать STDIN и создать новый файл. Но когда он приходит с ls, какой процесс происходит первым?Путаница о ls, dir и tee

Например:

➤ 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 результат?

ответ

1

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

Каждая команда в конвейере выполняется как отдельный процесс (т. Е. В под-оболочке).

Идея трубопровода является то, что output от процесса , связанный с исполняемым exec_A перенаправляется на обработку B, связанный с исполняемым exec_B:

exec_A | exec_B

Как это сделано в значительной степени зависит от реализации, но при условии прагматических ограничений, которые операционная система должна была бы создать ab uffer, чтобы поместить вывод A и заставить B читать из этого буфера. Это происходит до начала процессов.

Так что же происходит что-то вроде:

exec_A &> buf ; exec_B < buf &

Что процессы делают внутренне с данными, которые они получают или записи зависит от реализации этого процесса.В этом случае tee создает файл, который будет записываться при запуске процесса, что абсолютно логично, так как необходимо добавить входящие данные.

Учитывая, что это зависит от того, завершился ли процесс A (то есть ls/dir), перед тем как процесс B открыл файл. На самом деле это зависит от того, кто получает блокировку родителя ресурса.

Вы действительно можете заметить, что ls почти всегда будет выводить ресурс, который создается как например:

ls * | tee subdir/0

, потому что он получает блокировку на subdir конце.

+0

Итак, кто решил, что замок принадлежит? Это случайно? Потому что в этом случае иногда 'ls' получает файл, а иногда его нет ... – wrfly

+0

@ Гмм все процессоры, о которых я знаю, являются детерминированными, поэтому ответ в ** нет, это не случайно **, но зависит на начальных условиях. То, что мы не можем знать результат чего-то, не означает случайности. В принципе, сравнивая 'dir' vs' ls', я бы сказал, что большее влияние имеет реализация, чем ваша так называемая * cpu-randomness *. – g24l

1

Обе программы работают одновременно. В то время как процесс на левой стороне трубы записывает выход в трубу, процесс с правой стороны трубы считывается из него.

tee будет создавать выходной файл сразу после запуска, перед чтением с ввода. Вот почему вы можете (!) Видеть файл на выходе ls, и на выходе dir. Тем не менее, есть без гарантии. Как правило, это зависит от того, когда каждый процесс войдет в CPU, и сколько циклов, сколько времени нужно ждать, чтобы открыть файл и так далее.

Фактически на моей тестовой системе файл почти всегда показывался либо с ls, либо с dir. Но иногда файл отсутствовал в списке снова с ls или dir.

+0

Итак, это независимо от команды 'ls' или' dir', только из-за процессора, правильно? – wrfly

+0

Да, это не имеет значения. – hek2mgl

+0

Но в этом случае: 'ls * | tee subdir/0', 'ls' всегда получает правильный ответ (он получил файл), это то же самое или другое? – wrfly

 Смежные вопросы

  • Нет связанных вопросов^_^