小K本着「能坐着毫不站着,能躺着毫不坐着」的「懶人之道」,努力打造規範和可靠的代碼。下面就給你們講講小k在學習和使用shell過程當中遇到的問題。shell
今天真高興啊,今天真興高,小K一個小時就完成了今天的代碼開發。小Q,來給我測試一下,立刻就能上線。編程
#!/bin/bash echo '先將原數據文件a.txt作個備份' cp a.txt bak.txt echo '將原文件裏的xx替換成yy' sed -i "s/xxx/yyy/g" a.txt ###balabala省略一堆指令 echo '成功'
小Q:嘿嘿,來啦。無論三七二十一,先來個異常場景:a.txt不存在。bash
執行日誌以下:函數
先將原數據文件a.txt作個備份 cp: a.txt: No such file or directory 將原文件裏的xx替換成yy sed: 1: "a.txt": command a expects \ followed by text 成功
小Q:小K啊,代碼都報異常了,最後告訴我成功。。。學習
小K:簡單,我經過$?的值來判斷上一步的狀態進而決定是繼續執行仍是異常退出。(哼哼,爲了防止小Q在找茬兒,我每一個都加判斷)測試
echo '先將原數據文件a.txt作個備份' cp a.txt bak.txt if [ $? -ne 0 ];then echo 'command fail' exit 1 fi echo '將原文件裏的xx替換成yy' sed -i "s/xxx/yyy/g" a.txt if [ $? -ne 0 ];then echo 'command fail' exit 1 fi ###balabala一堆邏輯代碼 echo '成功'
一頓操做猛如虎,原來10行的代碼活生生變成了40行,有沒有簡單的方式呢?(幸好公司不是拿代碼行數作KPI,要否則我能寫到公司破產)優化
那有什麼方式能夠優化一下呢?噔噔噔噔...答案就是:set -o errexitspa
set -o errexit echo '先將原數據文件a.txt作個備份' cp a.txt bak.txt echo '將原文件裏的xx替換成yy' sed -i "s/xxx/yyy/g" a.txt ###balabala一堆邏輯代碼 echo '成功'
Tips:日誌
小K做爲努力「糞」發向上的有爲「青年」,把日誌打成這樣實在是讓人看不下去,至少得加個時間戳吧。blog
這個不難,經過date就行,但這一行一行的替換着實不像我這個懶人的風格。
立刻中午了,被小Q折騰的連水都沒喝一口,直接上代碼:
#具體格式能夠自行定義,這裏以 時間 日誌級別 日誌信息展現 function logger() { echo $(date "+%Y-%m-%d %H:%M:%S")" $1:$2" } logger 'info' '先將原數據文件a.txt作個備份' cp a.txt bak.txt
Tips:
小P:小K,小Q來一下。我忽然想到原數據文件可能不叫a.txt,我又不想改文件名。大家給搞下。
小K:(又改需求,一臉黑線。。。) 那我加個外部參數傳遞吧: sh xxx.sh a.txt
source=$1 logger 'info' "先將原數據文件[${source}]作個備份" cp ${source} bak.txt
小Q:若是後面還要加功能,須要傳入多個參數呢?
小K:嗯。。。使用$1的方式,代碼裏確定還得須要定義多個變量,有點刷代碼行數的嫌疑,並且若是不當心傳錯位很差判斷。
這樣的話小K就只能出殺手鐗了:sh xxx.sh source=a.txt target=bak.txt
for i in $* do export $i done logger 'info' "將原數據文件[${source}]複製到[${target}]" cp ${source} ${target}
Tips:
哼哼哈hi,搞定。等等,萬一小Q又來個異常測試,不給我傳變量名可咋整?
能夠在代碼里加上set –o nounset。
for i in $* do export $i done set -o nounset logger 'info' "將原數據文件[${source}]複製到[${target}]" cp ${source} ${target}
Tips:
這些小技巧你學會了嗎?
I will be back!
做者:範令凱
公衆號:互聯網技術到家
頭條號:互聯網技術到家