Linux系統(tǒng)管理員的Bash指南,11條Bash實(shí)踐經(jīng)驗(yàn)!
每個(gè)職業(yè)都有最常用的工具。對于許多系統(tǒng)管理員來說,shell可能是比較熟悉的。在大多數(shù)Linux和其他類Unix系統(tǒng)上,默認(rèn)的shell是Bash。
Bash是一個(gè)相當(dāng)古老的程序,它起源于20世紀(jì)80年代后期。但它建立在更多,更老的shell上,比如C shell(csh)。我們來看看一些基礎(chǔ)知識(shí)。
相信你在某些時(shí)候,曾無意中以root身份運(yùn)行命令并導(dǎo)致某種問題?這里有一些非常簡單的技巧可以防止你遇到這樣的問題。
使用別名
首先,為mv和rm等命令設(shè)置別名,指向mv -I和rm -I。這將確保運(yùn)行rm -f/boot至少要求你確認(rèn)。在紅帽企業(yè)版Linux中,如果你使用root帳戶,則默認(rèn)設(shè)置這些別名。
如果你還要為普通用戶帳戶設(shè)置這些別名,只需將這兩行放入主目錄中名為.bashrc的文件中(這些也適用于sudo):
- alias mv=’mv -i’
- alias rm=’rm -i’
你的根提示符
你可以采取的另一項(xiàng)措施是防止意外發(fā)生,確保你在使用root帳戶時(shí)知道。我通常這樣做是為了讓我的正常日常工作中使用的提示能夠很好地突出根提示符。
如果將以下內(nèi)容放入root的主目錄中的.bashrc文件中,你將看到一個(gè)黑色的紅色根提示符,清楚地表明你(或其他任何人)應(yīng)該謹(jǐn)慎操作。
- export PS1=”\[$(tput bold)$(tput setab 0)$(tput setaf 1)\]\u@\h:\w # \[$(tput sgr0)\]”
實(shí)際上,你應(yīng)該盡可能避免以root用戶身份登錄,而是通過sudo運(yùn)行大多數(shù)系統(tǒng)管理命令,但這是另一回事。
實(shí)施了一些小技巧來幫助防止使用root帳戶的“無意的副作用”,讓我們看看Bash可以給你你在日常工作中帶來怎樣的幫助?
控制history文件
你可能知道,當(dāng)在Bash中按向上箭頭鍵時(shí),你可以查看并重復(fù)使用以前的所有命令。這是因?yàn)檫@些命令已保存到主目錄中名為.bash_history的文件中。該歷史文件附帶了一組非常有用的設(shè)置和命令。
首先,你可以通過鍵入歷史記錄來查看整個(gè)最近的命令歷史記錄,或者你可以通過鍵入歷史記錄,或?qū)⑵湎拗茷樽罱?0個(gè)命令。你可以更好地控制Bash保存的內(nèi)容以及保存方式。
例如,如果將以下內(nèi)容添加到.bashrc,則任何以空格開頭的命令都不會(huì)保存到歷史記錄列表中:
- HISTCONTROL=ignorespace
如果你需要用命令寫入明文形式的密碼。(是的,這太可怕了,但它仍然會(huì)發(fā)生。)
如果你不希望在歷史記錄中顯示經(jīng)常執(zhí)行的命令,請使用:
- HISTCONTROL=ignorespace:erasedups
這樣,每次使用命令時(shí),都會(huì)從歷史記錄文件中刪除之前發(fā)生的所有事件,并且只將最后一次調(diào)用保存到歷史記錄列表中。
我特別喜歡的歷史記錄設(shè)置是HISTTIMEFORMAT設(shè)置。這將在歷史記錄文件中添加時(shí)間戳前的所有條目。例如,我使用:
- HISTTIMEFORMAT=”%F %T “
當(dāng)我輸入五條歷史記錄時(shí),我得到了很好的完整信息,如下所示:
- 1009 2018-06-11 22:34:38 cat /etc/hosts
- 1010 2018-06-11 22:34:40 echo $foo
- 1011 2018-06-11 22:34:42 echo $bar
- 1012 2018-06-11 22:34:44 ssh myhost
- 1013 2018-06-11 22:34:55 vim .bashrc
這使我更容易瀏覽我的命令歷史記錄,并找到我兩天前用來建立到家中的SSH隧道。
最好的Bash實(shí)踐
在編寫B(tài)ash腳本時(shí),我將用最好的11個(gè)用法列出來(我是這樣認(rèn)為的)。
11.Bash腳本可能變得復(fù)雜,添加注釋沒那么復(fù)雜。因?yàn)槿绻阍谥苣┲蠡氐焦ぷ髦?,不得不花時(shí)間搞清楚你上周五想要做什么的話,別忘了添加注釋。
10.用花括號(hào)括起所有變量名,比如$ {myvariable}。養(yǎng)成這個(gè)習(xí)慣可以使$ {variable} _suffix成為可能,并提高整個(gè)腳本的一致性。
9.評估表達(dá)式時(shí)不要使用反引號(hào);請改用$()語法??梢允褂茫?/p>
- for file in $(ls); do
反之:
- for file in `ls`; do
前一個(gè)選項(xiàng)是可嵌套的,更易于閱讀,并使一般的系統(tǒng)管理員感到滿意。不要使用反引號(hào)。
8.一致性很好。選擇一種風(fēng)格并在整個(gè)腳本中堅(jiān)持下去。顯然,我更喜歡人們在反引號(hào)中選擇$()語法,并將其變量放在在花括號(hào)中。
7.使用適當(dāng)?shù)膕hebang作為Bash腳本。因?yàn)槲艺诰帉態(tài)ash腳本,只打算用Bash執(zhí)行它們,所以我經(jīng)常使用#!/ usr / bin / bash作為我的shebang。不要使用#!/ bin / sh或#!/ usr / bin / sh。你的腳本將執(zhí)行,但它將以兼容模式運(yùn)行??赡軙?huì)產(chǎn)生許多意外的副作用。(當(dāng)然,除非你想要兼容模式。)
6.比較字符串時(shí),在if語句中引用變量是個(gè)好主意,因?yàn)槿绻愕淖兞渴强盏?,Bash會(huì)為這樣的行拋出一個(gè)錯(cuò)誤:
- if [ ${myvar} == “foo” ]; then
- echo “bar”
- fi
對于這樣的行,將評估為false:
- if [ “${myvar}” == “foo” ]; then
- echo “bar”
- fi
此外,如果你不確定變量的內(nèi)容(例如,在解析用戶輸入時(shí)),請引用變量以防止解釋某些特殊字符,并確保該變量被視為單個(gè)詞,即使它包含空格。
5.我想這是一個(gè)品味問題,但我更喜歡使用雙等號(hào)(==),即使比較Bash中的字符串。這是一致性的問題,盡管,對于字符串比較,只有一個(gè)等號(hào)會(huì)起作用,我的考慮立即變?yōu)?ldquo;單個(gè)等于是一個(gè)賦值運(yùn)算符!”
4.使用適當(dāng)?shù)耐顺龃a。確保如果你的腳本無法執(zhí)行某些操作,則會(huì)向用戶顯示已寫入的失敗消息(最好通過解決問題的方法)并發(fā)送非零退出代碼:
- # we have failed
- echo “Process has failed to complete, you need to manually restart the whatchamacallit”
- exit 1
這樣可以更容易地以編程方式從另一個(gè)腳本調(diào)用腳本并驗(yàn)證其成功完成。
3.使用Bash的內(nèi)置機(jī)制為變量提供合理的默認(rèn)值,或者如果未定義你希望定義的變量,則拋出錯(cuò)誤:
- # this sets the value of $myvar to redhat, and prints ‘redhat’
- echo ${myvar:=redhat}
- # this throws an error reading ‘The variable myvar is undefined, dear reader’ if $myvar is undefined
- ${myvar:?The variable myvar is undefined, dear reader}
2.特別是如果你正在編寫大型腳本,特別是如果你與其他腳本一起處理該大型腳本,請考慮在函數(shù)內(nèi)部定義變量時(shí)使用local關(guān)鍵字。local關(guān)鍵字將創(chuàng)建一個(gè)局部變量,該變量只在該函數(shù)中可見。這限制了沖突變量的可能性。
1.每個(gè)系統(tǒng)管理員有時(shí)必須這樣做:在控制臺(tái)上調(diào)試一些東西,可以是數(shù)據(jù)中心的真實(shí)服務(wù)器,也可以是虛擬化平臺(tái)的虛擬服務(wù)器。如果你必須以這種方式調(diào)試腳本,你會(huì)感謝你自己記住這個(gè):不要讓你的腳本中的行太長!
在許多系統(tǒng)上,控制臺(tái)的默認(rèn)寬度仍為80個(gè)字符。如果你需要在控制臺(tái)上調(diào)試腳本并且該腳本有很長的行,那么將是一個(gè)悲劇。此外,具有較短行的腳本,默認(rèn)值仍為80個(gè)字符,在普通編輯器中也更容易閱讀和理解!