我有很多程序,並且所有程序在其配置文件中都有一些相同的值(大多數(如果不是全部)都在 中/etc
)。
假設它是主機名,儲存在 Apache、Postfix、SQL、clamAV 等的設定檔中......有時我需要更改這些值。我現在要做的就是編輯所有這些文件並查找並用新值替換以前的值。
我想在一處更改它,並正確設置所有這些文件。我想到了bash的export
變數、source
指令或類似的東西;但是,由於配置文件不可執行,我認為它不會起作用。
推薦的方法是什麼?
答案1
顯然,您必須確定要管理的所有參數以及它們出現的所有位置。 (呃。) 你已經知道了。
以下方法可能會讓您走上正確的道路:
選擇一個永遠不會出現在設定檔之一中的字串。 (這聽起來像你必須第一次嘗試就做好。事實並非如此。如果您選擇字串(例如,
@@
)並且稍後需要在其中一個檔案中使用該字串,則可以修復它。您只需要重做很多設定。例如,很久以前,Unix有一個版本控制系統,稱為原始碼控制系統(SCCS);它將字串用作
@(#)
永遠不會自然出現在文件中的字串。據我所知,SCCS 不再使用(至少不多),所以使用它應該是安全的@(#)
。或者您可以使用類似!user2461440?
、 或任何您的真實姓名。您可以包含控製字元;例如,Ctrl+A或Ctrl+ G。選擇參數佔位符的命名約定。這可以是一些簡單明了的東西,例如,,,
@(#){HOSTNAME}
等等。@(#){IP}
@(#){GATEWAY}
建立所有設定檔的範本版本,例如
apache.template
等。您應該將這些(以及以下內容)放在安全、偏僻的地方,例如/root
.寫一個像這樣的腳本:
HOST=Zanzibar IP=10.11.12.42 ︙ LOG=/var/log/lumber ︙ fullpath[apache]=/etc/apache.conf fullpath[postfix]=/etc/postfix/configuration ︙ for file in apache postfix … do path=${fullpath[$file]} sed -e "s/@(#){HOSTNAME}/$HOST/g" \ -e "s/@(#){IP}/$IP/g" \ ︙ -e "s|@(#){LOG}|$LOG|g" \ ︙ "$file.template" > "$path.new" && mv "$path" "$path.bak" && mv "$path.new" "$path" done
@(#){LOG}
請注意,替換為的子命令$LOG
使用了不同的分隔符號 (|
),因為該$LOG
值包含/
s。因此,請注意,字串@(#)
不得包含此分隔符號 (|
)。 (當然,它不能包含標準 (/
) 分隔符號。)陣列(例如,
fullpath[apache]
)並非在所有 shell 中都有效。如果您沒有 bash 或其他支援陣列的 shell,則需要調整腳本來模擬或解決它們。您可能需要向腳本新增
chown
和命令才能正確設定檔案的系統屬性。chmod
或者,如果你真的真的確保您的腳本正常工作,您可以修改它以覆蓋適當的文件,例如sed … > "$path"
從而保留inode及其屬性,且不使用命令
mv
或.new
和.bak
檔案。當您想要變更您選擇自動執行的參數之一時,請
HOST=Wonderland
在腳本開頭編輯對應的賦值語句(例如, )。如果您不想編輯腳本,請將腳本分成兩個檔案:一個包含參數值(HOST=…
、IP=…
等...),另一個執行設定檔的所有處理。第二個腳本將是source
第一個取得參數值的腳本。這樣,當參數值變更時,您只需編輯包含這些值的(腳本)文件,而不是主腳本。請確保不要手動編輯文件,因為這些變更將在您下次執行參數化腳本時被覆蓋。相反,編輯相應的模板檔案並重新運行腳本。您可能需要在文件中添加註釋以提醒您這一點。 (如果您不喜歡為僅影響其中一個設定檔的變更重新產生所有設定檔的想法,您可以修改腳本,使其能夠僅重新產生選定的檔案。)