Как именно работают циклы bash?

У меня была похожая проблема; Пакет Scite debian находится вdebian/rules:

...
BUILD_DATE="$(date --utc --date="@${SOURCE_DATE_EPOCH:-$(date +%s)}" "+%b %d %Y %T")"
override CPPFLAGS += -DBUILD_DATE="\"$(BUILD_DATE)\""

%:
        dh $@

override_dh_auto_build:
        dh_auto_build --sourcedirectory=scintilla/gtk -- GTK3=1 $(BUILD_LUA)
        dh_auto_build --sourcedirectory=scite/gtk -- gnomeprefix=/usr GTK3=1 $(BUILD_LUA)
....

По сути, override_dh_auto_buildвызывает команду make, которая обнаруживает измененные исходные файлы и перестраивает только измененные. Однако, даже если debian/rulesустанавливает BUILD_DATE, выполнение:

fakeroot debian/rules -j$(nproc) override_dh_auto_build

... будет давать сбой в некоторых исходных файлах cpp, которые используют BUILD _DATE в качестве определения. Решение состоит в том, чтобы явно указать эту переменную в вызове командной строки:

fakeroot debian/rules -j$(nproc) CPPFLAGS+=-DBUILD_DATE="" override_dh_auto_build

... и тогда компиляция проходит (дополнительный бонус в том, что новый.deb не создается, так что вам не нужно ждать этого ). По сути, это помогает повторно запустить только процесс перестроения для измененных файлов, который дает вам.so/.exe, без упаковки.deb.

5
16.03.2021, 00:37
1 ответ

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

Для цикла forвы создаете строки для цикла, используя раскрытие фигурных скобок. Это расширение скобки должно быть расширено до того, как первая итерация цикла может быть запущена. Поскольку вы создаете такой огромный список слов (каждое из одного миллиарда целых чисел в диапазоне от 0 до 999999999 ), это, вероятно, займет некоторое время (и, вероятно, более 8 гигабайт оперативной памяти ).

Если вам действительно нужно выполнить такую ​​итерацию в bash, используйте вместо этого арифметический forцикл:

for (( i=0; i <= 999999999; ++i )); do echo hi; done

... или решить конкретный вопрос другим способом

yes hi | head -n 1000000000

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

25
18.03.2021, 22:25

Теги

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