2012-01-12 12 views
6

Tôi đang cố gắng tự động hóa việc thiết lập tạo trang web cho máy chủ phát triển nội bộ của chúng tôi.Tôi có thể tạo tập lệnh từ một mẫu bằng cách sử dụng bash như thế nào?

Hiện tại, điều này bao gồm việc tạo người dùng hệ thống, người dùng mysql, cơ sở dữ liệu và cấu hình apache. Tôi biết làm thế nào tôi có thể làm tất cả mọi thứ trong một tập tin bash duy nhất, nhưng tôi muốn hỏi nếu có một cách để sạch hơn tạo ra các cấu hình apache.

Về cơ bản những gì tôi muốn làm là tạo tệp conf dựa trên mẫu, tương tự như sử dụng printf. Tôi chắc chắn có thể sử dụng printf, nhưng tôi nghĩ rằng có thể có một cách sạch hơn, sử dụng sed hoặc awk.

Lý do tôi không chỉ muốn sử dụng printf là vì cấu hình apache dài khoảng 20 dòng và sẽ chiếm hầu hết các tập lệnh bash, cũng như làm cho khó đọc hơn.

Mọi trợ giúp đều được đánh giá cao.

+0

Giữ riêng tệp httpd.conf nguyên mẫu và có tập lệnh chỉnh sửa tệp mẫu (nguyên mẫu) vào tệp thực tế khi tệp chạy. Tất nhiên, điều đó có nghĩa là hai tệp được yêu cầu - tập lệnh và mẫu. Nhưng nó giữ hai tập tin phân tách hợp lý thực sự rời rạc. –

+0

Vâng, đó là những gì tôi đã yêu cầu (xin lỗi nếu nó không rõ ràng) nhưng tôi cần phải biết làm thế nào để làm điều đó. Tôi nghĩ câu trả lời của Péter Varga sẽ đưa tôi đến đó với một số điều chỉnh. – Brendan

Trả lời

7

Chọn một cách để đánh dấu tham số. Một khả năng là :parameter:, nhưng bất kỳ cặp dấu tương tự nào sẽ không bị nhầm lẫn với văn bản hợp pháp cho (các) tệp mẫu là tốt.

Viết một kịch bản sed (trong sed, awk, perl ...) tương tự như sau:

sed -e "s/:param1:/$param1/g" \ 
    -e "s/:param2:/$param2/g" \ 
    -e "s/:param3:/$param3/g" \ 
    httpd.conf.template > $HTTPDHOME/etc/httpd.conf 

Nếu bạn nhận được đến một điểm mà bạn cần thỉnh thoảng phải chỉnh sửa một cái gì đó và đôi khi không , bạn có thể tìm thấy nó dễ dàng hơn để tạo ra các sed lệnh có liên quan trong một tập lệnh và sau đó thực hiện điều đó:

{ 
echo "s/:param1:/$param1/g" 
echo "s/:param2:/$param2/g" 
echo "s/:param3:/$param3/g" 
if [ "$somevariable" = "somevalue" ] 
then echo "s/normaldefault/somethingspecial/g" 
fi 
} >/tmp/sed.$$ 
sed -f /tmp/sed.$$ httpd.conf.template > $HTTPDHOME/etc/httpd.conf 

Lưu ý rằng bạn nên sử dụng một cái bẫy để đảm bảo tạm thời không o utlive tính hữu dụng của nó:

tmp=/tmp/sed.$$ # Consider using more secure alternative schemes 
trap "rm -f $tmp; exit 1" 0 1 2 3 13 15 # aka EXIT HUP INT QUIT PIPE TERM 
...code above... 
rm -f $tmp 
trap 0 

Điều này đảm bảo rằng tệp tạm thời của bạn bị xóa khi tập lệnh thoát cho hầu hết các tín hiệu hợp lý. Bạn có thể duy trì trạng thái thoát khác 0 từ các lệnh trước đó và sử dụng exit $exit_status sau lệnh trap 0.

+0

Điều này là hoàn hảo, cảm ơn bạn. – Brendan

1

Sử dụng sed ví dụ như

sed s/%foo%/$foo/g template.conf > $newdir/httpd.conf 
+0

Làm cách nào để thay thế nhiều điểm đánh dấu bằng nhiều giá trị khác nhau? nghĩa là% foo% được thay thế bằng $ foo và% bar% được thay thế bằng $ bar. – Brendan

+1

Dễ dàng: 'sed 's /% foo%/$ foo/g; s /% bar%/$ bar/g" ' – tripleee

4

Tôi ngạc nhiên không ai đề cập đến tài liệu ở đây. Điều này có lẽ không phải là những gì OP muốn, nhưng chắc chắn là một cách để cải thiện tính dễ đọc của kịch bản mà bạn đã bắt đầu. Chỉ cần cẩn thận để thoát khỏi hoặc parametrize đi bất kỳ cấu trúc mà vỏ sẽ thực hiện thay thế trên.

#!/bin/sh 
# For example's sake, a weird value 
# This is in single quotes, to prevent substitution 
literal='$%"?*=`!!' 
user=me 

cat <<HERE >httpd.conf 
# Not a valid httpd.conf 
User=${user} 
Uninterpolated=${literal} 
Escaped=\$dollar 
HERE 

Trong ngữ cảnh này, tôi sẽ đề xuất $ {variable} so với biến $ tương đương để rõ ràng và tránh mọi sự mơ hồ có thể xảy ra.