Не могу понять, как исправить жалобу shellcheck, что я не должен использовать glob в качестве команды при запуске одного скрипта из другого
Пример скрипта:
#!/bin/bash
printf '1\n1\n1\n1\n' | ./script2*.sh >/dev/null 2>/dev/null
Shellcheck возвращает следующее:
In script1.sh line 3:
printf '1\n1\n1\n1\n' | ./script2*.sh >/dev/null 2>/dev/null
^-- SC2211: This is a glob used as a command name. Was it supposed to be in ${..}, array, or is it missing quoting?
Согласно https://github.com/koalaman/shellcheck/wiki/SC2211, не должно быть никаких исключений из этого правила.
В частности, он предлагает "Если вы хотите указать имя команды с помощью glob, например, чтобы не указывать жесткую версию кода в./myprogram-*/foo, сначала разверните массив или параметры, чтобы разрешить обработку случаев совпадений 0 или 2+".
Причина, по которой я в первую очередь использую глобус, заключается в том, что я добавляю или изменяю дату к любому сценарию, который я только что создал или изменил. Интересно, что когда я использую "bash script2*.sh" вместо "./script2*.sh", жалоба исчезает.
Я исправил проблему, или я обманываю проверку оболочки, чтобы игнорировать проблему, которую нельзя игнорировать? Если я использую неверный синтаксис bash, как я могу выполнить другой скрипт, на который нужно сослаться, чтобы правильно использовать глоб?
1 ответ
Проблема в том, что ./script2*.sh
может закончиться бегом
./script2-20171225.sh ./script2-20180226.sh ./script2-copy.sh
что является странным и, вероятно, непреднамеренным действием, особенно если сценарий смущен такими аргументами или если вы хотите, чтобы ваш самый последний файл использовался. Ваше "исправление" имеет ту же фундаментальную проблему.
Предложение, которое вы упоминаете, будет иметь вид:
array=(./script2*.sh)
[ "${#array[@]}" -ne 1 ] && { echo "Multiple matches" >&2; exit 1; }
"${array[0]}"
и защититься от этой проблемы.
Поскольку вы, похоже, предполагаете, что у вас когда-либо будет только один соответствующий файл, который будет вызван без параметров, вы можете превратить это в функцию:
runByGlob() {
if (( $# != 1 ))
then
echo "Expected exactly 1 match but found $#: $*" >&2
exit 1
elif command -v "$1" > /dev/null 2>&1
then
"$1"
else
echo "Glob is not a valid command: $*" >&2
exit 1
fi
}
whatever | runByGlob ./script2*.sh
Теперь, если у вас когда-либо будет ноль или несколько подходящих файлов, он будет прерван с ошибкой, вместо того, чтобы потенциально запустить неправильный файл со странными аргументами.