前段時間有個外國的程序猿走紅網絡,這個哥們可以說是懶到了極點,上班請假給領導發短信寫腳本,下班晚回家給老婆發短信寫腳本,甚至于接個咖啡也要寫腳本。這個哥們離職之后,他的同事在他的辦公電腦上發現了這些腳本,并公布到了網上,引起眾程序猿紛紛膜拜。最近我剛好學到shell腳本部分,就讓我分析其中的一個跟領導請假的腳本吧。
#!/bin/sh -e # Exit early if any session with my username is found if who | grep -wq $USER; then exit fi # Phone numbers MY_NUMBER='+xxx' NUMBER_OF_BOSS='+xxx' EXCUSES=( 'Locked out' 'Pipes broke' 'Food poisoning' 'Not feeling well' ) rand=$[ $RANDOM % ${#EXCUSES[@]} ] RANDOM_EXCUSE=${EXCUSES[$rand]} MESSAGE="Gonna work from home. "$RANDOM_EXCUSE # Send a text message RESPONSE=`curl -fSs -u "$TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN" \ -d "From=$MY_NUMBER" -d "To=$NUMBER_OF_BOSS" -d "Body=$MESSAGE" \ "https://api.twilio.com/2010-04-01/Accounts/$TWILIO_ACCOUNT_SID/Messages"` # Log errors if [ $? -gt 0 ]; then echo "Failed to send SMS: $RESPONSE" exit 1 fi
一 shebang聲明
#!/bin/sh -e
腳本的shebang聲明是在腳本直接執行,而不使用sh或者bash間接執行的時候,告訴解釋程序此腳本的類型,如果腳本中沒有此聲明,那么腳本在執行的時候會使用默認的shell程序執行它。在此例中,腳本使用了/bin/sh作為解釋程序。
在ubuntu系列linux里,為了加快系統啟動速度,/bin/sh被設置成了指向dash的鏈接,而非bash
#ll /bin/sh lrwxrwxrwx 1 root root 4 2月 16 10:23 /bin/sh -> dash*
在Centos里,/bin/sh鏈接到了bash
#ll /bin/sh lrwxrwxrwx. 1 root root 4 2月 14 16:55 /bin/sh -> bash
所以在ubuntu里如果要使用bash要寫成#!/bin/bash才行。
-e選項表示腳本中有任何錯誤都會終止執行腳本。
二 執行條件過濾
# Exit early if any session with my username is found if who | grep -wq $USER; then exit fi
腳本在主要代碼執行前,首先要判斷用戶傳入的參數、執行者的權限、文件目錄是否存在等是否符合腳本執行的條件,所以會進行相應的判斷,如果沒達到符合的條件就會提示用戶退出執行。在本例中,判斷了腳本的所屬者是否登錄了系統,如果已經登錄了就表明他已經來上班了,下面的請假過程就不用執行了。
三 聲明變量
# Phone numbers MY_NUMBER='+xxx' NUMBER_OF_BOSS='+xxx'
定義字符串變量,分別存入本人和老板的電話號碼。
EXCUSES=( 'Locked out' 'Pipes broke' 'Food poisoning' 'Not feeling well' )
定義請假理由的數組
rand=$[ $RANDOM % ${#EXCUSES[@]} ]
隨機抽取請假編號。${#EXCUSES[@]}代表數值元素的個數,然后通過與隨機數的取余運算獲得隨機的編號。$[ ]為算數運算符號,與let、$(())等價
RANDOM_EXCUSE=${EXCUSES[$rand]}
取得數組中的某一項。
MESSAGE="Gonna work from home. "$RANDOM_EXCUSE
將消息頭與隨機項合并組成消息。
三 執行主要任務
# Send a text message RESPONSE=`curl -fSs -u "$TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN" \ -d "From=$MY_NUMBER" -d "To=$NUMBER_OF_BOSS" -d "Body=$MESSAGE" \ "https://api.twilio.com/2010-04-01/Accounts/$TWILIO_ACCOUNT_SID/Messages"`
其中的$TWILIO_ACCOUNT_SID和$TWILIO_AUTH_TOKEN為環境變量,通過curl命令執行了登錄網站發送短信的過程,并把執行的結果返回給RESPONSE變量。
四 判斷執行的結果
# Log errors if [ $? -gt 0 ]; then echo "Failed to send SMS: $RESPONSE" exit 1 fi
當腳本的主要代碼執行完畢后,通過檢測執行后的狀態來判斷腳本的執行結果,如果執行結果大于0,說明執行過程中出現了錯誤,后臺執行的腳本會以發郵件的方式提示用戶。
五 設置環境變量和周期執行
TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxx TWILIO_AUTH_TOKEN=yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
此環境變量在用戶未登錄的情況下也要執行,所以不能設置在~/.bashrc ~/.bash_profil /etc/bashrc /etc/profile.d里,最好寫在/etc/rc.local里
# Runs `hangover.sh` monday to friday at 8:45 am. 45 8 * * 1-5 /path/to/scripts/hangover.sh >> /path/to/hangover.log 2>&1
周一至周五的8點45分執行腳本,并輸出日志。此任務沒有用戶名,應該是使用命令crontab -e編輯的。
六 總結
這位仁兄的代碼簡潔,注釋清晰,內容包含了shell編程的主要步驟,值得我等新人研究學習。
原創文章,作者:realmaster,如若轉載,請注明出處:http://www.www58058.com/72647