2011-02-08 12 views
132

Tôi đang cố gắng để suy biến bên trong một heredoc bash:Sử dụng các biến bên trong một heredoc bash

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

này không làm việc như tôi mong đợi ($ var được xử lý theo nghĩa đen, không mở rộng).

Tôi cần sử dụng sudo tee vì việc tạo tệp yêu cầu sudo. Làm một cái gì đó như:

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

Không hoạt động, bởi vì> tệp mở ra tệp hiện tại, không sử dụng sudo.

+5

Đây là một sự nhầm lẫn dễ hiểu! Như đã lưu ý dưới đây, trích dẫn bất kỳ phần nào của dấu phân cách tắt mở rộng trong heredoc (như thể nó nằm trong ''''), nhưng * không * trích dẫn dấu tách mở rộng (như thể nó nằm trong '" "'). * Tuy nhiên, * trực giác của bạn là chính xác trong Perl, nơi một heredoc với định danh đơn được định nghĩa giống như trong dấu nháy đơn, một với một mã định danh kép được trích dẫn như trong dấu ngoặc kép và một với mã nhận dạng được đánh dấu sau nếu trong backticks! Xem: [perlop: << EOF] (http://perldoc.perl.org/perlop.html#%3c%3cEOF) –

Trả lời

177

Trong câu trả lời cho câu hỏi đầu tiên của bạn, không có tham số thay vì bạn đã đặt dấu phân cách trong dấu ngoặc kép - the bash manual says:

Định dạng của ở đây-văn là:

 <<[-]word 
       here-document 
     delimiter 

Không tham số mở rộng, thay thế lệnh, mở rộng số học hoặc mở rộng tên đường dẫn được thực hiện trên từ. Nếu bất kỳ ký tự nào trong từ là được trích dẫn, thì dấu cách delimiter là kết quả của việc xóa trích dẫn theo từ và các dòng trong tài liệu tại đây không được mở rộng. Nếu từ không được bỏ phiếu, tất cả các dòng của tài liệu này phải chịu sự mở rộng tham số, thay thế lệnh và mở rộng số học. [...]

Nếu bạn thay đổi ví dụ đầu tiên để sử dụng <<EOF thay vì << "EOF" bạn sẽ thấy rằng nó hoạt động.

Trong ví dụ thứ hai, vỏ chỉ gọi sudo chỉ với thông số cat và chuyển hướng áp dụng cho đầu ra của sudo cat làm người dùng ban đầu. Nó sẽ có tác dụng nếu bạn cố gắng:

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

Mở rộng hoạt động cho các biến được trích dẫn một lần trong HEREDOC. – peter2108

+0

Nếu bạn quan tâm bạn cũng có thể làm điều này là: '(cat>/path/to/outfile) << EOF' thay cho' sudo sh -c ... << EOF' – Voltaire

+0

Hãy cho tôi biết burried in Bash là một lý do chính đáng tại sao điều này là như vậy. –

70

Không sử dụng dấu ngoặc kép với <<EOF:

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

mở rộng Variable là hành vi mặc định bên trong đây-docs. Bạn vô hiệu hóa hành vi đó bằng cách trích dẫn nhãn (với dấu nháy đơn hoặc kép).