LINUX.ORG.RU

Нечаянная загадка цикла while

 , ,


0

1
while read -r d; do
        [[ -d $d ]] || {
                echo "$d is not a directory, skipping it" >&2
                continue
        }
        d=${d%%+(/)}
        info_ "Processing <<$d>>"
        { ssh ${remoteHost} "mkdir -p '$d'" && echo 'mkdir OK' >&2; } || echo 'mkdir FAIL' >&2
        rsync -a${flBeVerbose:+v} "${d}/" "${remoteHost}:${d}"

done < <(cat "$confDirList" | sed -r -e '/^\s*(#.*)?$/d' -e 's%\s*(#.*)$%%')

Есть вот такой цикл. В confDirList - путь до файлика с каталогами для синхронизации через перевод строки, либо "-", если нужно читать с STDIN. Целиком код этого скриптика здесь: https://pastebin.com/HbhWLWad

Внимание, вопрос: (какого) почему такое может быть, что если делать ssh в цикле, то цикл выполнится только один раз (и будет напечатано: «mkdir OK»), а если не делать ssh - то всё ОК, выполнится по количеству каталогов в confDirList'е. Каким образом использование ssh может привести к генерации признака EOF при чтении из потока в цикле while??

★★★★★

Последнее исправление: DRVTiny (всего исправлений: 2)
Ответ на: комментарий от xaizek

Бинго! Да, так и есть, ssh каким-то образом аффектил поток STDIN... чужой поток.

Спасибо огромное, действительно опция "-n" помогла :)

DRVTiny ★★★★★
() автор топика
Ответ на: комментарий от DRVTiny

Только поток не чужой, каждая команда/дочерний процесс получает дескриптор, ссылающийся на тот же поток из которого читает read:

+[~]$ while read a; do read b; echo a=$a; echo b=$b; done < <(echo -e '1\n2\n3\n4')
a=1
b=2
a=3
b=4

xaizek ★★★★★
()
Ответ на: комментарий от xaizek

А ещё я вообще дурень, первая же тема в ссылках ниже - о том же самом :)

Ещё раз спасибо! Про то, что while не съедает STDIN полностью был в полном неведении, хотя пишу на BASH всякое уже 11ть лет. Вот уж действительно: век живи - вне учись.

DRVTiny ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.