Расширение строки - экранированная кавычечная переменная в значение

Чтобы начать, вот скрипт, который я запускаю, чтобы получить ошибочную строку:

# 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,

Другие вопросы по тегам