印象中,一直觉得只要多掌握linux命令,自然对于写shell脚本不会陌生.这句话对也不对.前半句对了,的确是要多掌握linux命令,这样才能写出使用高效的脚本,但是后半句不对.要写出shell脚本,还需要掌握shell的内部命令,流程控制,以及重定向等.
最近系统的学习了一些shell的入门,有了很多新的认识,积累如下.
1. 变量:
shell中,变量的使用并不需要声明,可以直接使用,而且没有类型的限制,同样一个变量,不同的操作,决定变量不同的类型,比如 [ $a = $b ],这里的变量a和b,是字符串.但是同样是他俩,[ $a -gt $b ],在这里他俩就成了数字.当然这只是特殊情况,如果a的值并不是数字,是会报错的.
同时需要明确,linux大小写敏感,shell自然也不例外.
另外需要注意的就是变量拓展,即声明一个a变量,$ab并不会被识别成a的值接上b,而应该${a}b.另外一种非变量拓展的方式是"$a"b
环境变量,用来改变shell的行为的一种特殊变量.常用的有
$HOME 当前用户的家路径
$PATH 当前系统的搜索命令的路径
$PS1 命令提示符
$PS2 二级提示符,即当输入的命令没有输入完全的时候的提示符
$IFS 域分隔符 默认是空格,制表符,换行符
$0 shell脚本的名字
$# shell脚本参数的个数
$$ shell脚本的进程号
$1...$n shell脚本的参数
$* shell脚本参数列表,受域分隔符的影响.
[email protected] shell脚本参数列表,不受域分隔符的影响.
例如:
2. 条件判断
test 和 [ ] , 对于判断而言,二者作用是完全一样的,可以使用test就可以用 [ ].
目前判断大致可以分为三种,
字符串的判断
[ $string1 = $string2 ] 字符串相等.这里需要注意空格的使用.
[ $string1 != $string2 ] 字符串不想等
[ -n $string1 ] 字符串不为空
[ -z $string1 ] 字符串为空
数字比较
[ $a -eq $b ] a和b相等
[ $a -ne $b ] a和b不相等
[ $a -gt $b ] a大于b
[ $a -ge $b ] a大于等于b
[ $a -lt $b ] a小于b
[ $a -le $b ] a小于等于b
[ ! a ] a为假则表达式为真,注意空格的使用.
文件判断
-f 是否是普通文件
-e 是否存在,但是存在可移植性问题.并不是每个版本的shell都支持这个选项
-d 是否是目录
-b 是否是块文件.
-s 是否大小不为0
-r 是否可读
-w 是否可写
-x 是否可执行
以上为是,则为真.
3. 流程控制 (if for while until case)
if 测试某个结果,根据结果的不同做出不同的工作.
常见的if控制结构:
if [ condition ]
then
command
elif [ condition ]
then
command
else
command
fi
举个例子:
#!/bin/bash echo what day is it today? read day if [ $day = sateday ] || [ $day = sunday ] then echo oh good!!! else echo oh god... fi
这个小例子里面还包括了一个知识点,即命令列表的知识,简单的拓展一下.
command1 && command2 && command3 && ..... 此shell语句中,从左往右顺序执行,遇到第一个返回false的命令则不再继续执行.
command1 || command2 || command3 || ..... 此shell语句从左往右顺序执行,遇到第一个执行成功的命令就不再继续执行.
for 循环执行执行某个命令块.
用法如下:
for 变量 in 范围
do
something
done
范围可以通过大括号指定,也可以是一个命令或者一个变量.如示例:
#!/bin/bash echo test for 1 for i in {a,b,c} do echo -e "\t$i" done echo test for 1 end echo test for 2 for i in {d..g} do echo -e "\t$i" done echo test for 2 end echo test for 3 for i in `seq 10` do echo -e "\t$i" done echo test for 3 end echo test for 4 filelist=$(ls) for i in $filelist do echo -e "\t$i" done echo test for 4 end
while 循环执行一段代码块但是和for不一样的是,while后面跟的是一个条件限定,而不是一个范围.while循环执行直到条件为假.
基本用法如下:
while condition
do
something
done
一般可以作为condition的有很多,if里面适用的在这里也几乎适用.如下:
#!/bin/bash while read i do echo $i done < for.sh echo "this is a test" | while read i do echo $i done
一定要注意shell中的真假只能用true(:)和false来表示.如果你用0或者1,那就错了.对于shell而言,无论0和1在条件判断中,都是真.而在上面的这个例子中,文件为eof代表条件为假.
until 循环执行一段代码段.和while相反,until循环执行直到条件为真.
用法和while类似.
until condition
do
something
done
惭愧,我一时竟然想不到一个可以使用的例子.抄一段:
#!/bin/bash until who | grep "$1" > /dev/null do sleep 60 done echo -e "\a" echo "$1 logged"
这个脚本的意思是,指定一个参数,也就是$1.如果$1代表的用户登陆过系统,就报警并且打印信息然后退出.否则就循环等待.
case 分支语句,和if有点类似我想,看看用法吧.
case 变量 in
pattern1) something ;;
pattern2) something ;;
esac
还是通过一个实例来看看他是怎么使用的吧.
#!/bin/bash echo will you marry me? read choice case $choice in Y|y|[Yy][Ee][Ss]) echo yes, i will ;; [Nn]*) echo you are good man,please don\'t let me hurt ;; *) echo ni chi fan mei you ;; esac
case的语句可以选择的几种方式,上面都列了出来.
Y|y|[Yy][Ee][Ss] #这段的意思是,无论输入Y或者y或者YEs或者yeS都会输出yes,i will 而*)的意思相当于default. <span style="font-size:18px;">4. 函数</span>
shell的函数很简单.不需要参数,不需要返回值.只需要这样
func()
{
do something
}
但是这个函数看起来不是和废物一样嘛,接受不了参数,又没有办法输出结果.肯定不是啊,shell的函数可以理解成一个脚本内的脚本,也就是说他传递参数的方式和shell脚本接收参数的方式类似.$#表示函数的参数个数,[email protected]函数的参数列表$*也是参数列表$1$2是函数的第1或者2个参数.
#!/bin/bash test_master() { if test $# -ne 2 then echo please input 2 parameter exit fi echo who is the master in your home? for i in `seq $#` do eval res='$'$i if [ $res != "alai" ] then echo $res fi done } test_master alai jingjing
5. 部分命令
本段主要涉及的都是内置命令.
break 用来跳出循环,为内置命令.可以在后面跟一个数字表示跳出多少层循环.一般不建议这么使用.容易把代码逻辑搞乱.
:命令 此命令为空命令.永远表示true,但是运行速度要快于true(书本上这么说的,我反正察觉不到),很早之前的shell习惯性的用 : command 的方式作为脚本注释.现在统一采用#
continue 跳大下一次循环,统一可以跟一个数字表示继续第n此循环,也不建议这么使用.
. 命令 表示在当前shell执行命令.一般我们用的./的方式,会生成一个子进程然后执行脚本,使用这个命令,直接在当前的进程执行命令.
echo 打印命令.不解释啦.
eval 这个命令很有趣,允许对参数进行求值.上面讲解函数的时候也有它的用法.这里不多说啦.不要忘记单引号哈.
exit n 以退出码n来结束脚本的运行.目前而言0表示运行成功.其它表示运行失败.在脚本中多运用这个命令是个很好的习惯.
export 将其后的变量导入到子shell中.
expr 将参数作为表达式求值相当于$[ ] 用法 res=`expr 1+2`
let 作用和expr是一样的,用法有差异 let a=1+1 注意别有空格.这个应该不是内置的
大致就总结这么多吧.希望能够对同学们入门shell有帮助.