本文主要讲 linux 中 shell 的编程
目录
一些说明
一般 shell 只能处理整数,使用 awk 和 bc 来计算浮点数
关于 shell 中的变量,之前的文章已经讲过
脚本一般用 .sh 结尾,虽然说 linux 中不要求什么后缀名格式,但是这个后缀是说明这是个脚本,是为了方便人看的
在脚本的前面有时候会有 #! /bin/sh ,这个是指定运行 shell 的解释器,可写可不写
用 -x 在命令运行前打印,这样可以知道现在进行到哪一行,出错了方便调试
$ /bin/sh –x trim.sh
在脚本中传递参数
1、逐个传递参数
脚本中 $0 代表脚本的名称
$1 和 $2 ...代表
语法如下
$ script.sh argument1 argument2 argument3 .... argumentx 对应 $0 $1 $2 $3 $4....
看一段例子
$ cat color3.sh
echo the name of the script : $0
echo the first argument is : $1
echo the second argument is : $2
$ chmod u+x color3.sh
$ color3.sh tt yy
the name of the script : color3.sh
the first argument is : tt
the second argument is : yy
2、整体传递一串参数
$* 代表所有的参数
$# 代表参数的个数
使用 shift 可以将这串参数向左移动
$ cat ./test.sh
echo we got $*
shift 2 # 所有参数整体左移两个
echo shift 2 and we got $* shift 2
echo shift 2 again we got $* shift 2
echo finally $*
$ ./test.sh 1 2 3 4
we got 1 2 3 4
shift 2 and we got 3 4
shift 2 again we got finally # 依然为空
# 这里说明没有参数了继续 shift 的话就是空
3、$$代表当前进程号
(base) 123deiMac:~ a123$ echo $$
2649
(base) 123deiMac:~ a123$ ps
PID TTY TIME CMD
2649 ttys000 0:00.02 -bash
read 命令
用于在脚本运行期间在键盘上输入命令
但实际上 read 最多的用法是让程序暂停一下(因为我们希望程序是自动运行,在运行期间无需再输入参数)
返回码 Return Code
$? 代表程序运行的返回码
使用 exit 0 指定返回码为 0
在程序的循环/选择/判断分支中指定返回码,可以判断程序的执行情况
要注意 shell 中返回 0 一般代表正常
返回 1 代表错误
使用 test 比较整数的大小
语法
[ number option number ] # 注意这里的方括号内一共有四个空格,要打全四个空格不然 shell 不认
或者
test number option number
shell 一般只能处理整数,要用浮点数的话考虑 awk 和 bc
Option :
-lt less than
-le less than or equal to
-gt greater than
-ge greater than and equal to
-eq equal to
-ne not equal to
(base) 123deiMac:~ a123$ tmp=3
(base) 123deiMac:~ a123$ [ "$tmp" -lt 5 ]
(base) 123deiMac:~ a123$ echo $?
0
(base) 123deiMac:~ a123$ ["$tmp" -lt 5] # 没打全四个空格
-bash: [3: command not found
(base) 123deiMac:~ a123$ test $tmp -lt 5
(base) 123deiMac:~ a123$ echo $?
0
使用test比较字符串
注意这里比较是否相同时一个等号(而非 C++ 中的两个等号)
[ “string1” = “string2” ] # string1 与 string2 相等则返回真
[ “string1” != “string2” ] # string1 与 string2 不相等则返回真
[ -z “string” ] # string 的长度为零则返回真
[ -n “string” ] # string 的长度不为零则返回真
[ “string” ] # 同上一条
看一个例子,感受用 test 进行数字比较和字符串比较的异同
$tt =03
$ bb = 3
$ [ “$tt” –eq “$bb” ] # do numerical comparison
$ echo $? # true
0
$ [ “$tt” = “$bb” ] # do string comparison
$ echo $? # false
1
使用test比较文件
语法:
$ test -option filename
或
$ [-option filename ] # 注意是三个空格
Options:
-d FILE # FILE exists and is a directory
-e FILE # FILE exists
-f FILE # FILE exists and is a regular file
除此之外,可以用 -nt 和 -ot 比较两个文件的新旧
$ [ FILE1 -nt FILE2 ] # true, if FILE1 is newer (modification date) than FILE2
$ [ FILE1 -ot FILE2 ] # true, if FILE1 is older than FILE2
判断分支:if 和 case
if 用于二分支,case 用于多分支
没有大括弧,一般使用缩进方便阅读(没有缩进机器也认识,但是人不容易看)
把指定字反过来写以结束此分支
$ more color14.sh
#!/bin/sh
echo “pls input a value : \n” read xx
if [ “$xx” –gt 10 ]
then
echo xx
echo is larger than 10
else
echo xx is less than 10
fi
下面这个例子说明 case 的匹配中
* 表示任意字符(包括空字符)
? 表示单个字符
[...] 匹配方括号中的任意字符
| 表示或
$ more color15.sh
#!/bin/sh
echo “pls input a value : \n” read xx
case $opt in
1) echo option 1 ;;
2) echo option 2 ;;
3) echo option 3 ;;
*) echo option not in 1-3 ;;
esac
使用 let 在 shell 中赋值
$ x=1.1
$ y=8
$ z=2.2
$ let aa=x+y
-bash: let: 1.1: syntax error in expression (error token is ".1")
$ let bb=y/x
-bash: let: 1.1: syntax error in expression (error token is ".1")
# system gives error message
$ let cc=y/3
$ echo $cc 2 # 说明结果是浮点数时只会取整数部分,不会四舍五入
let 除了赋值还能比较数的大小(和 test 的操作符不一样,test 要四个空格,使用 -lt 等,let 使用大于小于号)
$ x =2
$ (( x=x+2 ))
$ echo $x
4
$ (( x < 1 ))
$ echo $?
1 # false
shell 中的循环:for while 和 until
这三个中用的最多的还是 for
while 和 until 就是相互为否定的关系
until 和 while 加了否定就可以互换
所以这里重点讲 for
1、在一个列表中循环
$ more color23.sh
#!/bin/sh
for xx in 1 2 3 4 5 do
let xx=xx*xx
echo xx is $xx
done
$ chmod u+x color23.sh
$ color23.sh
xx is 1
xx is 4
xx is 9
xx is 16
xx is 25
2、字符串的循环 考虑使用 cat
$ more color24.sh
#!/bin/sh
ls > dir_list # save the directory list in file dir_list
for xx in $(cat dir_list) # list in the format of $(command) # for xx in dir_list
do
if test -d $xx # if $xx is a directory
then
echo the content of dir $xx
ls -F $xx # list the content of directory $xx
echo
fi
done
3、其他一般的循环,语法类似 C++
for((i=1;i<=10;i++));do echo $(expr $i \* 4);done
for((i=1;i<=10;i++))
do echo $(expr $i \* 4) # do echo `expr $i \* 4`
done
4、for 中的 break continue 和 exit
类似于 C++
break 退出本次循环
continue 跳过本次循环
exit 退出这个程序
shell 中的函数
工作中会用到,这里不展开讲