2012-02-03 25 views
3

私はシェルスクリプト変数を使用してファイルから文字列を読み込んで、関数内で値を持つ変数を代用したいシェル解析文字列

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

が重複する可能性を](http://stackoverflow.com/questions/2900707/lazy-evaluation-in-bash) –

答えて

1

一般に、私はKent's answerまたはthis answerに示されているようなsed/awkを使用して、検索と置換の方法に行きます。

シェルのみのアプローチを希望する場合、標準的な方法は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

この「評価」は私が望んだものでした。それは本当に危険ですが、私のスクリプトの唯一のユーザーは私です。私がばかだと、私には恥がある。 – 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