shell script 就是利用shell的功能所写的程序,这个程序是使用纯文本文件,将一些shell的语法和命令(包括外部命令)写在里面,搭配正则表达式、管道命令和数据流重定向等功能,以达到我们的目的。
假设存在/home/dmtsat/shell.sh
命令执行顺序,从上至下,从左至右
命令执行会忽略空白
空白行也会被忽略
tab视为空白
读取到enter符号,就尝试开始执行该行(或该串)命令
如果需要换行的话,可以使用 \[Enter]
来扩展到下一行
#可以作为批注, 也就是注释
直接命令执行:shell.sh文件必须要具备可读和可执行(rx)权限
/home/dmtsai/shell.sh
工作目录在 /home/dmtsai 命令:./shell.sh
以bash执行的话,通过 bash shell.sh 或者 sh shell.sh执行
test
命令用于检查文件类型和比较值,并且根据表达式的值来确定状态并退出。所以如果只执行test
命令,是不会有任何输出的,可以使用echo $?
来查看上次执的状态码(0表示成功,其他值则表示不成功)。用在Shell Script中可以作为判读语句和if..then
一起使用,如果在终端输出打印,则经常和管道命令&&
和||
一起使用,如:
$ test 1 -ge 2 && echo "yes" || echo "no"
no12
shell中提供了逻辑运算符-a, -o, !,表示与,或,非:
test Expression # 表达式是否为true
test ! Expresssion # 表达式是否为false
test Expression1 -a Expression2 # 表达式1和2都是否为true
test Expression1 -o Expression2 #是否表达式1或2为true1234
如:
# 如果1>0 且 2>3,输出true,否则false
$ test 1 -gt 0 -a 2 -gt 3 &&echo "true" || echo "false"
false
# 如果1>0 或 2>3,输出true,否则false
$ test 1 -gt 0 -o 2 -gt 3 &&echo "true" || echo "false"
true
# 如果1>1或2>3,输出true,否则false
$ test 1 -gt 1 -o 2 -gt 3 &&echo "true" || echo "false"
false123456789
test
命令也可以判断字符串长度是否为0,还可以比较两个字符串:
test -n String # 字符串长度不为0则为true
test String #等效-n参数
test -z String # 字符串长度为0,则为true
test String1 = String2 #字符串1和2相等,则为true注意空格
test String != String2 # 字符串1和字符串2不等,则为true12345
如:
$ test "" && echo "true" || echo "false"
false
$ test "12123" && echo "true" || echo "false"
true
$ test -n "" && echo "true" || echo "false"
false
$ test -z "" && echo "true" || echo "false"
true
$ test "123" = "132" && echo "true" || echo "false"
false
$ test "123" = "123" && echo "true" || echo "false"
true
$ test "123" != "132" && echo "true" || echo "false"
true
$ test "123" != "123" && echo "true" || echo "false"
false12345678910111213141516
test
命令可用来比较两个数的大小:
test Integer1 -eq Integer2 #数字1等于数字2,则为true
test Integer1 -ge Integer2 #数字1大于等于数字2,则为true
test Integer1 -gt Integer2 #数字1大于数字2,则为true
test Integer1 -le Integer2 #数字1小于等于数字2,则为true
test Integer1 -lt Integer2 #数字1小于数字2,则为true
test Integer1 -ne Integer2 #数字1不等于数字2,则为true123456
如:
$ test 1 -le 0 && echo "true" || echo "false"
false
$ test 1 -ge 0 && echo "true" || echo "false"
true
$ test 1 -gt 0 && echo "true" || echo "false"
true
$ test 1 -lt 0 && echo "true" || echo "false"
false
$ test 1 -ne 0 && echo "true" || echo "false"
true12345678910
test -b FILE #文件是否存在并且是块设备
test -c FILE #文件是否存在并且是字符文件
test -d FILE #文件是否存在并且是目录(常用)
test -e FILE #文件是否存在(常用)
test -f FILE #文件是否存在并且是普通文件(常用)
test -h FILE #文件是否存在并且是连接文件
test -L FILE #等效于-h
test -p FILE #文件是否存在且为一个管道文件(FIFO)
test -r FILE #文件是否存在并且具有可读权限
test -s FILE #文件是否存在并且文件大小不为0
test -S FILE #文件是否存在并且是一个Socket
test -t FD #文件描述符FD是否在终端打开
test -w FILE #文件是否存在并且具有可写权限
test -x FILE #文件是否存在并且具有可执行权限
如:
# 当前目录下存在一个android文件夹
$ ls -l
total 4
drwxrwxr-x 2 root root 4096 6月 26 16:50 testFile
$ test -e testFile && echo "true" || echo "false"
true
$ test -b testFile && echo "true" || echo "false"
false
$ test -c testFile && echo "true" || echo "false"
false
$ test -d testFile && echo "true" || echo "false"
true
$ test -e testFile && echo "true" || echo "false"
true
$ test -f testFile && echo "true" || echo "false"
false
$ test -h testFile && echo "true" || echo "false"
false
$ test -r testFile && echo "true" || echo "false"
true
$ test -s testFile && echo "true" || echo "false"
true
$ test -S testFile && echo "true" || echo "false"
false
$ test -w testFile && echo "true" || echo "false"
true
$ test -x testFile && echo "true" || echo "false"
true
[]
的使用在shell script中,除了经常使用test
命令来判断表达式外,还可以使用判断符号[]
,不过需要注意一下几点:
$ name=shell
$ [ "$name" == "shell" ] && echo "true" || echo false
true123
判断符号中也支持逻辑运算符-a,-o,!
,以及test
命令中的一些判断参数,如:
$ [ "$name" == "shells" -a 1 -gt 0 ] && echo true || echo false
false
执行命令: /path/to/scriptname opt1 opt2 opt3
默认变量 : $0 $1 \$2 \$3
默认变量 | 含义 |
---|---|
$0 | 当前脚本的文件名 |
n|传递给脚本的参数。n是一个数字,表示第几个参数。例如,第一个参数是 n | 传 递 给 脚 本 的 参 数 。 n 是 一 个 数 字 , 表 示 第 几 个 参 数 。 例 如 , 第 一 个 参 数 是 1,第二个参数是$2 | |
$# | 传递给脚本或函数的参数个数。 |
∗|传递给脚本或函数的所有参数。代表:" ∗ | 传 递 给 脚 本 或 函 数 的 所 有 参 数 。 代 表 : " 1c 2c 2 c 3” 其中c为分隔符,默认为空格键 | |
$@ | 传递给脚本或函数的所有参数。被双引号(” “)包含时,与 $* 稍有不同。代表:”$1” 、”$2”、 “$3” |
$? | 上个命令的退出状态,或函数的返回值。 |
$$ | 当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。 |
[root@iZ2zee88b1mcsq6mmf7w95Z ~]# cd scripts/; cat sh03.sh
#!/bin/bash
# Program:
# This program is hello world!
#
echo "Total -> $#"
echo "whole -> '$@'"
shift
echo "num -> $#"
echo "whole -> '$@'"
shift 3
echo "num -> $#"
echo "whole -> '$@'"
exit 0
[root@iZ2zee88b1mcsq6mmf7w95Z scripts]# ./sh03.sh one two three four five six seven
Total -> 7
whole -> 'one two three four five six seven'
num -> 6
whole -> 'two three four five six seven'
num -> 3
whole -> 'five six seven'
[root@iZ2zee88b1mcsq6mmf7w95Z scripts]#
shift 后面接数字,就是去掉最前面的几个参数。
if [条件判断式]; then
当条件成立后,可以进行的命令工作内容;
fi
#fi表示结束if
举例子吧 输入 yes or no
[root@iZ2zee88b1mcsq6mmf7w95Z scripts]# nl sh04.sh
1 #!/bin/bash
2 # Program:
3 # This program is hello world!
4 #
5 read -p "please input(y/n):" result
6 if [ "$result" == "Y" ] || [ "$result" == "y" ] ; then
7 echo "yes"
8 exit 0
9 fi
10 if [ "$result" == "N" ] || [ "$result" == "n" ] ; then
11 echo "no"
12 exit 0
13 fi
14 exit 0
[root@iZ2zee88b1mcsq6mmf7w95Z scripts]# ./sh04.sh
please input(y/n):y
yes
[root@iZ2zee88b1mcsq6mmf7w95Z scripts]# ./sh04.sh
please input(y/n):N
no
[root@iZ2zee88b1mcsq6mmf7w95Z scripts]#
注: 特别要注意[] 中的空格 必须写啊
#一个简单条件判断
if [条件判断式]; then
当条件成立后,可以进行的命令工作内容;
else
当条件不成立时,执行的命令;
fi
# 多个条件判断
if [条件判断式1]; then
当条件1成立后,可以进行的命令工作内容;
elif [条件判断式2]; then
当条件2成立时,执行的命令;
elif ......
else
当前面的所有条件都不成立的时候,执行这个;
fi
将上面的改成这个格式:
[root@iZ2zee88b1mcsq6mmf7w95Z scripts]# nl sh05.sh
1 #!/bin/bash
2 # Program:
3 # This program is hello world!
4 #
5 read -p "please input(y/n):" result
6 if [ "$result" == "Y" ] || [ "$result" == "y" ] ; then
7 echo "yes"
8 elif [ "$result" == "N" ] || [ "$result" == "n" ] ; then
9 echo "no"
10 else
11 echo "error "
12 fi
13 exit 0
[root@iZ2zee88b1mcsq6mmf7w95Z scripts]# ./sh05.sh
please input(y/n):y
yes
[root@iZ2zee88b1mcsq6mmf7w95Z scripts]# ./sh05.sh
please input(y/n):n
no
[root@iZ2zee88b1mcsq6mmf7w95Z scripts]# ./sh05.sh
please input(y/n):a
error
[root@iZ2zee88b1mcsq6mmf7w95Z scripts]#
类似于switch…case
case $变量名称 in #关键字是case 还有变量前有$
"第一个变量内容")
程序段
;;
"第二个变量内容")
程序段
;;
"第三个变量内容")
程序段
;;
*) #类似于default
exit 1
;;
esac
eg:
[root@iZ2zee88b1mcsq6mmf7w95Z scripts]# nl sh07.sh
1 #!/bin/bash
2 # Program:
3 # This program is hello world!
4 #
5 typeset -l result
6 read -p "please input(y/n):" result
7 #result=echo $result | tr 'A-Z' 'a-z'
8 echo $result
9 case $result in
10 "y" )
11 echo "yes"
12 ;;
13 "n")
14 echo "no"
15 ;;
16 *)
17 echo "error "
18 exit 1
19 ;;
20 esac
21 exit 0
[root@iZ2zee88b1mcsq6mmf7w95Z scripts]# ./sh07.sh
please input(y/n):Y
y
yes
[root@iZ2zee88b1mcsq6mmf7w95Z scripts]#
函数不需要太多解释了,直接上用法吧!
function 函数名(){
}
举个例子吧:
[root@iZ2zee88b1mcsq6mmf7w95Z scripts]# cat sh08.sh
#!/bin/bash
# Program:
# This program is hello world!
#
function printfMe(){
echo -n "your choice is: " #-n表示不断行继续在同一行显示
}
echo "This program will print your selection!"
case $1 in
"one")
printfMe; echo $1 | tr 'a-z' 'A-Z'
;;
"two")
printfMe; echo $1 | tr 'a-z' 'A-Z'
;;
"three")
printfMe; echo $1 | tr 'a-z' 'A-Z'
;;
*)
printfMe; echo "shit";;
esac
exit 0
[root@iZ2zee88b1mcsq6mmf7w95Z scripts]# ./sh08.sh one
This program will print your selection!
your choice is: ONE
[root@iZ2zee88b1mcsq6mmf7w95Z scripts]# ./sh08.sh two
This program will print your selection!
your choice is: TWO
[root@iZ2zee88b1mcsq6mmf7w95Z scripts]# ./sh08.sh Three
This program will print your selection!
your choice is: shit
[root@iZ2zee88b1mcsq6mmf7w95Z scripts]#
函数的内置变量和shell script的内置变量差不多。
用 $0 $1 $2…来代替,这里就不演示了。传参的方式就是 函数名 参数1 参数2 ...
#条件成立时进行循环
while [ 判断式 ]
do #do是循环的开始
程序段
done #done是循环的的结束
#条件成立时就终止循环,否则继续执行
util [ 判断式 ]
do #do是循环的开始
程序段
done #done是循环的的结束
for var in con1 con2 con3...
do
程序段
done
#第一次循环 $var的值是con1 第二次是con2 依次类推...
#数值处理
for ( (初始值;限制值;执行步长) )
do
程序段
done
写一个i++的例子吧
s=0
for ( (i=1; i<=100; i=i+1) )
do
s=s+1
done
利用bash的相关参数调试
格式:sh [-nvx] test.sh
参数:
typeset
有两个选项 -l 代表小写 -u 代表大写。
用法:
typeset -u name
name=’asdasdas’
echo $name
typeset -l ame
ame=’asdasdas’
echo $ame
结果:
ASDASDAS
asdasdas
利用表达式
echo ‘hello’ | tr ‘a-z’ ‘A-Z’
echo ‘HELLO’ | tr ‘A-Z’ ‘a-z’
结果:
HELLO
hello