2011-02-08 35 views
132

我試圖插一個bash定界符的內部變量:使用變量

var=$1 
sudo tee "/path/to/outfile" > /dev/null << "EOF" 
Some text that contains my $var 
EOF 

這不是工作,我會期望($ VAR字面上處理,不展開)。

我需要使用sudo tee,因爲創建文件需要sudo。做類似:

sudo cat > /path/to/outfile <<EOT 
my text... 
EOT 

不起作用,因爲> outfile在當前shell中打開文件,該文件不使用sudo。

+5

這是一個可以理解的混亂!如下所述,引用分隔符的任何部分都會關閉heredoc中的擴展(就像在''''中那樣),但* not *引用分隔符會使擴展開啓(就像它在'「」'中一樣)。 *然而,*您的直覺在Perl中是正確的,其中具有單引號標識符的heredoc表現得像在單引號中一樣,其中一個帶有雙引號標識符就像在雙引號中一樣,另一個帶有帶勾號標識符如果在反引號!參見: [perlop:<< EOF](http://perldoc.perl.org/perlop.html#%3c%3cEOF) –

回答

177

在回答你的第一個問題,有沒有參數替代,因爲你已經把分隔符引號 - the bash manual says

這裏,文件的格式爲:

 <<[-]word 
       here-document 
     delimiter 

無參數擴展,命令替換,算術擴展或 路徑名擴展在上執行。如果單詞中的任何字符均爲 引用,則分隔符是對單詞的引用刪除的結果,並且此文檔中的 行不會展開。如果單詞未加引號,則此文檔中的所有 行均經過參數擴展,命令替換和算術擴展。 [...]

如果更改使用<<EOF,而不是<< "EOF",你會發現,它的作品你的第一個例子。

在第二個示例中,shell僅使用參數cat調用sudo,並且重定向適用於原始用戶的輸出sudo cat

sudo sh -c "cat > /path/to/outfile" <<EOT 
my text... 
EOT 
+1

擴展適用於HEREDOC中的單引號變量。 – peter2108

+0

如果你感興趣,你也可以這樣做: '(cat>/path/to/outfile)<< EOF'代替'sudo sh -c ... << EOF' – Voltaire

+0

請告訴我burash在Bash這就是爲什麼這樣的好理由。 –

70

不要<<EOF使用引號:

var=$1 
sudo tee "/path/to/outfile" > /dev/null <<EOF 
Some text that contains my $var 
EOF 

變擴建是在這裏,文檔內的默認行爲,如果你嘗試它會工作。您通過引用標籤(使用單引號或雙引號)來禁用該行爲。