2.1 調(diào)用腳本
在最簡單的情況下,腳本只不過是一組系統(tǒng)命令的集合,存儲(chǔ)在一個(gè)文件中。至少,這樣可以避免每次調(diào)用時(shí)都要重新輸入那一串命令。
示例 2-1:cleanup:清理 /var/log 下日志文件的腳本
# Cleanup
# 當(dāng)然要以 root 身份運(yùn)行。
cd /var/log
cat /dev/null > messages
cat /dev/null > wtmp
echo "Log files cleaned up."
這里沒有什么特別的,只是一組可以在控制臺(tái)或終端窗口中逐條輸入的命令。將命令放入腳本的好處遠(yuǎn)不止于此——腳本變成了一個(gè)“程序”,一個(gè)“工具”,而且可以很容易地根據(jù)具體應(yīng)用進(jìn)行修改或定制。
示例 2-2:cleanup:改進(jìn)版清理腳本
#!/bin/bash
# Proper header for a Bash script.
# Cleanup, version 2
# 當(dāng)然要以 root 身份運(yùn)行。
# 插入代碼以在非 root 時(shí)打印錯(cuò)誤信息并退出。
LOG_DIR=/var/log
# 變量比硬編碼值更好。
cd $LOG_DIR
cat /dev/null > messages
cat /dev/null > wtmp
echo "Logs cleaned up."
exit
# 用 exit 正確地退出腳本。
# 不帶參數(shù)的 exit 返回前一條命令的退出狀態(tài)。
現(xiàn)在,這已經(jīng)開始像一個(gè)真正的腳本了。但我們還可以做得更好……
示例 2-3:cleanup:增強(qiáng)和通用版腳本
#!/bin/bash
# Cleanup, version 3
# 警告:
# -------
# 這個(gè)腳本用到了許多后面會(huì)講到的特性。
# 當(dāng)你學(xué)完本書前半部分時(shí),這些都不再神秘。
LOG_DIR=/var/log
ROOT_UID=0 # 只有 UID 為 0 的用戶有 root 權(quán)限。
LINES=50 # 默認(rèn)保留的行數(shù)。
E_XCD=86 # 不能切換目錄?
E_NOTROOT=87 # 非 root 退出錯(cuò)誤。
# 當(dāng)然要以 root 身份運(yùn)行。
if [ "$UID" -ne "$ROOT_UID" ]
then
echo "Must be root to run this script."
exit $E_NOTROOT
fi
if [ -n "$1" ] # 檢查命令行參數(shù)是否存在(非空)。
then
lines=$1
else
lines=$LINES # 默認(rèn)值
fi
cd $LOG_DIR
if [ `pwd` != "$LOG_DIR" ] # 或 if [ "$PWD" != "$LOG_DIR" ]
then
echo "Can't change to $LOG_DIR."
exit $E_XCD
fi
tail -n $lines messages > mesg.temp # 保留日志文件最后部分
mv mesg.temp messages # 重命名為系統(tǒng)日志文件
cat /dev/null > wtmp
echo "Log files cleaned up."
exit 0
# 腳本退出時(shí)返回 0 表示成功
由于你可能不希望清空整個(gè)系統(tǒng)日志,這個(gè)版本的腳本會(huì)保留日志文件的最后一部分。你會(huì)不斷發(fā)現(xiàn)優(yōu)化腳本以提高效率的方法。
Sha-Bang(#!)說明
sha-bang(#!)在腳本開頭告訴系統(tǒng),這個(gè)文件是一組要交給指定命令解釋器執(zhí)行的命令。#! 實(shí)際上是一個(gè)兩字節(jié)的“魔數(shù)”,標(biāo)記文件類型,這里表示可執(zhí)行的 shell 腳本。緊跟在 #! 后面的是一個(gè)路徑名,指向解釋腳本命令的程序(如 shell、編程語言或工具)。該解釋器會(huì)從腳本頂部(#! 后一行)開始執(zhí)行命令,忽略注釋。
常見的 sha-bang 行有:
#!/bin/sh
#!/bin/bash
#!/usr/bin/perl
#!/usr/bin/tcl
#!/bin/sed -f
#!/bin/awk -f
每一行都調(diào)用不同的命令解釋器,比如 /bin/sh(大多數(shù) Linux 系統(tǒng)默認(rèn)是 bash)等。使用 #!/bin/sh 可以讓腳本在非 Linux 的 UNIX 系統(tǒng)上也能運(yùn)行,但會(huì)失去 bash 的特有功能。該腳本會(huì)遵循 POSIX sh 標(biāo)準(zhǔn)。
注意,sha-bang 行中的路徑必須正確,否則運(yùn)行腳本時(shí)只會(huì)看到“Command not found.”的錯(cuò)誤信息。
如果腳本只包含通用的系統(tǒng)命令,沒有用到 shell 的內(nèi)部指令,可以省略 #!。但如果腳本中有變量賦值等 shell 特性,必須加上 #!。
小貼士
本教程鼓勵(lì)以模塊化方式構(gòu)建腳本。請(qǐng)收集和整理有用的“模板”代碼片段,將來會(huì)積累出豐富的腳本庫。例如,下面的腳本開頭用于檢測(cè)參數(shù)數(shù)量是否正確:
E_WRONG_ARGS=85
script_parameters="-a -h -m -z"
if [ $# -ne $Number_of_expected_args ]
then
echo "Usage: `basename $0` $script_parameters"
exit $E_WRONG_ARGS
fi