注意事项:
1. 指令的执行是从上而下、从左而右的分析与执行;
2. 指令的下达就如同第五章内提到的: 指令、选项与参数间的多个空白都会被忽略掉;3. 空白行也将被忽略掉,并且 [tab] 按键所推开的空白同样视为空格键;
4. 如果读取到一个 Enter 符号 (CR) ,就尝试开始执行该行 (或该串) 命令;
5. 至于如果一行的内容太多,则可以使用『 \[Enter] 』来延伸至下一行;
6. 『 # 』可做为批注!任何加在 # 后面的资料将全部被视为批注文字而被忽略!
执行:
直接指令下达:
shell.sh 档案必须要具备可读与可执行 (rx) 的权限,然后:
绝对路径:使用 /home/dmtsai/shell.sh 来下达指令;
相对路径:假设工作目录在 /home/dmtsai/ ,则使用 ./shell.sh 来执行
变量『PATH』功能:将 shell.sh 放在 PATH 指定的目录内,例如: ~/bin/
以 bash 程序来执行:
透过『 bash shell.sh 』或『 sh shell.sh 』来执行
第一行 #!/bin/bash 在宣告这个 script 使用的 shell 名称
整个 script 当中,除了第一行的『 #! 』是用来宣告 shell 的之外,其他的 # 都是『批注』用途!
主要环境变量的宣告: 建议务必要将一些重要的环境变量设定好,鸟哥个人认为, PATH 与 LANG (如果有使用到输出相关的信息时) 是当中最重要的
以利用 exit 这个指令来让程序中断,并且回传一个数值给系统。
在每个 script 的文件头处记录好:
script 的功能;
script 的版本信息;
script 的作者与联络方式;
script 的版权宣告方式;
script 的 History (历史纪录);
script 内较特殊的指令,使用『绝对路径』的方式来下达;
script 运作时需要的环境变量预先宣告与设定。
read命令接收标准输入(键盘)的输入,例子:
#!/bin/bash
echo -n "Enter your name:" //参数-n的作用是不换行,echo默认是换行
read name //从键盘输入
echo "hello $name,welcome to my program" //显示信息
exit 0 //退出shell程序。
小指令『 $(command) 』
利用 $((计算式)) 来进行数值运算,可惜的是, bash shell 里头预设仅支持到整数的数据而已
直接指令下达或者是利用 bash (或 sh) 来下达脚本时该 script 都会使用一个新的 bash 环境来执行脚本内的指令!
利用 source 来执行脚本,在父程序中执行,因此各项动作都会在原本的 bash 内生效!
利用 test 指令的测试功能
[root@www ~]# test -e /dmtsai && echo "exist" || echo "Not exist" #检查 /dmtsai 是否存在
-e 该『档名』是否存在?(常用)
-f 该『档名』是否存在且为档案(file)?(常用)
-d 该『文件名』是否存在且为目录(directory)?(常用)
-r 侦测该档名是否存在且具有『可读』的权限?
-w 侦测该档名是否存在且具有『可写』的权限?
-x 侦测该档名是否存在且具有『可执行』的权限?
-nt (newer than)判断 file1 是否比 file2 新
-ot (older than)判断 file1 是否比 file2 旧
-eq 两数值相等 (equal)
-ne 两数值不等 (not equal)
-gt n1 大于 n2 (greater than)
-lt n1 小于 n2 (less than)
test -n string 判定字符串是否非为 0 ?若 string 为空字符串,则为 false。 注: -n 亦可省略
test str1 = str2 判定 str1 是否等于 str2 ,若相等,则回传 true
-a (and)两状况同时成立!例如 test -r file -a -x file,则 file 同时具有 r 与 x 权限时,才回传 true。
-o (or)两状况任何一个成立!例如 test -r file -o -x file,则 file 具有 r 或 x 权限时,就可回传 true。
利用判断符号 [ ]
如果要在 bash 的语法当中使用中括号作为 shell 的判断式时,必须要注意中括号的两端需要有空格符来分隔
[□"$HOME"□==□"$MAIL"□]
在中括号 [] 内的每个组件都需要有空格键来分隔;
在中括号内的变数,最好都以双引号括号起来;
在中括号内的常数,最好都以单或双引号括号起来。
例子:
[ "$yn" == "Y" -o "$yn" == "y" ] && echo "OK, continue" && exit 0
[ "$yn" == "N" -o "$yn" == "n" ] && echo "Oh, interrupt!" && exit 0
Shell script 的默认变数($0, $1...)
脚本档名为 $0 这个变量,第一个接的参数就是 $1,第二个接的参数就是$2,...
$# :代表后接的参数『个数』,以上表为例这里显示为『 4 』;
$@ :代表『 "$1" "$2" "$3" "$4" 』之意,每个变量是独立的(用双引号括起来);
$* :代表『 "$1c$2c$3c$4" 』,其中 c 为分隔字符,默认为空格键, 所以本例中代表『 "$1 $2 $3 $4" 』之意。
shift:造成参数变量号码偏移:
shift 会移动变量,而且 shift 后面可以接数字,代表拿掉最前面的几个参数的意思
利用 if .... then
因为
[ "$yn" == "Y" -o "$yn" == "y" ]
上式可替换为
[ "$yn" == "Y" ] || [ "$yn" == "y" ]
所以之前的例子可以写成:
if [ "$yn" == "Y" ] || [ "$yn" == "y" ]; then
echo "OK, continue" exit 0
fi
if [ "$yn" == "N" ] || [ "$yn" == "n" ]; then
echo "Oh, interrupt!" exit 0
fi
更复杂的情况:
if [ "$1" == "hello" ]; then
echo "Hello, how are you ?"
elif [ "$1" == "" ]; then
echo "You MUST input parameters, ex> {$0 someword}"
else
echo "The only parameter is 'hello', ex> {$0 hello}"
fi
利用 case ..... esac 判断
case $1 in
"hello")
echo "Hello, how are you ?"
;;
"")
echo "You MUST input parameters, ex> {$0 someword}"
;;
*)
echo "Usage $0 {hello}"
;;
esac
利用 function 功能
function fname() {
程序段
}
在后续的程序段里面, 只要执行 fname的话,就表示我的 shell script 要去执行『 function fname.... 』 里面的程序段
注意:『 function fname() { 程序段 } 』内的 $0, $1... 等等与 shell script 的 $0 是不同的。
while do done, until do done (不定循环)
while [ "$yn" != "yes" -a "$yn" != "YES" ]
do
read -p "Please input yes/YES to stop this program: " yn
done
echo "OK! you input the correct answer."
--------------
until [ "$yn" == "yes" -o "$yn" == "YES" ]
do
read -p "Please input yes/YES to stop this program: " yn
done
echo "OK! you input the correct answer."
for...do...done (固定循环)
for animal in dog cat elephant
do
echo "There are ${animal}s.... "
done
----------------
users=$(cut -d ':' -f1 /etc/passwd) # 撷取账号名称
for username in $users # 开始循环进行!
do
id $username
finger $username
done
for...do...done 的数值处理
read -p "Please input a number, I will count for 1+2+...+your_input: " nu
s=0
for (( i=1; i<=$nu; i=i+1 ))
do
s=$(($s+$i))
done
echo "The result of '1+2+3+...+$nu' is ==> $s"
shell script 的追踪与 debug
[root@www ~]# sh [-nvx] scripts.sh
选项与参数:
-n :不要执行 script,仅查询语法的问题;
-v :再执行 sccript 前,先将 scripts 的内容输出到屏幕上;
-x :将使用到的 script 内容显示到屏幕上,这是很有用的参数!