
Вот мой небольшой фрагмент bash-скрипта.
i=5
command='echo $i'
$command
Я хочу, чтобы этот скрипт печатал 5
, т.е. я хочу, чтобы он запускал echo и печатал 5. Но вместо этого он продолжает печатать $i
. Так как мне решить эту проблему?
решение1
Это было бы:
eval "$command"
Если вы хотите, чтобы содержимое $command
оценивалось как шелл-код.
Если вы не можете гарантировать, что это $command
не начнется с -
(что может привести к тому, eval
что некоторые оболочки будут bash
рассматривать это как опцию), вы можете запустить:
eval " $command"
вместо этого. Этот дополнительный начальный пробел не повлияет на способ разбора команды и не позволит $command
рассматривать ее как опцию, eval
если она начинается с -
. eval -- "$command"
также будет работать в некоторых оболочках (включая bash
), но не является POSIX (IIRC) и не будет работать, например, в dash
оболочке Bourne.
Обратите внимание, что, вероятно, вы $command
должны быть:
command='echo "$i"'
Если только вы не намеревались $i
подвергнуться разделению+глоб
Потенциально лучшим способом хранения кода в «переменных» было бы использование функций:
mycommand() { echo "$i"; }
(используется mycommand
вместо command
, так как command
это уже существующая команда).
Если $command
это break
/ continue
/ return
, поведение будет зависеть от оболочки.
Если вы хотите $command
сохранитьпростая команда, то есть список слов, первое из которых ищется как команда для выполнения со списком слов в качестве аргументов, вы бы использовали переменную массива:
command=('echo' '$i' "$i")
"${command[@]}"
Это запустит echo
, с echo
, $i
и содержимым в $i
качестве аргументов.
command='echo $i ;x /* '$i
$command
(со значением по умолчанию $IFS
) — это тот, который имел бы наименьший смысл. Там, $command
будет содержать строку. Первый $i
оставлен как есть, второй расширен (как вне одинарных кавычек), а затем эта строка будет подвергнута split+glob (как $command
не внутри двойных кавычек), результатом чего станет несколько слов, взятых какпростая командаснова.