Избегайте буферизации вывода для группы команд (фигурные скобки) в сценарии bash

У меня есть сценарий bash, содержащий группу команд в фигурных скобках { ... } . Эта группа содержит некоторые начальные команды echo а затем один цикл . На каждой итерации цикл выполняет различные медленные команды (в основном с curl и некоторый дополнительный синтаксический анализ). Каждая итерация медленная (из-за сетевого взаимодействия), но она печатает одну строку (кода python); насколько я вижу, не должно быть проблем с буферизацией, исходящих из самих команд, поскольку они прекращают работу и уходят.

Вся группа команд передается на python -u (я также пытался с tail -f проверить), и, очевидно, весь цикл выполняется до того, как все будет прочитано python -u или tail -f .

Я знаю, как отключить (по возможности) одну команду с помощью различных инструментов, таких как stdbuf но я не думаю, что это может помочь здесь, потому что похоже, что проблема возникает из командной группировки, а не из той или иной команды.

Любой намек?

2 Solutions collect form web for “Избегайте буферизации вывода для группы команд (фигурные скобки) в сценарии bash”

(Обратите внимание на будущих читателей: тон раздражения здесь не для вопроса, а для ошибок, которые я пытался ответить на него и нескольких изменений, которые они повлекли за собой).

О, ради всего святого. Проблема в tail -f . Это прекрасно работает:

 #!/bin/bash printf 'hi\n' { for i in 1 2 3 4; do sleep 0.5 /bin/echo $i done; } | cat printf 'bye\n' 

Это не труба, это не группа. Это tail . Как и в России, преследуя наши собственные хвосты!

Таким образом, tail -f не удалось, потому что по какой-то причине он не выводится сразу. Не знаю, почему python -u терпит неудачу, но я не думаю, что это что-то в скрипте. Может быть, попробуйте unbuffer . Попробуйте свой сценарий с cat , по крайней мере, и убедитесь, что в этом случае он не загружен.


Раньше неудавшаяся попытка умышленно ушла отсюда, поэтому будущие читатели могут разобраться в комментариях.

Этот скрипт демонстрирует ту же проблему буферизации, которую вы получаете:

 #!/bin/bash printf 'hi\n' { for i in 1 2 3 4; do sleep 0.5 printf '%s\n' $i done; } | tail -f printf 'bye\n' 

Этого нет. Вывод внутри группы перенаправляется на stderr, затем stderr из всей группы передается по команде в команду. Поскольку это stderr, он не загружен.

 #!/bin/bash printf 'hi\n' { for i in 1 2 3 4; do sleep 0.5 printf '%s\n' $i 1>&2 done; } |& tail -f printf 'bye\n' 

Адаптировано из ответа Ван Хунцзина в этом вопросе . Трудность заключалась в том, чтобы найти способ небуферировать трубу с помощью скобок, а не явную команду. Пришлось немного поиграть, чтобы правильно перенаправить перенаправление.

вам просто нужно сделать:

 { stdbuf -o0 curl ... stdbuf -o0 whatever ... }| tail -f 

…, который будет работать для динамически связанных приложений, хотя я уверен, что curl включает в себя собственный переключатель небуферов .

  • Bash: слияние имени папки из переменной с именем файла
  • Как заставить excel интерпретировать китайские символы в CSV-файле
  • Выбор случайной выборки из дерева каталогов
  • Измените существующий скрипт, чтобы хранить данные только две недели
  • Копирование новейших файлов
  • Как я могу более эффективно собирать данные от пользователей на vm?
  • строковые манипуляции без awk или sed
  • Вывод трубы jack_cpu_load через sed
  • Распечатать номера от 1 до 50
  • Извлеките подстроку из значения переменной
  • Bash Script для cp-файлов из списка
  • Interesting Posts

    Нечетное поведение с сжатым файлом gzip

    Скрипт Zsh, который принимает переменное количество аргументов

    Debian VM Может видеть другие компьютеры в сети, но не может подключиться к WWW

    На экране входа в Mint разная раскладка клавиатуры для каждого пользователя

    Почему входы / выходы с высоким диском уменьшают оперативность / производительность системы?

    Бесплатное и быстрое ПО NAS для управления

    Печатать аргументы оболочки в обратном порядке

    «Найти» вывод относительно каталога

    простое решение rsync с файловым менеджером (thunar или nautilus или …)

    создание архива с использованием tar, включая все «dotfiles», но исключая все подкаталоги и структуру каталога wo

    Почему цитирование исполняемого файла постоянно меняет название PuTTY?

    Как убрать постоянный / домашний

    Как остановить устройство, когда выполняется другое устройство

    Как добавить слова в существующий столбец

    YUM UPDATE застрял навсегда

    Linux и Unix - лучшая ОС в мире.