2016-10-03 5 views
1

Я функция read_command определяется как:Bash подстановка переменной в функции

function read_command { 
    local __newline __lines __input __newstr __tmp i; 
    exec 3< "$*"; 
    __newline=$'\n'; 
    __lines=(); 
    while IFS= read <&3 -r __line && [ "$__line" != '####' ]; do 
     echo "$__line"; 
     __lines+=("$__line"); 
    done 
    while IFS= read <&3 -r __line && [ "$__line" != '####' ]; do 
     read -e -p "${__line#*:}$PS2" __input; 
     local ${__line%%:*}="$__input"; 
    done 
    __command=""; 
    for i in "${__lines[@]}"; do 
     __tmp=$(echo "${i}"); 
     __command="${__command} ${__newline} ${__tmp}"; 
    done 
    echo -e "$__command"; 
} 

В текущем каталоге есть файл с именем «тест», со следующим содержанием:

greet ${a:-"Bob"} 
greet ${b:-"Jim"} 
#### 
a: name of friend a 
b: name of friend b 
#### 

В терминале выполнена команда

read_command test 

Без ввода я ожидаю положить последнего утверждения быть:

greet Bob 
greet Jim 

Но то, что я получаю:

greet ${a:-"Bob"} 
greet ${b:-"Jim"} 

Что здесь не так?

Редактировать: Как предложил Дэвид, добавление eval работает в некоторых случаях, за исключением следующего.

j=1;i="export DISPLAY=:0 && Xephyr :${j}&";k=$(eval echo "$i"); 
echo $k 

экспорт DISPLAY =: 0

Я ожидаю K быть "экспорт DISPLAY =: 0 & & Xephyr: 1 &", что здесь не так? Edit: Я попытался с помощью следующей

k=$(eval "echo \"$i\"") 

Это ссылка на сценарий я работаю. https://gist.github.com/QiangF/565102ba3b6123942b9bf6b897c05f87

+0

Точки с запятой в конце строки являются излишними; в сценарии оболочки новая строка * или * точка с запятой достаточна в качестве разделителя команд. – tripleee

+0

Я просто следую примеру, в Интернете слишком много плохих примеров. – godblessfq

ответ

2

В течение первого while цикла, в echo "$__line", у вас есть __line='greet ${a:-"Bob"}'. Когда вы попытаетесь распечатать это, Bash не будет расширяться ${a:-"Bob"} в Bob. (Даже если вы удалите цитаты около $__line, этого не произойдет.) Чтобы получить этот эффект, вам нужно добавить eval, например, eval echo "$__line". К сожалению, eval поставляется со своей банкой червей, вы должны начать беспокоиться о взаимодействии между уровнями цитирования и т. Д.

+0

Как предотвратить «eval echo $ __ line» от выполнения команды в __line, см. Редактирование в вопросе. – godblessfq

+0

Это очень похоже на [XY Problem] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Какую проблему вы пытаетесь решить с помощью этого кода? Это также выглядит нечетко, как http://mywiki.wooledge.org/BashFAQ/050 – tripleee

+0

Альтернативой для cheat.sh является использование замены шаблона, но это менее удобно. (https://github.com/tests-always-included/mo) – godblessfq

Смежные вопросы