shell實例練習+詳解


想着將Shell與Python和Java等腳本比較比較,當一有這個念頭我就放棄了。這太侮辱Shell了。(哭笑臉!)

作為一個程序員,Linux那是最基本要求。而shell腳本有時候也會顯示它在Linux中獨特的魅力,讓我們一起來學習學習吧!!!!

 

我愛學習!!

 

案例一

打印九九乘法表

  >循環語句(for)

  >變量計算(加減乘除)

語句:

1 for i in $(seq 9); do  for j in $(seq $i); do echo -n "$i*$j=$(($i*$j))  "; done;echo ""; done

結果:

 

說明:

>for循環:for arg in Range;do CMD;done

  循環常見場景:

  ##1、有限數字(用空格隔開)
  for i in 1 2 3 4 5;do echo $i ;done 
  ##2、序列數據(seq 開始 步長 最后) ---步長默認1
  for i in $(seq 1 3 100); do echo $i ;done
  ##3、命令結果(默認空格為分隔符)
  for i in `cat 01.txt`;do echo $i ;done
  for i in `ls | grep "heh"` ;do echo $i ;done
  ##4、語法循環(類似C,注意為雙括號,分號隔開)
  for ((i=1;i<3;i+=2));do echo i ;done
  for ((;;);do echo"無限循環";done
  ##5、其他情況
  具體情況,具體分析

>算術運算

  shell中涉及的算術計算與其他語言一樣(或其他語言與shell一樣,順序請強迫症患者忽略),有加(+)、減(-)、乘(*)、除(/)、取模(\)、取余(%)、求冪(**)。

shell中有好幾種方法實現運算。

  方法一,中括號:[...]   ##中括號完成算術執行,需通過"$"引用打印出來

    echo $[2+3]

  方法二,雙小括號:((...))    ##等同於let 

    echo $((3+2))    ##echo $"let 3+2"

  方法三,let、expr表達式

    let i= 3+2;echo $i;

    echo $(expr $i * 3);(運算符之間要有空格,否則全部不執行運算全部輸出)(expr還有其他高級應用,暫且不說)

  注意:bash不支持浮點類型計算,以上都只能實現整數運算。浮點的運算需要使用bc/awk

    echo 0.5*4-0.2|bc;

    echo $(awk  'BEGIN{print 0.5*4-0.2}'); 

 

案例二

循環打印日期(可指定起始日期或默認日期),並返回天數

  > 循環

  >if判斷

  >date日期

 1 #!/bin/bash
 2 
 3 ##判斷變量,是否為空(如果沒有或只有一個,進行默認賦值)
 4 if [ "$1" == "" ] 
 5 then
 6     start_date=`date -d "today last month" "+%Y%m01"`
 7     end_date=`date -d "today" "+%Y%m%d"`
 8 else
 9     if [ "$2" == "" ]
10     then
11         start_date=`date -d "$1" "+%Y%m%d"`
12         end_date=`date -d "today" "+%Y%m%d"`
13     fi
14 fi        
15 
16 ##判斷兩個變量是否有問題(可擴展,進行可用性識別)
17 if [ "$start_date" -gt "$end_date" ]    
18 then
19     echo "ERROR! \nplease input a right date"
20     exit
21 fi
22 
23 ##通過循環,返回日期值(包含開始和結束日期,閉區間)
24 for i in `seq 0 100000`
25 do
26     t_date=`date -d "${start_date} +$(($i+1)) day" "+%Y%m%d"`
27     echo $t_date
28     cnt_days=$i
29     
30     ##如果循環到當天,就退出
31     if [ $t_date == $end_date ]
32     then
33         break
34     fi
35 done
36 
37 echo "The days between two date is "+$cnt_days+" !"

>if判斷

格式:if 條件 ; then cmd ; elif cmd ; else cmd ; fi

條件格式要求:中括號兩端有至少一個空格,如 [ **** ] ;判斷符中間也需要空格,否則執行雖然不報錯但不是我們要的結果!

  常用的條件:

  數值判斷

  數字1 -eq 數字2   兩數相等為真 (equal)
  數字1 -ne 數字2   兩數不等為真 (not equal)
  數字1 -gt  數字2   數字1大於數字2為真 (great than)
  數字1 -ge 數字2   數字1大於等於數字2為真 (great equal)
  數字1 -lt   數字2   數字1小於數字2為真 (less than)

  數字1 -le  數字2   數字1小於等於數字2為真 (less equal)

  文件判斷

  -e  文件是否存在(目錄或普通文件,exists) 【示例:[ -e ./02.txt ] && echo "hehe",這是一種簡版的if判斷,先執行中括號內部命令,true則執行&&后的命令;】

  -f  是否為普通文件 (file)【示例:[ -f ./02.txt ] && echo "heh"】

    -d  是否為目錄文件(directory)【示例:[ -d ./111 ] && echo "heh"】    

  -r  文件權限:是否可讀(read) 【示例:[ -r ./111 ] && echo "heh"】

  -w  文件權限:是否可寫(write) 【示例:[ -w ./111 ] && echo "heh"】

  -x  文件權限:是否可執行(execute) 【示例:[ -x ./111 ] && echo "heh"】

  字符段判斷

  ==  是否相同(測試“=”也可以)【[ "hehe" == "xizao"  ] && echo "good"】

  !=  是否不等  【[ "hehe" != "xizao"  ] && echo "good"】

  -z  是否為空(長度是否為0)  【[ -z "" ] && echo "good"】

   

 案例三

  對重要的系統數據進行備份,備份周期為一個月(20170901增加)

 1 #!/bin/bash
 2 
 3 #備份日期
 4 date_log=`date "+%Y%m%d"`
 5 
 6 #加入備份root中的數據
 7 tar -czvf /home/shj/bak/root_${date_log}_bak.tar.gz  /root 
 8 
 9 #刪除一個月之前的數據
10 find /home/shj/bak -name "root_*_bak" -mtime +30 -exec rm -rf {} \;

  通過crontab -e,做成定時任務每日零點零分執行(假如我的文件名為:shj_bak.sh)

1 #分 時 天 月 周 cmd
2 0 0 * * * sh shj_bak.sh

 

 案例四

  今天遇到同事不知道怎么了就把crontab任務刪除了,需要進行恢復(20170901)

  1、通過cron日志查看有那些任務(如果這些日志在期間內沒有執行過,將無法收集)

    cat /var/log/cron | grep "shj" | awk -F“(” '{print $3}' | sed 's/(//g' | sort | uniq -c  # cat查詢數據后以管道符傳給grep,匹配shj用戶,結果給到awk,“(”作為分隔符,打印第三列,並用sed將“)”替換掉,排序后取出唯一值,並顯示執行了多少次。  

  2、知道了命令和執行次數,就需要考慮執行頻率了。找到日志開始時間和結束時間

    cat /var/log/cron | grep "shj" | awk '{print $1 " " $2}' | sort | uniq  >mytmp

    echo "日志開始時間為:`head -1 mytmp`,,結束時間為:`tail -1 mytmp`"

  3、重寫crontab

 

案例五

  通過shell做hive、MySQL的定時任務。(當前工作不少都是這個)(20170906)

  shell寫hive的定時任務(路徑默認為當前家目錄)

    1、創建你需要的腳本,例:vim  hive_perday.sh

    2、編寫shell腳本

#!/bin/bash
    
    if [ "$1"==""  ]  #$1如果不加"",當$1為空會報錯。假如這個有個日期參數。
    then
        para1=`date "+%Y&m%d"`
    else
        para1=$1
    fi

#寫你的hive語句(假如需要參數)
    hive_sql="select * from mytable where col>'para1'"
#執行你的hive,並將結果輸出到指定位置(含錯誤),將&1替換為/dev/null則不輸出錯誤
    hive -e "{$hive_sql}" >~/file 2>&1
#執行hive文件
    hive -f hive_file

#寫入你的MySQL語句
mysql_sql="select * from table where *****"
mysql -host10.10.10.10 -utest -p**** -P3306 -e "{$mysql_sql}"

    3、將你的腳本部署到定時任務中,如果是長期執行則用crontab,如果只執行一次用at。

 

案例六

  Linux文本處理(今天將csv導入MySQL時,發現多了一列以及表頭)。於是,我們用awk、sed處理一下吧。(20171011補充)

  ]$ awk -F, '{print $1","$3","$4","$5}' filename >new_file.csv    處理掉多余的列

  ]$ sed -n '2,$p' new_file.csv > final.csv

  ]$ mysql -h10.**** -u*** -p****

  mysql > load data local infile 'final.csv' insert into table(a,b,c,d); 

  

原創博客,轉載請注明出處!歡迎郵件溝通:shj8319@sina.com


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM