Выполнить команду, которая является результатом выполнения сценария, имя которого находится в переменной
При проводке этот вопрос изначально, я полностью misworded его, получая другой, разумный, но другой вопрос, который правильно ответил здесь.
Ниже приводится правильная версия вопроса, который я изначально хотел задать.
В одном из моих сценариев Bash есть точка, в которой у меня есть переменная SCRIPT
который содержит /path/to/an/exe
который при выполнении выводит line to be executed
.
Что в конечном итоге нужно сделать моему сценарию, так это выполнить это line to be executed
. Следовательно, последняя строка сценария
$($SCRIPT)
так что $SCRIPT
расширяется до /path/to/an/exe
, а также $(/path/to/an/exe)
выполняет исполняемый файл и возвращает line to be executed
, который затем выполняется.
Однако бег shellcheck
на скрипте возникает эта ошибка:
In setscreens.sh line 7:
$($SCRIPT)
^--------^ SC2091: Remove surrounding $() to avoid executing output.
For more information:
https://www.shellcheck.net/wiki/SC2091 -- Remove surrounding $() to avoid e...
Есть ли способ переписать это $($SCRIPT)
более подходящим способом? eval
здесь не очень помогает.
4 ответа
Если сценарий выводит командную строку оболочки для выполнения, правильный способ сделать это:
eval "$("$SCRIPT")"
$($SCRIPT)
будет работать только в том случае, если команда может быть полностью вычислена, не используя ничего, кроме разделения слов и расширения имени пути, что обычно является редкой ситуацией. Если вместо этого программа выводит, например,grep "Hello World"
или cmd > file.txt
тогда тебе понадобится eval
или эквивалент.
Вы можете упростить это, установив команду, которая будет выполняться как позиционный аргумент в вашей оболочке, и выполнить ее из командной строки
set -- "$SCRIPT"
и теперь запустим результат, полученный разложением SCRIPT
, выполнив указанные ниже действия в командной строке.
"$@"
Это работает, если ваш вывод из SCRIPT
содержит несколько слов, например настраиваемые флаги, которые необходимо запустить. Поскольку это выполняется в вашей текущей интерактивной оболочке, убедитесь, что запускаемая команда не уязвима для внедрения кода. Вы можете сделать один шаг осторожности и запустить свою команду в суб-оболочке, чтобы не допустить воздействия на вашу родительскую среду, выполняя( "$@" ; )
Или используйте shellcheck disable=SCnnnn
чтобы отключить предупреждение и воспользоваться случаем, чтобы прокомментировать явное намерение, вместо того, чтобы уклоняться от обнаружения, скрываясь за промежуточной переменной или массивом аргументов.
#!/usr/bin/env bash
# shellcheck disable=SC2091 # Intentional execution of the output
"$("$SCRIPT")"
Отключение shellcheck с помощью комментария проясняет намерение и сообщает, что сомнительный код не является ошибкой, а является осознанным выбором дизайна реализации.
Вы можете сделать это за 2 шага
command_from_SCRIPT=$($SCRIPT)
$command_from_SCRIPT
и он чистый в Shellcheck