2012-02-03 2 views
3

я прочитал строки из файла с переменным сценарием оболочки, и хочу заменить переменные со значениями в функции какShell синтаксического анализ строка

hello.txt: 
------------- 
Hello $NAME 


a.sh 
------------- 
function printout 
{ 
    echo ???somehow_parse??? $1 
} 

NAME=Joe 
printout "$(cat hello.txt)" 
NAME=Nelly 
printout "$(cat hello.txt)" 

пример не лучший, но он описывает мою проблему. Другими словами: могу ли я использовать оболочку в качестве механизма шаблона?

Я использую ksh.

+0

возможно дубликат [Ленивые оценки в Bash ] (http://stackoverflow.com/questions/2900707/lazy-evaluation-in-bash) –

ответ

1

В общем, я бы пошел на поиск и заменил подход, используя sed/awk, такой как показано в Kent's answer или this answer.

Если вы хотите использовать только оболочку, тогда стандартным способом будет использование eval. Однако это создает угрозу безопасности. Например:

[[email protected]]$ cat hello.txt 
hello $NAME; uname -a 
[[email protected]]$ NAME="shawn" 
[[email protected]]$ eval echo "`cat hello.txt`" # DO NOT DO THIS! 
hello shawn 
Linux SOMEHOST 2.6.9-101.ELsmp #1 SMP Fri May 27 18:57:30 EDT 2011 i686 i686 i386 GNU/Linux 

Обратите внимание, как команда может быть введена в шаблон!

Однако вы можете снизить риск использования этого подхода:

[[email protected]]$ eval "OUT=\"`cat hello.txt`\"" 
[[email protected]]$ echo $OUT 
hello shawn; uname -a 

Обратите внимание, что это еще не несложный, как команды до сих пор могут быть введены с помощью $(cmd) или `cmd`.

Одним словом, вы должны использовать eval, только если вы понимаете риски и можете контролировать/ограничивать доступ к файлам шаблонов.

Вот пример того, как это может быть применен в сценарии:

function printout { 
    FILENAME=$1 
    eval "OUT=\"`cat $FILENAME`\"" 
    echo $OUT 
} 

NAME=Joe 
printout hello.txt 
NAME=Nelly 
printout hello.txt 
+0

Этот 'eval' был тем, что я хотел. Это уверенно рискованно, но единственным пользователем моего сценария является я. Если я дурак, стыдись меня. – torbatamas

0

нравится это?

kent$ head hello.txt t.sh 
==> hello.txt <== 
hello $name 

==> t.sh <== 
#!/bin/bash 

function printout 
{ 
    echo $1|awk -v name="$name" 'gsub(/\$name/,name)' 
} 
name=xxx 
printout "$(cat hello.txt)" 
name=yyy 
printout "$(cat hello.txt)" 

запустить его:

kent$ ./t.sh 
hello xxx 
hello yyy 
1

Если вы уверены, что содержимое файла шаблона является полностью безопасным, то есть, он не содержит строку, чтобы выполнить команду, которая может нанести вред ваш компьютер, то вы можете использовать eval:

#!/bin/bash 
NAME=Joe 
TEMPLATE=$(cat hello.txt) 
eval "echo $TEMPLATE" 
NAME=Nelly 
eval "echo $TEMPLATE" 

Пример вывода:

HELLO Joe 
HELLO Nelly 
0

Я думаю, самым простым решением является использование утилиты basename.

Например, если у вас есть следующая строка: a='/home/you/stuff/myfile.txt' вы могли бы использовать такие команды, как:

dirname $a 
basename $a 
basename $a .txt 

и получить вывод, который выглядит следующим образом:

/home/you/stuff 
myfile.txt 
myfile 
Смежные вопросы