Как выполнить несколько файлов .sh в разных каталогах, используя *.sh

Tar по умолчанию записывает на стандартный вывод или читает из стандартного ввода, поэтому нет необходимости в символе дефиса для обозначения стандартного вывода/стандартного ввода. Просто оставьте параметр -f. Вы получили синтаксическую ошибку для --file= -из-за пробела между =и -. Длинные опции с --записываются --param=valueбез пробелов вокруг знака равенства.

3
26.04.2020, 22:20
4 ответа

Причина, по которой ваш код не работает, заключается в том, что происходит, когда расширяется шаблон подстановки имени файла.

Шаблон расширится до списка совпадающих путей. Код в вашем скрипте вызовет shс этим списком. Это означает, что он выполнит первое совпадающее имя как сценарий и передаст другие имена в качестве аргументов этому сценарию:

sh /var/scripts/dir/my_first.inc.sh /var/scripts/dir/my_second.inc.sh /var/scripts/dir/my_third.inc.sh

Вместо этого просто перебирайте совпадающие имена:

#!/bin/sh

for name in /var/scripts/*/my_*.inc.sh; do
    sh "$name"
done

Это предполагает, что каждое из совпадающих имен является сценарием, который должен выполняться с помощью sh(, а неbash). Если отдельные файлы исполняемые и имеют правильную строку #!-,затем удалите shиз вызова сценария в цикле выше. Если файлы являются «точечными сценариями», то есть сценарием, который должен быть получен, замените shна ., чтобы скрипт выполнялся в среде текущего скрипта.

Обратите внимание, что приведенный выше сценарий может быть сценарием sh(#!/bin/sh), поскольку он не использует никаких функций bash. Если другой скрипт является «точечным скриптом», то вам, очевидно, придется изменить его на #!/bin/bashили любой другой интерпретатор, необходимый для получения скриптов.

8
19.03.2021, 02:25

Вы можете использовать цикл forдля итерации (рекурсивно )по всем файлам оболочки в пути, найденном с помощью find, например:

for i in $(find /var/scripts/ -type f -name '*.sh')
  do sh "$i"
done
0
19.03.2021, 02:25

Я не знаю, лучшее ли это решение, но xargsв целом можно использовать для подобных вещей:

ls /var/scripts/*/my_*.inc.sh | xargs -I {} sh {}

Как указал @user000001, это не будет работать для имен файлов с символом новой строки.

2
19.03.2021, 02:25

Самый безопасный способ перебора файлов в сценариях оболочки (, включая bash ), — использовать расширение пути (подстановку )в цикле for. Правильный код:

for file in /var/scripts/*/my_*.inc.sh
do
  echo "Executing $file"
  "$file"
done

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

Если вы хотите выполнить рекурсивный поиск или использовать параметры, которые не могут быть предоставлены с помощью подстановки, find можно использовать с параметром -exec(ниже предполагается недавний поиск GNU):

find a/ -executable -type f -name '*.sh' -exec {} \;

Если поиск по-прежнему необходим, но вы и выполняете несколько команд для каждого файла, можно использовать read, но вы должны быть осторожны с параметрами для обработки всех имен файлов (ниже предполагается bash и GNU find):

#!/bin/bash
find a/ -executable -type f -name '*.sh' -print0 |
  while IFS= read -r -d $'\0' file
  do
    echo "Executing $file"
    "$file"
  done
3
19.03.2021, 02:25

Теги

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