Bash-скрипт continue ключевое слово, не прерывающее итерацию цикла

Я следую серии руководств, чтобы изучить сценарий оболочки Bash. Одно из упражнений состоит в том, чтобы пройтись по файлам в текущем каталоге и найти шаблон в этих файлах. Если шаблон найден, сценарий должен суммировать размер этих файлов.

#!/bin/sh
patern=echo
totalSize=0

for file in * 
do
    [ ! -f $file ] && continue  

    if grep $patern $file > /dev/null
    then    
        echo "pattern matched in $file" 
        echo "file size is `stat -c%s $file`"
        fileSize=`stat -c%s $file`

        totalSize=`expr $totalSize + $fileSize`
        echo "size so far is $totalSize bytes"
        echo                                                    
    fi
done

У меня есть еще одна папка в каталоге, из которого я запускаю скрипт. Папка называется "somedir". Он пуст. Я взял фрагмент выходного текста, вставленный ниже. Средние 3 строки показывают, когда цикл перебирает каталог «somedir», который печатается как «sum_files» — имя моего сценария вместе с размером файла.

Я не понимаю такого поведения. Как пустой каталог может иметь размер файла?
Но меня больше всего беспокоит, почему ключевое слово continue не останавливает итерацию цикла. Вывод показывает, что скрипт выполняет приведенный ниже оператор if, содержащий команду grep, даже если он должен остановиться, если каталог найден.

Я убедился, что тестовая команда[ ! -f $file ] на самом деле возвращает 0, когда цикл достигает каталога, и поэтому должна быть вызвана команда && continue. Так почему же программа продолжает остальную часть кода цикла и пытается выполнить поиск каталога, а не просто пропустить итерацию цикла при продолжении, как и ожидалось? Я знаю, что это довольно тривиально, но хотел бы знать, что здесь происходит.

Выходной текст

шаблон, сопоставленный при выходе на пенсию
размер файла 396
размер на данный момент 6385 байт

шаблон соответствует в sum_files
размер файла 398
размер на данный момент 6783 байт

шаблон соответствует tp0
размер файла 164
размер на данный момент 6947 байт


person Drok    schedule 20.09.2015    source источник
comment
Используйте shellcheck.net, чтобы определить несколько других ошибок в вашем скрипте.   -  person chepner    schedule 20.09.2015
comment
Ваш вопрос не имеет смысла… это не имеет смысла: Средние 3 строки показывают, когда цикл выполняет итерацию по каталогу somedir, который печатается как sum_files. Попробуйте set -x посмотреть, что произойдет.   -  person gniourf_gniourf    schedule 20.09.2015
comment
Шаблон @gniourf_gniourf соответствует шаблону sum_files --- размер файла составляет 398 --- размер на данный момент составляет 6783 байта. С выхода терминала. Каждый файл выводит 3 строки текста, показывающего имя файла, если было найдено совпадение с шаблоном, его размер файла и общую сумму. Здесь я показываю аномалию, когда итерация цикла for проходит через папку somedir, чего не должно происходить. Где я должен установить -x в коде?   -  person Drok    schedule 20.09.2015
comment
Цикл проходит по файлу sum_file. Поместите set -x сразу после #!/bin/sh.   -  person gniourf_gniourf    schedule 20.09.2015
comment
На самом деле @gniourf_gniourf вы правы, потому что я запускаю скрипт в своем bin-файле, где находится файл скрипта, поэтому, конечно, это не имеет никакого смысла, потому что скрипт сам себя находит. РЖУ НЕ МОГУ.   -  person Drok    schedule 20.09.2015
comment
Ага. Этот вопрос должен быть закрыт :).   -  person gniourf_gniourf    schedule 20.09.2015
comment
Возможный дубликат Проверьте, существует ли файл, и продолжите, иначе выйдите в Баш   -  person jww    schedule 01.04.2018


Ответы (2)


continue продолжает цикл, как если бы он достиг своего дна.

Чтобы выйти из цикла, используйте break.

Подробнее о сценариях bash здесь: http://tldp.org/LDP/abs/html/index.html

person alk    schedule 20.09.2015
comment
Я понял из учебника, которому следую, и tldp.org/LDP/abs/html /loopcontrol.html#EX28 из этой ссылки, что: Продолжить остановит текущую итерацию цикла, где останов остановит весь цикл for, как если бы он достиг конца всех файлов. Когда я заменяю break на continue, скрипт прекратит поиск любых других файлов, как только найдет каталог, который не соответствует тому поведению, которое я хочу. - person Drok; 20.09.2015
comment
К вашему сведению, код возврата 0 означает успех, поэтому правая часть && будет выполнена. Шелл не С. - person gniourf_gniourf; 20.09.2015
comment
@gniourf_gniourf: речь идет не о кодах возврата, а о логическом выражении, которое оценивается [ ! -f $file ], то есть true из false. (tldp.org/LDP/abs/html/fto.html) - person alk; 20.09.2015
comment
код возврата 0 означает истину (или, скорее, успех). Попробуйте: true; echo $? и false; echo $?. Еще раз, оболочка не C. - person gniourf_gniourf; 20.09.2015
comment
Да это я понимаю. Результат теперь ожидаемый. Я проверил [ ! -f $file ], запустив echo $? после него и получил 0, когда каталог повторился в цикле. Извините за путаницу. Я не видел леса за деревьями! - person Drok; 20.09.2015
comment
Ребята, моя ошибка заключалась в том, что я написал !, но не смог проанализировать его в своем мозгу. - person alk; 20.09.2015
comment
Рекомендовать ABS — сомнительный совет, есть много других руководств, более точных и полезных. ABS действительно повезло получить известность, которую раньше приносило участие в TLDP, но это произошло благодаря сомнительным достоинствам. - person tripleee; 04.04.2018
comment
@tripleee: которые более точны и полезнее: мы оценили ваше предложение. Рад скорректировать свой ответ. - person alk; 04.04.2018
comment
wiki.bash-hackers.org/scripting/tutoriallist имеет рейтинги для ряда руководств. . Самый высокий рейтинг на конкурирующей вики принадлежит @lhunath и IIRC, предназначенному для замены ABS. См. также настроения, например. в unix.stackexchange.com/questions/242111/ хотя я не смог быстро найти канонический ABS, считающийся вредным. В основном это неясно и причудливо, а иногда утомительно многословно, а не просто неправильно. - person tripleee; 04.04.2018

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

введите здесь описание изображения

person Nasty Sushi    schedule 20.09.2015