Расширение строки - экранированная кавычечная переменная в значение
Чтобы начать, вот скрипт, который я запускаю, чтобы получить ошибочную строку:
# sed finds all sourced file paths from inputted file.
#
# while reads each match output from sed to $SOURCEFILE variable.
# Each should be a file path, or a variable that represents a file path.
# Any variables found should be expanded to the full path.
#
# echo and calls are used for demonstractive purposes only
# I intend to do something else with the path once it's expanded.
PATH_SOME_SCRIPT="/path/to/bash/script"
while read -r SOURCEFILE; do
echo "$SOURCEFILE"
"$SOURCEFILE"
$SOURCEFILE
done < <(cat $PATH_SOME_SCRIPT | sed -n -e "s/^\(source\|\.\|\$include\) //p")
Вы также можете использовать следующее, чтобы проверить это как фиктивные данные:
[ /path/to/bash/script ]
#!/bin/bash
source "$HOME/bash_file"
source "$GLOBAL_VAR_SCRIPT_PATH"
echo "No cow powers here"
Для экипажа, в основном while
Цикл выплевывает следующее на макет данных:
"$HOME/bash_file"
bash: "$HOME/bash_file": no such file or directory
bash: "$HOME/bash_file": no such file or directory
"$GLOBAL_VAR_SCRIPT_PATH"
"$GLOBAL_VAR_SCRIPT_PATH": command not found
"$GLOBAL_VAR_SCRIPT_PATH": command not found
Мой вопрос, можете ли вы заставить переменную правильно расширяться, например, напечатать "/home//bash_file" и "/extended/variable/path"? Я должен также заявить, чтохотяeval
Работы я не собираюсь использовать из-за его потенциальной ненадежности.
Подсказка, что любое значение переменной используется в cat | sed
будет доступен глобально, в том числе для вызывающего скрипта, так что это не потому, что скрипт не может вызвать значение переменной.
Первая попытка решения
Используя анубхаву envsubst
решение:
SOMEVARIABLE="/home/nick/.some_path"
while read -r SOURCEFILE; do
echo "$SOURCEFILE"
envsubst <<< "$SOURCEFILE";
done < <(echo -e "\"\$SOMEVARIABLE\"\n\"$HOME/.another_file\"")
Это выводит следующее:
"$SOMEVARIABLE"
""
"/home/nick/.another_file"
"/home/nick/.another_file"
К сожалению, это не расширяет переменную! О, Боже:(
Вторая попытка решения
На основании первой попытки:
export SOMEVARIABLE="/home/nick/.some_path"
while read -r SOURCEFILE; do
echo "$SOURCEFILE"
envsubst <<< "$SOURCEFILE";
done < <(echo -e "\"\$SOMEVARIABLE\"\n\"$HOME/.another_file\"")
unset SOMEVARIABLE
который дает результаты, которые мы хотели без eval
и без возни с глобальными переменными (все равно слишком долго), ура!
Хорошие призеры были далее предложены с использованием eval
(хотя потенциально небезопасно), который можно найти в этом ответе и здесь (ссылка любезно предоставлена расширенными комментариями Анубхавы).
2 ответа
Мой вопрос, можете ли вы заставить переменную правильно расширяться, например, print
"/home//bash_file"
а также"/expanded/variable/path"
?
Да, вы можете использовать envsubst
программа, которая подставляет значения переменных среды:
while read -r sourceFile; do
envsubst <<< "$sourceFile"
done < <(sed -n "s/^\(source\|\.\|\$include\) //p" "$PATH_SOME_SCRIPT")
Я думаю, что вы спрашиваете, как рекурсивно расширить переменные в Bash. Пытаться
expanded=$(eval echo $SOURCEFILE)
внутри вашей петли. eval
запускает расширенную команду, которую вы даете. поскольку $SOURCEFILE
не в кавычках, он будет расширен, например, до $HOME/whatever
, Тогда eval
расширит $HOME
прежде чем передать его echo
, echo
распечатает результат, и expanded=$(...)
поместит напечатанный результат в $expanded
,