高级Bash脚本编程入门
最近在看《Advanced Bash Scripting Guide》這本書,第二章舉了一個清除日志的例子,來講述如何使用Bash進行編程并聊到了一些編程規范。本文主要是基于這部分內容記錄我的讀書筆記并整理一些相關知識點。
說到清除日志,你可以使用下面命令來完成清除/var/log下的log文件這件事情:
cd /var/log cat /dev/null > messages cat /dev/null > wtmp echo "Logs cleaned up."更簡單的清除日志方法是:
echo "" >messages #或者 >messages注意: /var/log/messages 記錄系統報錯信息 /var/log/wtmp 記錄系統登錄信息
在Bash編程時,腳本通常都是放到一個文件里面,該文件可以有后綴名也可以沒有,例如,你可以將該文件命名為cleanlog,然后在文件頭聲明一個命令解釋器,這里是#!/bin/bash:
#!/bin/bash LOG_DIR=/var/log cd $LOG_DIR cat /dev/null > messages cat /dev/null > wtmp echo "Logs cleaned up." exit當然,還可以使用其他的命令行解釋器,例如:
#!/bin/sh #!/bin/bash #!/usr/bin/perl #!/usr/bin/tcl #!/bin/sed -f #!/usr/awk -f#自刪除腳本 #!/bin/rm說明:
- #!?后面的路徑必須真實存在,否則運行時會提示Command not found的錯誤。
- 在UNIX系統中,在!后邊需要一個空格。
- 如果腳本中還包含有其他的#!行,那么bash將會把它看成是一個一般的注釋行。
上面代碼將/var/log定義為變量,這樣會比把代碼寫死好很多,因為如果你可能想修改為其他目錄,只需要修改變量的值就可以。
對于/var/log目錄,一般用戶沒有訪問權限,故需要使用root用戶來運行上面腳本,另外,用戶不一定有修改目錄的權限,所以需要增強代碼,做一些判斷。
#!/bin/bashLOG_DIR=/var/log ROOT_UID=0 LINES=50 E_XCD=66 E_NOTROOT=67# 當然要使用root 用戶來運行. if [ "$UID" -ne "$ROOT_UID" ] thenecho "Must be root to run this script."exit $E_NOTROOT ficd $LOG_DIRif[ "$PWD" != "$LOG_DIR" ] thenecho "Can't change to $LOG_DIR."exit $E_XCD ficat /dev/null > messages cat /dev/null > wtmp echo "Logs cleaned up."#返回0表示成功 exit 0上面代碼一樣定義了一些變量,然后加了兩個判斷,去檢查腳本運行中可能出現的錯誤并打印錯誤說明。如果腳本運行錯誤,則程序會退出并返回一個錯誤碼,不同類型的錯誤對應的錯誤碼不一樣,這樣便于識別錯誤原因;如果腳本運行正常,則正常退出,默認返回碼為0。
對于cd $LOG_DIR操作判斷是否執行成功,更有效的做法是:
#使用或操作替代if else判斷 cd /var/log || {echo "Cannot change to necessary directory." >&2exit $E_XCD }通常,我們可能不想全部清除日志,而是保留最后幾行日志,這樣就需要給腳本傳入參數:
#!/bin/bashLOG_DIR=/var/log ROOT_UID=0 LINES=50 E_XCD=66 E_NOTROOT=67# 當然要使用root 用戶來運行. if [ "$UID" -ne "$ROOT_UID" ] thenecho "Must be root to run this script."exit $E_NOTROOT ficd $LOG_DIRif[ "$PWD" != "$LOG_DIR" ] thenecho "Can't change to $LOG_DIR."exit $E_XCD fi# 測試是否有命令行參數,非空判斷 if [ -n "$1" ] thenlines=$1 elselines=$LINES # 默認,如果不在命令行中指定 fi# 保存log file消息的最后部分 tail -$lines messages > mesg.temp mv mesg.temp messagescat /dev/null > wtmp echo "Logs cleaned up."#返回0表示成功 exit 0上面使用if else來判斷是否有輸入參數,一個更好的檢測命令行參數的方式是使用正則表達式做判斷,以檢查輸入參數的合法性:
E_WRONGARGS=65 # 非數值參數(錯誤的參數格式)case "$1" in"" ) lines=50;;*[!0-9]*) echo "Usage: `basename $0` file-to-cleanup"; exit $E_WRONGARGS;; * ) lines=$1;; esac編寫完腳本之后,你可以使用sh scriptname或者bash scriptname來調用這個腳本。不推薦使用sh <scriptname,因為這禁用了腳本從stdin中讀數據的功能。更方便的方法是讓腳本本身就具有 可執行權限,通過chmod命令可以修改。比如:
chmod 555 scriptname #允許任何人都具有可讀和執行權限或者:
chmod +rx scriptname #允許任何人都具有可讀和執行權限 chmod u+rx scriptname #只給腳本的所有者可讀和執行權限既然腳本已經具有了可執行權限,現在你可以使用./scriptname來測試這個腳本了。如果這個腳本以一個#!行開頭,那么腳本將會調用合適的命令解釋器來運行。
這樣一個簡單的腳本就編寫完成并能運行了,從這個例子中,我們可以學到bash編程的一些代碼規范:
- 使用變量
- 腳本運行中,需要做一些異常判斷
除此之外,google公司還定義了一份Shell Style Guide,可以仔細閱讀并約束自己去遵循這些規范。
總結
以上是生活随笔為你收集整理的高级Bash脚本编程入门的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: UWB定位记录二(DWM1000模组介绍
- 下一篇: FGSM实例:利用fgsm攻击RMB识别