Выполняется только команда после конвейера, как конвейер работает в этих сценариях?

Да,

for f in *{b,c}*

сначала расширяется до:

for f in *b* *c*

А затем цикл работает над независимым расширением этих двух глобул.

Здесь вам нужен один глобус. Здесь подойдет *[bc]*, но для чего-то более сложного, в bash, вам нужно включить ksh-подобные расширенные глобы. Вероятно, вам также понадобится опция nullglob:

shopt -s nullglob extglob
for f in *@(b|c)*; do...

In zsh:

for f in *(b|c)*(N); do

The (N) being for per-glob nullglob.

In ksh93:

for f in ~(N)*@(b|c)*; do
-1
08.04.2019, 15:23
2 ответа

Вот как работают конвейеры. :Выходные данные левой команды отправляются в качестве входных данных для правой команды.

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

cat /var/log/messages ; date

Если вы хотите запустить вторую команду только в случае успеха первой, используйте&&:

cat /var/log/messages && date

Если вы хотите запустить вторую команду только в случае сбоя первой, используйте||:

cat /var/log/messages || date

Если вы хотите запустить первую команду в фоновом режиме и одновременно запустить вторую, используйте&

cat /var/log/messages & date
0
28.01.2020, 05:08

Обе команды в обоих примерах выполняются . На самом деле отображается только вывод команды после символа трубы.

В вашем конвейере содержимое файла /var/log/messagesпередается на вход команды dateпутем запуска catв левой части конвейера.

Команда dateне заботится о своем стандартном входном потоке и игнорирует поступающие туда данные. Однако он будет производить свой собственный вывод, который он делает в своем стандартном потоке вывода.

Чистый видимый результат заключается в том, что вывод catигнорируется и отбрасывается, в то время как вывод dateотображается в терминале (или где-либо еще, куда идет вывод конвейера. ).

Что на самом деле происходит с выводом команды cat, так это то, что, поскольку dateне читает его, команда catвременно блокируется, ожидая чтения ее вывода (после успешного вывода. сколько буфер канала может вместить; он не знает dateникогда не прочитает ). Команда dateделает свое дело и выводит свою строку, после чего завершается.

В этот момент, когда dateзавершается и стандартный поток ввода dateзакрывается, команда catполучает сигнал PIPEот оболочки. Этот сигнал сообщает cat, что любые данные, которые он пытается записать на свой стандартный вывод, никогда не будут прочитаны, и он также завершается (, завершаясь PIPE, является действием по умолчанию для этого сигнала ). Остальная часть файла, из которого считывался cat, никогда не читается, а данные в буфере канала отбрасываются, когда оболочка освобождает связанную с ними память.

То же самое происходит с заменой dateна wили любой другой командой, которая не читает свой стандартный входной поток.

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

cat /var/log/messages | tr '[:lower:]' '[:upper:]'

или без трубы (, так как catфактически не требуется ни в одном из этих примеров ),

tr '[:lower:]' '[:upper:]' </var/log/messages
2
28.01.2020, 05:08

Теги

Похожие вопросы