Tar по умолчанию записывает на стандартный вывод или читает из стандартного ввода, поэтому нет необходимости в символе дефиса для обозначения стандартного вывода/стандартного ввода. Просто оставьте параметр -f
. Вы получили синтаксическую ошибку для --file= -
из-за пробела между =
и -
. Длинные опции с --
записываются --param=value
без пробелов вокруг знака равенства.
Причина, по которой ваш код не работает, заключается в том, что происходит, когда расширяется шаблон подстановки имени файла.
Шаблон расширится до списка совпадающих путей. Код в вашем скрипте вызовет 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
или любой другой интерпретатор, необходимый для получения скриптов.
Вы можете использовать цикл for
для итерации (рекурсивно )по всем файлам оболочки в пути, найденном с помощью find
, например:
for i in $(find /var/scripts/ -type f -name '*.sh')
do sh "$i"
done
Я не знаю, лучшее ли это решение, но xargs
в целом можно использовать для подобных вещей:
ls /var/scripts/*/my_*.inc.sh | xargs -I {} sh {}
Как указал @user000001, это не будет работать для имен файлов с символом новой строки.
Самый безопасный способ перебора файлов в сценариях оболочки (, включая 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