工作中shell腳本的實用頻率非常高,比如作為不同語言之間的膠水,或者是為了避免重復勞動而寫的一次性工具。熟練掌握shell腳本的一些使用技巧,絕對是提高工作效率的利器!PS.本文中指的Shell都是Bash
shell的啟動方式通過兩種維度來劃分,交互與非交互,登錄與非登錄。這里面其實比較復雜,不同的發行版本可能也不太一樣,都可以另外寫一篇來談了。簡單的說一般情況下你login了一臺機器,在bash下就是交互登錄啟動,這個時候shell會先source/etc/PRofile,~/.bash_profile, ~/.bash_login, ~/.profile這3個文件(如果有的話),然后一般~/.bash_profile里面會source一把~/.bashrc。所以這個時候你執行一些腳本的話環境變量已經配置好了。但是如果是用crontab啟動,就是非交互啟動,這個時候shell只會source一邊/etc/profile, 那么很多環境變量是沒有設置的,所以通過crontab啟動的腳本在開頭最好都source一下~/.bash_profile或者~/.bashrc
---------------------------------------我是分割線------------------------------------
場景1
job1每天會執行一次,完成后會輸出一個done文件到目錄/home/minecraft/daily/yyyymmdd下,然后job1完成后執行job2
對于這個場景,我們可以每天在固定時間起一個crontab任務,任務執行一個shell腳本,該腳本每隔固定的時間去探查done文件是否存在,如存在則執行job2. 為了防止這個任務一直等待下去,一般會添加一個探查的次數限制。
另外一種思路是每天用crontab間隔一段時間就起一次任務來探查done文件,如存在則執行job2.這個思路存在一個問題,當我前一次探查到done后開始執行job2,后一次還是會來繼續探查done文件,重復啟動job2,產生錯誤??梢酝ㄟ^設置一個lock文件來終止后面的所有探查進程來保證job2的唯一性。在當前場景下思路1比較簡潔有效。
思路1代碼如下
1 DATE=$(date +%Y%m%d) 2 retry=60 3 while :; 4 do 5 if [[ -e /home/minecraft/daily/${DATE}/done ]]; then 6 break 7 else 8 ((retry--)) 9 sleep 10m10 fi11 if [[ ${retry} -le 0 ]]; then12 exit 113 fi14 done15 16 run job217 18 exit 0
假如job1不是touch一個done文件,而是輸出一個文件,那么我們就需要判斷2點:1.文件是否存在;2.文件是否已經完成寫入。第一點好判斷,第二點的話可以每隔一段時間check一下文件大小,當2次check的大小不變,就可以認為文件已經寫入完成了。查看文件大小可以用
1 size=$(wc -c < file)
或者利用管道
1 size=$(cat file | wc -c)
又假設job1寫入的是1天前的數據,那么可以利用
1 NDAYAGO=$(date "1 ady ago" "+%Y%m%d")
來獲得日期字符串
TO BE CONTINUE...
新聞熱點
疑難解答