Bash переполнение буфера строки чтения

У меня есть сценарий bash, который читает строки из файла, а затем выполняет некоторую логику с этими строками.

So

while read line;
do
# some stuff
done < "$1"

В теле цикла while я передаю вывод одной команды в tee. Когда этот вывод очень велик, порядка 100 КБ, следующий вызов чтения строки завершится неудачно, и цикл while завершится до того, как будут прочитаны все строки в файле.

Почему это происходит? Я не эксперт по bash, но похоже, что происходит какое-то переполнение буфера. Если да, то как мне это исправить?

Спасибо д

Изменить: Итак, некоторые пояснения необходимы. $ 1 - это первый аргумент командной строки, передаваемый сценарию bash, который соответствует имени файла. Что я и делаю, так это передаю каждую строку входного файла в качестве параметра другой программе. Я подключаю stdout и stderr этой программы к | tee -a somefile

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

Итак, более подробный пример того, что я делаю:

while read line;
do
setSomeVar1
setSomeVar2
program --output="$setSomeVar1" -options "$line" 2>&1 | tee -a "$setSomeVar2"
done < "$1"

Спасибо,

-D


person zdevex    schedule 27.02.2013    source источник
comment
Что такое $1? Что именно вы делаете в теле цикла?   -  person chepner    schedule 27.02.2013
comment
Правильный инструмент для работы ... бас, не так ли.   -  person n. 1.8e9-where's-my-share m.    schedule 27.02.2013
comment
Возможно, что-то еще в теле цикла также читает из стандартного ввода, что означает, что он перекачивает данные из файла, предназначенного для команды read.   -  person chepner    schedule 27.02.2013
comment
Если команды используют stdio и подключены к терминалу, они будут сбрасываться по каждой строке. В противном случае прочтите о stdbuf здесь   -  person Fredrik Pihl    schedule 27.02.2013
comment
@chepner - это первый аргумент командной строки, в данном случае имя файла. Цикл передает каждую строку файла в качестве аргумента другой программе.   -  person zdevex    schedule 28.02.2013
comment
@ n.m. Что ты имеешь в виду? Выполнение цикла в bash - неподходящий инструмент для какой работы? Я не вдавался в подробности, чем занимаюсь, я просто спрашиваю, почему этот цикл bash while не работает при определенных условиях.   -  person zdevex    schedule 28.02.2013
comment
@chepner Как я уже сказал выше, я не эксперт по bash, но | someCommand считается ли отправкой со стандартного ввода? Спасибо за помощь.   -  person zdevex    schedule 28.02.2013
comment
Хорошо, я неправильно понял проблему, я думал, что вы читаете 100 тысяч строк с помощью bash,   -  person n. 1.8e9-where's-my-share m.    schedule 28.02.2013
comment
Если вы не публикуете именно то, что делаете, мы не сможем угадать, что не так. Разместите код, с которым вы работаете.   -  person moebius_eye    schedule 29.08.2013


Ответы (2)


Если что-то еще в теле цикла считывается со стандартного ввода, вы можете read получить ввод из другого файлового дескриптора (3 обычно бесплатны):

while read -u 3 line; do
...
done 3< "$1"
person chepner    schedule 27.02.2013
comment
предположение столь же хорошее, как и любое, учитывая отсутствие деталей (хотя и хорошее предположение!) - person Fredrik Pihl; 27.02.2013
comment
@Fredrik Я не имел в виду недостаток подробностей. Я думал, что дал все относящиеся к делу. Я обновил сообщение выше, добавив дополнительные сведения. Есть ли еще какие-нибудь подробности, которые могут быть вам полезны? - person zdevex; 28.02.2013
comment
Увы, это не решило проблему. Он все еще завершает сценарий после большого вывода. - person zdevex; 28.02.2013

Я столкнулся с той же проблемой, если кто-то все еще занимается этим после всех этих лет.

В блоке # do some stuff, какие бы команды вы там ни выполняли, которые по какой-то причине могут перекачивать stdin, добавьте < /dev/null, чтобы вы явно запретили этой команде принимать stdin. Это сработало для меня.

person zxlin    schedule 21.06.2021