Да,
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
Вот как работают конвейеры. :Выходные данные левой команды отправляются в качестве входных данных для правой команды.
Если вы хотите запустить две команды одну за другой, используйте точку с запятой:
cat /var/log/messages ; date
Если вы хотите запустить вторую команду только в случае успеха первой, используйте&&
:
cat /var/log/messages && date
Если вы хотите запустить вторую команду только в случае сбоя первой, используйте||
:
cat /var/log/messages || date
Если вы хотите запустить первую команду в фоновом режиме и одновременно запустить вторую, используйте&
cat /var/log/messages & date
Обе команды в обоих примерах выполняются . На самом деле отображается только вывод команды после символа трубы.
В вашем конвейере содержимое файла /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