Я использовал следующий способ выполнения набора файлов сценариев Bash в текущем сеансе Bash:

source ~/myScripts/{assignments.sh,nginx_conf.sh,php_conf.sh,drush_install.sh}

Мне неудобно его поддерживать. Некоторая вертикальная коллекция лучше. Псевдокод:

assignments.sh
nginx_conf.sh
php_conf.sh
drush_install.sh

Как бы вы сделали это по вертикали?

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

Обновить

Теперь я понимаю, что моя однострочная операция source была обречена на провал, поскольку в Bash 4.3.48(1) интерпретатор Bash оценивает source таким образом, что может работать только с одним файлом, и любой другой файл за ним будет оцениваться как аргумент для первого файла (набор фигурных скобок {} не поможет в этом).

У меня сложилось впечатление, что это то же самое, что и с bash вместо source.

0
user9303970 10 Мар 2018 в 06:19

1 ответ

Лучший ответ

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

while read f; do
   source ~/myScripts/"$f"
done <<SRC_LIST
assignments.sh
nginx_conf.sh
php_conf.sh
drush_install.sh
so_forth.sh
SRC_LIST

Это также позволяет избежать проблемы source file [arguments], когда последующие имена файлов будут рассматриваться как аргументы для assignments.sh (если только вы не имели в виду последующие аргументы??). Список необходимо будет вручную обновлять в соответствии с тем, что находится в файловой системе.

Другим вариантом было бы пропустить утомительное перечисление файлов и добавить их; это предполагает, что все совпадающие файлы в каталоге могут и должны быть получены (поэтому нельзя смешивать другие случайные *.sh файлы, которые не должны быть источником). Однако это осложняется крайним случаем, когда ни один файл не соответствует глобусу, и в этом случае bash по умолчанию передает буквальное имя файла ~/myScripts/*.sh в источник, поэтому это необходимо обойти. (временно, если необходимо) и ничего не найдено, если совпадений нет:

REVERT=$(shopt -p nullglob)
shopt -s nullglob
for f in ~/myScripts/*.sh; do
    source "$f"
done
$REVERT

С этим методом имена файлов должны быть названы таким образом, чтобы glob соответствовал им в правильном порядке, если есть порядок, в котором файлы должны быть получены. (В ZSH не нужны вызовы shopt как вместо этого for f in ~/myScripts/*.sh(N); do будет достаточно для выполнения нулевого глобуса. Другие оболочки будут различаться тем, как они обрабатывают глобусы и что делать, если ничего не совпадает.)

5
thrig 7 Фев 2018 в 17:19
Спасибо триг. Пожалуйста, добавьте несколько слов о том, почему вы использовали read f? А также, если heredoc идет после done, как он все еще работает?
 – 
user9303970
7 Фев 2018 в 11:37
read f — это то, как строки считываются в переменную. heredoc ни в каком смысле не "работает"; оболочка анализирует его и отправляет содержащиеся в нем данные в цикл
 – 
thrig
7 Фев 2018 в 17:21