Подводные камни в Bash №7
Продолжаем делать правильно.
Этот код выглядит вполне нормально:
Он считает, сколько строк в файле bar.txt
содержат слово foo
.
Здесь главная проблема — переменная count
не изменится вне цикла while
, потому что в Bash каждая команда в пайплайне (|
) запускается в отдельной оболочке (subshell). То есть count++
происходит «внутри», и снаружи этого не видно.
Если простым языком: Каждая часть, разделённая |
, запускается в отдельной «коробке» (subshell). То есть while
работает внутри своей коробки. B всё что там происходит, не видно снаружи.
Некоторые оболочки
ksh93
или Bash с включённой настройкойshopt -s lastpipe
работают по-другому — цикл выполняется в той же оболочке, и тогдаcount
изменится.
Этот код вернет 0, несмотря на count++
, а вот например в zsh вернется 3.
Как быть?
Первый вариант:
Эта штука говорит интерпретатору — сделай всё сам и не передавай работу другому.
Второй вариант:
Вообще избавиться от while
и всё сделать через grep
:
Можно еще наколхозить и передавать значения через временный файл, но это прям пиздец шляпа и костыль.
Выводы
Нужно просто посчитать строки:
Нужно обрабатывать строки:
Хочешь использовать pipe:
Вот и вся наука.