2014-11-25 69 views
1

我已經從文件中讀取了一行bash代碼,並且我想將它發送給日誌。爲了使它更有用,我想發送該行的可變展開版本。如何強制bash對字符串進行可變擴展?

我只想擴展shell變量。我不希望管道被解釋,也不希望產生任何邊過程,比如當擴展與$(rm -r /)一行時。

我知道變量擴展是非常深入編織到bash中。我希望有一種方法可以執行只是擴展,沒有任何副作用,可能來自管道,外部程序和 - 也許這裏的文件。可能是eval

#!/bin/bash 
linenr=42 
line=`sed "${linenr}q;d" my-other-script.sh` 
shell-expand $line >>mylog.log 

我想要一種只擴展shell變量的方法。 如果x=aa="example"那麼我想下面的擴展:

echo $x應該echo a

echo ${a}應該echo example

touch ${!x}.txt應該touch example.txt

if [ ((${#a} - 6 )) -gt 10 ]; then echo "Too long string"應該if [ 1 -gt 10 ]; then echo "Too long string"

echo "\$a and \$x">/dev/null應該echo "\$a and \$x>dev/null"

回答

0

你是絕對正確的,這是非常危險的,使用的是bash。事實上,你的命令受到你的問題困擾。

讓我們來詳細瞭解您的腳本:

#!/bin/bash 
line=`sed "${42}q;d" my-other-script.sh` 
shell-expand $line >>mylog.log 

戰略經濟對話可以產生輸出的多行,所以它是一種誤導使用的名稱line

那麼你並沒有引述$線,這可能會影響晦澀:

$ x='| grep x' 
$ ls -l $x 
ls: cannot access |: No such file or directory 
ls: cannot access grep: No such file or directory 
-rw-rw-r-- 1 foo bar 34493 Nov 19 18:51 x 
$ 

在這種情況下不執行管,但傳遞給程序LS。 如果您有不可信的輸入,編寫健壯的shell腳本非常困難。

使用eval是邪惡的 - 我永遠不會建議使用它,特別是爲了這樣的目的!

另一種方法是在perl中迭代$ ENV數組,並用env值替換所有的env鍵。這樣你可以更好地控制可能發生的事情。

+0

非常感謝您的回答。我已經知道Bash的評價不合適,否則我不會問這個問題。其實我下意識地想着'R'的評價(而'R'是一種主要功能的編程語言,所以幾乎沒有任何與評估相關的副作用)。對錯誤信息抱歉。 – 2014-11-25 18:31:08

+0

'sed「$ {42} q; d」my-other-script.sh'是一個錯字;它應該是:'sed「42q; d」my-other-script.sh'或更好 - 我把它放在我的答案上。我明白,這個'sed'調用只能產生一行。 – 2014-11-25 18:41:30

+0

您可以在一個子命令中使用兩個回聲:'echo「$(echo」我的用戶名是$ USER「)」'但引用必須小心。 – 2014-11-25 18:46:40

相關問題