2015-01-13 23 views
28

Tôi đang cố gắng để tạo ra một tập tin kịch bản sử dụng chuỗi thay thế từ ENV mà còn muốn ngăn chặn một số từ thoátLàm thế nào để tránh các biến mở rộng heredoc?

export PLACEHOLDER1="myPlaceholder1Value" 
export PLACEHOLDER2="myPlaceholder2Value" 
sudo /bin/su -c "cat <<EOF> /etc/init.d/my-script 
#!/bin/bash 
# 
### BEGIN INIT INFO 
# Provides:   my-script 
# Required-Start: \$remote_fs \$syslog 
# Required-Stop:  \$remote_fs \$syslog 
# Should-Start:  \$network \$time 
# Should-Stop:  \$network \$time 
# Default-Start:  2 3 4 5 
# Default-Stop:  0 1 6 
# Short-Description: blabla 
# Description:  bla bla desc 
# 
### END INIT INFO 
# 
myvariable_1=toto$PLACEHOLDER1 
myvariable_2=titi$PLACEHOLDER2 
myvariable_final=\"dynamicvar=\${myvariable_1},\${myvariable_2}\" 
EOF 
" 

Nó là kết quả, trong đó là không tốt như myvariable_final không trốn thoát và thay thế như một từ phụ thuộc init script ($ remote_fs, $ syslog, $ mạng, $ thời gian)

#!/bin/bash 
# 
### BEGIN INIT INFO 
# Provides:   my-script 
# Required-Start: 
# Required-Stop: 
# Should-Start: 
# Should-Stop: 
# Default-Start:  2 3 4 5 
# Default-Stop:  0 1 6 
# Short-Description: blabla 
# Description:  bla bla desc 
# 
### END INIT INFO 
# 
myvariable_1=totomyPlaceholder1Value 
myvariable_2=titimyPlaceholder2Value 
myvariable_final="dynamicvar=," 

Nếu tôi cố gắng để đặt một dấu chéo ngược \ đằng sau dolla rs $, tôi quản lý để tránh sự thay thế nhưng tôi nhận được một dấu chéo ngược không mong muốn \:

export PLACEHOLDER1="myPlaceholder1Value" 
export PLACEHOLDER2="myPlaceholder2Value" 
sudo /bin/su -c "cat <<EOF> /etc/init.d/my-script 
#!/bin/bash 
# 
### BEGIN INIT INFO 
# Provides:   my-script 
# Required-Start: \$\remote_fs \$\syslog 
# Required-Stop:  \$remote_fs \$syslog 
# Should-Start:  \$network \$time 
# Should-Stop:  \$network \$time 
# Default-Start:  2 3 4 5 
# Default-Stop:  0 1 6 
# Short-Description: blabla 
# Description:  bla bla desc 
# 
### END INIT INFO 
# 
myvariable_1=toto$PLACEHOLDER1 
myvariable_2=titi$PLACEHOLDER2 
myvariable_final=\"dynamicvar=\$\{myvariable_1},\$\{myvariable_2}\" 
EOF 
" 

kết quả trong:

#!/bin/bash 
# 
### BEGIN INIT INFO 
# Provides:   my-script 
# Required-Start: $\remote_fs $\syslog 
# Required-Stop: 
# Should-Start: 
# Should-Stop: 
# Default-Start:  2 3 4 5 
# Default-Stop:  0 1 6 
# Short-Description: blabla 
# Description:  bla bla desc 
# 
### END INIT INFO 
# 
myvariable_1=totomyPlaceholder1Value 
myvariable_2=titimyPlaceholder2Value 
myvariable_final="dynamicvar=$\{myvariable_1},$\{myvariable_2}" 

Wanted/kết quả tham dự whould đã:

#!/bin/bash 
# 
### BEGIN INIT INFO 
# Provides:   my-script 
# Required-Start: $remote_fs $syslog 
# Required-Stop:  $remote_fs $syslog 
# Should-Start:  $network $time 
# Should-Stop:  $network $time 
# Default-Start:  2 3 4 5 
# Default-Stop:  0 1 6 
# Short-Description: blabla 
# Description:  bla bla desc 
# 
### END INIT INFO 
# 
myvariable_1=totomyPlaceholder1Value 
myvariable_2=titimyPlaceholder2Value 
myvariable_final="dynamicvar=${myvariable_1},${myvariable_2}" 

được giải quyết bằng cách đặt báo giá xung quanh EOF như dưới đây và sử dụng dấu gạch chéo để kiểm soát thoát khi cần thiết

export PLACEHOLDER1="myPlaceholder1Value" 
export PLACEHOLDER2="myPlaceholder2Value" 
sudo /bin/su -c "cat << 'EOF' > /etc/init.d/my-script 
#!/bin/bash 
# 
### BEGIN INIT INFO 
# Provides:   my-script 
# Required-Start: \$remote_fs \$syslog 
# Required-Stop:  \$remote_fs \$syslog 
# Should-Start:  \$network \$time 
# Should-Stop:  \$network \$time 
# Default-Start:  2 3 4 5 
# Default-Stop:  0 1 6 
# Short-Description: blabla 
# Description:  bla bla desc 
# 
### END INIT INFO 
# 
myvariable_1=toto$PLACEHOLDER1 
myvariable_2=titi$PLACEHOLDER2 
myvariable_final=\"dynamicvar=\${myvariable_1},\${myvariable_2}\" 
EOF 
" 

Trả lời

77

Chỉ cần sử dụng 'EOF' để ngăn chặn sự biến từ mở rộng:

sudo /bin/su -c "cat << 'EOF' > /etc/init.d/my-script 
#      ^^

Từ man bash:

Đây Documents

Đây là loại chuyển hướng hướng dẫn shell đọc đầu vào từ t ông nguồn hiện tại cho đến khi một dòng chỉ chứa dấu phân cách (không có khoảng trắng ở cuối) được nhìn thấy. Tất cả các dòng đọc đến thời điểm đó là sau đó được sử dụng làm đầu vào tiêu chuẩn cho một lệnh.

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

 <<[-]word 
       here-document 
     delimiter 

Không mở rộng tham số, 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 văn bản. Nếu bất kỳ ký tự nào trong từ được trích dẫn, dấu phân tách là kết quả của việc xóa trích dẫn trên từ và các dòng trong tài liệu tại đây không được mở rộng. Nếu chữ là không thể viện chứng, tất cả các dòng ở đây-tài liệu phải chịu tham số mở rộng, thay thế lệnh, và mở rộng số học.Trong trường hợp thứ hai , trình tự ký tự \ bị bỏ qua và \ phải được sử dụng để báo các ký tự \, $ và `.

+2

Trích dẫn xung quanh 'EOF' đã thực hiện các mẹo như với thoát, tôi có thể kiểm soát những gì được thay thế và wnat không được thay thế – TheCodeKiller

+1

@ TheCodeKiller đẹp! Nó khá phức tạp ... cho đến khi bạn biết điều đó :) Rất vui vì điều này hữu ích cho bạn! – fedorqui

1

khi sử dụng lệnh su đặt lệnh tự trong dấu ngoặc kép sigle và chỉ thoát khỏi $ với một dấu gạch chéo. các biến giữ chỗ phải đặt trong bối cảnh lệnh bash (ở đây sau su). vì vậy bạn cần phải làm sth như

su -c 'ph="ph"; cat <<EOF> script 
varinscript=$ph 
var=\${var} 
EOF' 
+0

Câu trả lời của bạn là tốt nhưng tôi muốn ngăn chặn việc đưa lại tất cả lệnh env/export VAR vào lệnh một lần nữa. – TheCodeKiller

Các vấn đề liên quan