1. 程式人生 > >shell指令碼中使用if和bc比較變數值和指定值

shell指令碼中使用if和bc比較變數值和指定值

【預備知識】

假如我有個日誌檔案,每天會往裡追加。日誌摘要如下——
2018-06-12 09:08:56,105 - hdfs.client - INFO - Renaming ‘/apps/wps_prt_feature/business_info/2018-06-11/android_app.temp-1528765731’ to ‘/apps/wps_prt_feature/business_info/2018-06-11/android_app’.
… …
2018-06-12 09:09:29,392 - hdfs.client - INFO - Renaming ‘/apps/wps_prt_feature/business_info/2018-06-11/ios_app.temp-1528765764’ to ‘/apps/wps_prt_feature/business_info/2018-06-11/ios_app’.

我想在裡面找到帶有當天日期和Renaming字樣的內容,以便確認我跑的作業成功了,
那麼我就想用shell指令碼從日誌檔案中過濾出來。如何實現呢?下面是思考的過程——

[tony@test-host-10 business_info]$ today=`date +%F`    # 獲取當天日期
[tony@test-host-10 business_info]$ echo $today 
2018-05-24

從包含當天日期的日誌記錄中進一步篩選出含有Renaming的日誌

[tony@test-host-10 business_info]$ grep $today log_fifth | grep Renaming
| wc -l 2 [tony@test-host-10 business_info]$ renamed_hdfsFile_result=`grep $today log_fifth | grep Renaming | wc -l` [tony@test-host-10 business_info]$ echo $renamed_hdfsFile_result 2

經過bc計算,如果true(有2行含有Renaming的記錄)則輸出1,否則輸出0

[[email protected]10 business_info]$ echo "$renamed_hdfsFile_result == 2"
| bc 1

在linux shell中測試一下指令碼

[[email protected]10 business_info]$ if [ `echo "$renamed_hdfsFile_result == 2" | bc` -eq 1 ]; then echo "OK~"; else echo "BAD"; fi
OK~

測試成功後,就可以把我們的業務邏輯寫入到腳本里了
[[email protected] business_info]$ cat check_hdfs_dir.sh

#!/bin/bash

today=`date +%F`
renamed_hdfsFile_result=`grep $today log_fifth | grep Renaming | wc -l`
if [ `echo "$renamed_hdfsFile_result == 2" | bc` -eq 1 ]
then
  echo "Successfully renamed android_app and ios_app on our HDFS ^_^"
else
  echo "Not good!"
fi

【需求場景】

我想要在整點時間執行某指令碼,但是不想使用crontab。比如我想在上午9點開始執行指令碼,需要從date時間中獲取小時數,再和9比較,如果大於等於9則開始執行指令碼。這裡用到了bc來比較數值大小。
如果沒有安裝bc,需要以root使用者使用yum install -y bc即可安裝,安裝後就能直接使用了。示例指令碼如下。

#!/bin/bash

function run_job(){
  yesterday=`date -d"1 days ago" +%Y-%m-%d`
  now_hour=`date | awk -F":" '{print $1}' | awk '{print $5}'`
  echo "Present hour number is____${now_hour}"
  # 判斷當前hour是不是9點或9點以後
  if [ `echo "${now_hour} >= 9" | bc` -eq 1 ]; then
    echo "Now it's $1"
    echo Starting processing data on ${yesterday}
    # DO WHAT YOU WANT HERE.
    if [ $? -eq 0 ]; then
      echo 
      echo "0=}========> Job finished."
      exit 0
    else
      echo "Something wrong while running job."
      exit -1
    fi

  else
    current=$1
    echo "Current time is ${current}, not the right time(09:00) to run job. Wait another 30 minutes ..."
    sleep 30m

  fi
}

while (true); do
  current_time=`date +"%Y-%m-%d %H:%M:%S"`
  # 此處傳參一定要加雙引號,否則run_daily_job()中的echo "Current time is ${current} ..." 只會顯示年月日,不顯示時分秒
  run_job "$current_time"
done

現在是下午14:29,此時執行指令碼,輸出結果是——

Present hour number is____14
Now it’s 2018-05-24 14:29:57
Starting processing data on 2018-05-23

0=}========> Job finished.

【延伸】加強指令碼的健壯性

如果無法獲取到now_hour,指令碼就失效了。所以,為了保證能在9點鐘執行我的指令碼,需要在沒有獲取到now_hour變數值的情況下給一個預設值。讀者可以自己在上面腳本里加一行,加在引用now_hour之前的語句即可。
加之前,可以自己驗證一下,我這邊驗證過了,請看——
【若變數hour為空,則用 :- 給一個預設值】

[tony@test-host-10 business_info]$ hour=''  #此時hour為空
[tony@test-host-10 business_info]$ echo $hour 

[tony@test-host-10 business_info]$ hour=${hour:-9}   #hour變數為空,則 :- 給一個預設值9
[tony@test-host-10 business_info]$ echo $hour 
9
[tony@test-host-10 business_info]$ hour2=${hour2:-15}   #hour2變數為空,則 :- 給一個預設值15
[tony@test-host-10 business_info]$ echo $hour2 
15 

好了就寫到這裡,看官們覺得漲知識了,請在文章左側點個贊 ^_^