Я только что запустил несколько команд в терминале, и я начал задаваться вопросом, берет ли Unix / Linux ярлыки при выполнении команд по конвейеру?
Например, допустим, у меня есть файл с миллионом строк, первые 10 из которых содержат hello world
. Если вы запускаете grep "hello world" file | head
команду, останавливается ли первая команда, как только она находит 10 строк, или она продолжает поиск всего файла в первую очередь?
command-line
pipe
utilities
efficiency
DisgruntledGoat
источник
источник
-m
аргумент.Ответы:
Вроде. Оболочка понятия не имеет, что будут выполнять команды, которые вы запускаете, она просто соединяет выход одного с входом другого.
Если
grep
найдет более 10 строк с надписью «Привет, мир», тоhead
получит все 10 нужных строк и закроет канал. Это приведетgrep
к уничтожению с помощью SIGPIPE, поэтому не нужно продолжать сканирование очень большого файла.источник
grep
будет продолжать отправлять вывод в пустоту, как/dev/null
Когда программа пытается выполнить запись в канал, и процесс не читает из этого канала, программа записи получает сигнал SIGPIPE . Действие по умолчанию, когда программа получает SIGPIPE, - завершить программу. Программа может игнорировать сигнал SIGPIPE, и в этом случае запись возвращает ошибку (
EPIPE
).В вашем примере, вот график того, что происходит:
grep
Иhead
команды запуска параллельно.grep
читает некоторый ввод, начинает обрабатывать его.grep
вырабатывается первый блок вывода.head
читает этот первый кусок и записывает его.grep
могут закончиться первыми), в конечном итогеhead
будет напечатано требуемое количество строк. В этот моментhead
выходит.grep
иhead
процессов,grep
могут накапливаться некоторые данные и не напечатали его еще. В моментhead
выходаgrep
может быть чтение ввода или выполнение внутренней обработки, и в этом случае он будет продолжать это делать.grep
выпишу данные, которые он обработал. В этот момент он получит SIGPIPE и умрет.Вполне вероятно, что
grep
обработает немного больше данных, чем строго необходимо, но обычно это всего несколько килобайт:head
обычно считывает порциями по несколько килобайт (потому что это более эффективно, чемread
системный вызов для каждого байта - такое поведение называется буферизацией), поэтому остаток от последнего фрагмента после требуемой последней строки отбрасывается.grep
возможно, накоплены некоторые данные, которые готовы стать выходным блоком (снова буферизироваться). Он получит SIGPIPE, когда попытается очистить свой выходной буфер.В целом, система точно спроектирована так, что утилиты фильтрации, естественно, работают эффективно. Программы, которые должны продолжать работать, когда их выходной канал отключается, должны игнорировать сигнал SIGPIPE.
источник
Sortof, конвейер работает так: сначала он выполняет первую команду, а затем вторую в вашем случае.
То есть, давайте дадим
A|B
команду. Тогда нет уверенности в томA
илиB
начинает первым. Они могут начаться в одно и то же время, если имеется несколько процессоров. Канал может содержать неопределенный, но конечный объем данных.Если B пытается прочитать из канала, но данные недоступны,
B
будет ждать, пока данные не поступят. Если приB
чтении с дискаB
может возникнуть та же проблема, и нужно дождаться окончания чтения с диска. Более близкая аналогия - чтение с клавиатуры. ТамB
нужно будет ждать, пока пользователь наберет. Но во всех этих случаях B запускает операцию «чтения» и должен дождаться ее завершения. Но еслиB
это команда, для которой требуется только частичный вывод,A
то после определенного момента, когдаB
уровень входного сигнала s достигнутA
, SIGPIPE будет уничтоженЕсли
A
попытка записи в канал и канал заполнен,A
необходимо дождаться освобождения некоторого места в канале.A
может иметь такую же проблему, если он пишет в терминал. Терминал имеет управление потоком данных и может контролировать скорость передачи данных. В любом случае,A
он запустил операцию записи и будет ждать, пока операция записи не закончится.A
иB
ведут себя как сопроцессы, хотя не все сопроцессы будут взаимодействовать с каналом. Ни один из них не полностью контролирует другого.источник
head
выходит), в программе появляется сигнал SIGPIPE, и по умолчанию происходит выход.grep
не имеет прямого контроля над каналом (он просто получает данные), а канал не имеет прямого контроляgrep
(он просто отправляет данные) ...То
grep
, что делает любая другая программа, полностью зависит от внутренней логики этих программ. Если вы укажете в параметрахgrep
командной строки сделать ранний выход-при-обнаружении , то это произойдет, в противном случае он будет переходить к самому концу файла в поисках шаблона ...Терминал также совершенно не связан с внутренними действиями
grep
иshell
действиями трубопровода ... Терминал - это, в основном, стартовая площадка и выходной дисплей ...источник