如何执行Scripts
我们假设你写的这个程序文件名是 /home/dmtsai/shell.sh
1. 直接指令下达: shell.sh 档案必须要具备可读与可执行 (rx) 的权限,然后:
o 绝对路径:使用 /home/dmtsai/shell.sh 来下达指令;
o 相对路径:假设工作目录在 /home/dmtsai/ ,则使用 ./shell.sh 来执行
o 变量『PATH』功能:将 shell.sh 放在 PATH 指定的目录内,例如: ~/bin/
2. 以 bash 程序来执行:通过『 bash shell.sh 』或『 sh shell.sh 』来执行
执行方式差异:
直接指令下达 (不论是绝对路径/相对路径还是 $PATH 内),或者是利用 bash (或 sh) 来下达脚本指令时, 该 script 都会使用一个新的 bash 环境来执行脚本内的指令,其实 script 是在子程序的 bash 内执行的,当子程序完成后,在子程序内的各项变量或动作将会结束而不会传回到父程序中。
3. 利用 source 来执行脚本:在父程序中执行。
test判断指令
1. 关于某个档名的『文件类型』判断
-e 该『档名』是否存在?(常用)
-f 该『档名』是否存在且为文件(file)?(常用)
-d 该『档名』是否存在且为目录(directory)?(常用)
-b 该『档名』是否存在且为一个 block device 装置?
-c 该『档名』是否存在且为一个 character device 装置?
-S 该『档名』是否存在且为一个 Socket 档案?
-p 该『档名』是否存在且为一个 FIFO (pipe) 档案?
-L 该『档名』是否存在且为一个连结档?
-f 该『档名』是否存在且为文件(file)?(常用)
-d 该『档名』是否存在且为目录(directory)?(常用)
-b 该『档名』是否存在且为一个 block device 装置?
-c 该『档名』是否存在且为一个 character device 装置?
-S 该『档名』是否存在且为一个 Socket 档案?
-p 该『档名』是否存在且为一个 FIFO (pipe) 档案?
-L 该『档名』是否存在且为一个连结档?
2. 关于档案的权限侦测
-r 侦测该档名是否存在且具有『可读』的权限?
-w 侦测该档名是否存在且具有『可写』的权限?
-x 侦测该档名是否存在且具有『可执行』的权限?
-u 侦测该文件名是否存在且具有『SUID』的属性?
-g 侦测该文件名是否存在且具有『SGID』的属性?
-k 侦测该文件名是否存在且具有『Sticky bit』的属性?
-s 侦测该档名是否存在且为『非空白档案』?
-w 侦测该档名是否存在且具有『可写』的权限?
-x 侦测该档名是否存在且具有『可执行』的权限?
-u 侦测该文件名是否存在且具有『SUID』的属性?
-g 侦测该文件名是否存在且具有『SGID』的属性?
-k 侦测该文件名是否存在且具有『Sticky bit』的属性?
-s 侦测该档名是否存在且为『非空白档案』?
3. 两个档案之间的比较
如: test file1 -nt file2
-nt (newer than)判断 file1 是否比 file2 新
-ot (older than)判断 file1 是否比 file2 旧
-ef 判断 file1 与 file2 是否为同一档案,可用在判断 hard link 的判定上。 主要意义在判定,两个档案是否均指向同一个 inode
-ot (older than)判断 file1 是否比 file2 旧
-ef 判断 file1 与 file2 是否为同一档案,可用在判断 hard link 的判定上。 主要意义在判定,两个档案是否均指向同一个 inode
4. 关于两个整数之间的判定
如: test n1 -eq n2
-eq 两数值相等 (equal)
-ne 两数值不等 (not equal)
-gt n1 大于 n2 (greater than)
-lt n1 小于 n2 (less than)
-ge n1 大于等于 n2 (greater than or equal)
-le n1 小于等于 n2 (less than or equal)
-ne 两数值不等 (not equal)
-gt n1 大于 n2 (greater than)
-lt n1 小于 n2 (less than)
-ge n1 大于等于 n2 (greater than or equal)
-le n1 小于等于 n2 (less than or equal)
5. 判定字符串的数据
test -z string 判定字符串是否为 0 ?若 string 为空字符串,则为 true
test -n string 判定字符串是否不为 0 ?若 string 为空字符串,则为 false。 注: -n 亦可省略
test str1 = str2 判定 str1 是否等于 str2 ,若相等,则回传 true
test str1 != str2 判定 str1 是否不等于 str2 ,若相等,则回传 false
test -n string 判定字符串是否不为 0 ?若 string 为空字符串,则为 false。 注: -n 亦可省略
test str1 = str2 判定 str1 是否等于 str2 ,若相等,则回传 true
test str1 != str2 判定 str1 是否不等于 str2 ,若相等,则回传 false
6. 多重条件判定
例如: test -r filename -a -x filename
-a (and)两状况同时成立!例如 test -r file -a -x file,则 file 同时具有 r 与x 权限时,才回传 true。
-o (or)两状况任何一个成立!例如 test -r file -o -x file,则 file 具有 r 或 x 权限时,就可回传 true。
! 反相状态,如 test ! -x file ,当 file 不具有 x 时,回传 true
-o (or)两状况任何一个成立!例如 test -r file -o -x file,则 file 具有 r 或 x 权限时,就可回传 true。
! 反相状态,如 test ! -x file ,当 file 不具有 x 时,回传 true
判断符号 [ ]
使用中括号必须要特别注意:中括号的两端需要有空格符来分隔,假设空格键使用『□』符号来表示,那么,在这些地方你都需要有空格键[□"$HOME"□==□"$MAIL"□]
在中括号 [] 内的每个组件都需要有空格键来分隔; 在中括号内的变量,最好都以双引号括号起来; 在中括号内的常量,最好都以单或双引号括号起来。
中括号的使用方法与 test 几乎一模一样,只是中括号比较常用在条件判断式 if ..... then ..... fi 的情况中
Shell script 的默认变量($0, $1...)
执行的脚本档名为 $0 这个变量,第一个接的参数就是 $1
/path/to/scriptname opt1 opt2 opt3 opt4
$0为/path/to/scriptname, $1为opt1
$0为/path/to/scriptname, $1为opt1
$# :代表后接的参数『个数』,以上表为例这里显示为『 4 』;
$@ :代表『 "$1" "$2" "$3" "$4" 』之意,每个变量是独立的(用双引号括起来);
$* :代表『 "$1c$2c$3c$4" 』,其中 c 为分隔字符,默认为空格键, 所以本例中代表『 "$1 $2 $3 $4" 』之意。
$@ :代表『 "$1" "$2" "$3" "$4" 』之意,每个变量是独立的(用双引号括起来);
$* :代表『 "$1c$2c$3c$4" 』,其中 c 为分隔字符,默认为空格键, 所以本例中代表『 "$1 $2 $3 $4" 』之意。
shift:造成参数变量号码偏移
shift 后面可以接数字,代表拿掉最前面的几个参数的意思
shift 后面可以接数字,代表拿掉最前面的几个参数的意思
条件判断式
1. if...then判断
if [ 条件判断式 ]; then
当条件判断式成立时,可以进行的指令工作内容;
fi <==将 if 反过来写,就成为 fi 啦!结束 if 之意
当条件判断式成立时,可以进行的指令工作内容;
fi <==将 if 反过来写,就成为 fi 啦!结束 if 之意
[ "$yn" == "Y" -o "$yn" == "y" ] 可替换为[ "$yn" == "Y" ] || [ "$yn" == "y" ]
if [ 条件判断式 ]; then
当条件判断式成立时,可以进行的指令工作内容;
else
当条件判断式不成立时,可以进行的指令工作内容;
当条件判断式成立时,可以进行的指令工作内容;
else
当条件判断式不成立时,可以进行的指令工作内容;
fi
if [ 条件判断式一 ]; then
当条件判断式一成立时,可以进行的指令工作内容;
elif [ 条件判断式二 ]; then
当条件判断式二成立时,可以进行的指令工作内容;
else
当条件判断式一不二均不成立时,可以进行的指令工作内容;
fi
2. case...in判断
case $变量名称 in <==关键词为 case ,还有变量前有钱字号
"第一个变量内容") <==每个变量内容建议用双引号括起来,关键词则为小括号 )
程序段
;; <==每个类别结尾使用两个连续的分号来处理!
"第二个发量内容")
程序段
;;
*) <==最后一个变量内容都会用 * 来代表所有其他值 不包含第一个变量内容与第二个变量内容的其他程序执行段
exit 1
;;
esac <==最终的 case 结尾!『反过来写』
"第一个变量内容") <==每个变量内容建议用双引号括起来,关键词则为小括号 )
程序段
;; <==每个类别结尾使用两个连续的分号来处理!
"第二个发量内容")
程序段
;;
*) <==最后一个变量内容都会用 * 来代表所有其他值 不包含第一个变量内容与第二个变量内容的其他程序执行段
exit 1
;;
esac <==最终的 case 结尾!『反过来写』
function 功能
function fname() {
程序段
}
function 也是拥有内建变量的~他的内建变量与 shell script 很类似, 函数名称表示 $0 ,而后续接的变量也是以 $1, $2... 来替代的,函数内的$n将不再表示script的参数。
程序段
}
function 也是拥有内建变量的~他的内建变量与 shell script 很类似, 函数名称表示 $0 ,而后续接的变量也是以 $1, $2... 来替代的,函数内的$n将不再表示script的参数。
循环
1. while do done, until do done (不定循环)
当 condition 条件成立时,就进行循环,直到 condition 的条件不成立才停止
while [ condition ] <==中括号内的状态就是判断式
do <==do 是循环的开始!
程序段落
done <==done 是循环的结束
while [ condition ] <==中括号内的状态就是判断式
do <==do 是循环的开始!
程序段落
done <==done 是循环的结束
当 condition 条件成立时,就终止循环, 否则就持续进行循环的程序段。
until [ condition ]
do
程序段落
done
do
程序段落
done
2. for...do...done (固定循环)
for var in con1 con2 con3 ...
do
程序段
done
do
程序段
done
for (( 初始值; 限制值; 执行步阶 ))
do
程序段
done
do
程序段
done
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
sh [-nvx] scripts.sh-n :不要执行 script,仅查询语法的问题;
-v :在执行 sccript 前,先将 scripts 的内容输出到屏幕上;
-x :将使用到的 script 内容显示到屏幕上,这是很有用的参数