Что происходит, когда файлы добавляются / удаляются в середине цикла sh «for f in *»?

Ваше соединение, вероятно, прервано брандмауэром из-за бездействия (отсутствие фреймов TCP, относящихся к соединению SSH). Попробуйте включить keep-alive.

В вашем / etc / ssh / ssh_config добавьте:

TCPKeepAlive yes
ServerAliveInterval 30
ServerAliveCountMax 10
5
26.04.2017, 00:29
2 ответа

Оболочка полностью определяет список значений для цикла перед запуском тела цикла. То есть:

  1. Оболочка строит путь, используя значение переменной search_dir.
  2. Оболочка собирает список имен файлов в указанном каталоге, чтобы построить список совпадений для шаблона подстановочных знаков.
  3. Оболочка выполняет тело цикла по очереди с каждым элементом списка совпадений.

Вы можете изменить значение переменной search_dir и изменить содержимое каталога во время выполнения цикла. Это не повлияет на файлы, на которые действует цикл.

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

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

Если вы хотите обрабатывать новые файлы по мере их создания, вам придется повторить цикл. Очевидно, что файлы могут быть созданы во время выполнения цикла или после того, как все предыдущие файлы были обработаны, поэтому скрипт должен будет продолжать работать вечно. Существуют инструменты для ожидания создания файла в каталоге. В Linux основным средством для этого является inotify; если вам нужно обрабатывать файлы по мере их создания, то вам должны помочь inotifywait или incron.Помните, что inotify только уведомляет вас о файлах, созданных (или измененных, или доступных в зависимости от вашего триггера) после запуска команд на основе inotify; вам также нужно будет позаботиться о ранее существующих файлах, и вы не можете просто сделать для записи в *; делать …; Выполнено; inotifywait …, поскольку файлы могут создаваться во время выполнения цикла или даже во время запуска команды inotifywait.

1
27.01.2020, 20:38

Когда оболочка доберется до оператора for-, она расширит значение $search_dirи выполнит подстановку имени файла, чтобы сгенерировать список записей каталога, которые будут повторяться. Это происходит только один раз, и если вещи в $search_dirисчезнут или если в этот каталог будут добавлены новые файлы/каталоги во время выполнения цикла, эти изменения не будут приняты.

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

for entry in "$search_dir"/*; do
    if [ -e "$entry" ]; then
        # operate on "$entry"
    else
        # handle the case that "$entry" went away
    fi
done

Как справедливо отмечает Стефан в комментариях, это лишний тест в большинстве случаев.

5
27.01.2020, 20:38

Теги

Похожие вопросы