首先,我们简单的介绍一下bash,bash是GNU计划编写的Unixshell,它是许多Linux平台上的内定shell,它提供了用户与系统的很好的交互,对于系统运维人员,bash的地位是举足轻重的,bash编程能很快处理日常的任务
bash入门,一个最简单的bash例子
#vim hello.sh #!/bin/bash #This is the first example of the bash #echo “Hello world”
下面,我们就这个简单的bash 脚本来介绍一下bash的基本框架
第一行:
#!:这里是说明这个脚本的类型,即bash程序,需要用/bin/bash来执行
第二行:
除了第一行声明脚本类型,其他的’#’后面的语句都是注释,解释这个脚本,一个好的编程人员,注释是一个好的习惯。
第三行:
输出Hello world这个字符串,echo就是起到输出的作用
这个脚本就这样结束,那我们如何执行这个脚本呢?
方法一:
#bash hello.sh
或
#sh hello.sh #(sh为bash的一个符号链接)
方法二:
#chmod a+x hello.sh #./hello.sh
bash的变量
bash是一种弱类型,可以直接赋值并使用,不像其他语言,无须事先定义
bash的名称规则:
要以字母、数字、下划线命名,且不能以数字开头
不能与系统的变量相互冲突
bash的赋值:
VAR_NAME=VALUE
注意,等于号的中间是没有空格的
实例:
[root@localhost ~]# hobby=linux [root@localhost ~]# echo "My hobby is $hobby learning" My hobby is linux learning
bash的变量类型:
环境变量
本地变量
位置变量
特殊变量
本地变量:作用在整个bash
VAR_NAME=VALUE
局部变量:只在某个脚本中有效,当脚本执行结束后,被释放
localVAR_NAME=VALUE
要使用local 来表明这个变量时局部变量
环境变量:对当前的shell以及这个shell产生的子shell有效
exportVAR_ANME=VALUE
实例:export PATH=$PATH:/usr/local/apache/bin
位置变量:
实例:#bash test.sh 1 23 4
上面执行一个脚本,后面的1、23、4就是传递给脚本的位置变量
在脚本中一般都为:$0、$1、$2…${10},$0是一个特殊的位置变量,它表示的是一个脚本的自身,这里指test.sh,10以后的位置变量用花括号括起来
这里,我们还得再提一下有些特殊变量
$?:命令执行后的返回值
返回的状态码有(0-255)
echo$?
实例:
[root@localhost ~]# echo "Helloworld" ;echo $? Hello world 0
若是返回0,则表明上一个程序或是脚本被成功执行了
实例:
[root@localhost ~]# cat /etc/passwd1 ; echo $? cat: /etc/passwd1: No such file or directory 1
若是1-255,表明执行错误,具体,我就不一一说明了
$#:一般是指传递的参数的个数,可以是位置变量的总个数
$@、$*:代替的是整个参数的列表,但是,用双引号括起来的时候,$@表现为一个列表中有多个元素,则$*则是表现为一个元素的列表,这也是它们的不同之处,有兴趣的可以查阅资料
bash变量的撤销
其实,我们上面提到过了,bash的变量不用可以的去实现声明,当我们再次用到某一个 变量时,重新赋值即可,但,也是有撤销命令的,即unset
[root@localhost~]# hobby=linux [root@localhost ~]# echo $hobby linux [root@localhost~]# unset hobby [root@localhost~]# echo $hobby
或是重新赋值,再次使用
[root@localhost ~]# hobby=linux [root@localhost ~]# echo $hobby linux [root@localhost~]# hobby=python [root@localhost~]# echo $hobby python
bash变量的取值
$VAR_NAME
${VAR_NAME}:花括号可以省略,所有一般都写成上面的格式
实例:
[root@localhost~]# hobby=linux [root@localhost ~]# echo $hobby linux [root@localhost ~]# echo ${hobby} linux
bash的基本循环语法
一、for
1、for 变量 in 列表
do
循环体
done
列表中包含一个或多个元素;当for遍历列表结束后,这个循环就结束了
实例:在/tmp目录下创建是个10文件,为file1-file10
#!/bin/bash #the firstexample of the for for file in {1..10} do touch /tmp/file$file done
这样,在/tmp下就生成了10个文件了
这里的列表的生成方式有多种:
I、{startnumber..endnumber}
例如:{1..100},1到100
II、使用seq命令
seq startnumber step endnumber
使用seq时,要使用命令引用
实例:
#!/bin/bash #the second example of the for for file in `seq 1 2 10` do touch /tmp/file$file done
这个脚本就是生成数字为奇数的文件,即file1、file3,seq的命令引用是采用反引号的,步进值为2
III、也可以是所有的位置变量$@
IV、也能以命令的方式生成
2、for ((变量初始化;条件判断;变量变化))
do
循环体
done
实例:
#!/bin/bash #Thisis the third example of the for for((i=1;i<=10;i++)) do echo$i done
这个脚本会输出1-10,这些数字,初始变量i为1,条件判断是i小于等于10时,执行其循环体,大10则跳出循环体,每循环一次,i的值会自动加1。
二、while
1、while 条件
do
循环体
done
实例:
#!/bin/bash #thefirst example of while while[ $1 –gt 1 ] do echo“The number you gluess is bigger” exit3 done cho“you gluess it”
这个脚本是让用户输入一个位置变量,并判断这个位置变量的大小,如果大于1,则输出循环体的内容,小于等于1时,输出循环体外的内容
这里有两个知识点,有可能大家不知道,一个是-gt是什么意思,另一个是exit 3,我先解释后者,前面-gt留到判断时再说
exit 退出循环体,并返回状态值,可以自己定义,上面提到过了
-gt其实就是数字间的判断,gt是大于的意思
2、while死循环
while true
do
循环体
done
实例:
#!/bin/bash #thisis a loop while whiletrue do echo“hello world” done
这个脚本会一直输出helloworld,直到用户按下Ctrl+c中断其执行
3、读取文件的每一行,并且进行操作
while read VAR_NAME
do
循环体
done< file
实例:取出系统的用户名,使用while语句
#!/bin/bash #thethird example of while while read line do echo$line | cut -d: -f1 done< /etc/passwd
三、until
until表达式
do
循环体
done
只要条件满足表达式中的内容,就跳出循环,如果不满足,则继续执行循环体
实例:
#!/bin/bash #thefirst example of until echo"you can input q to quit" until[ "$Username" == "q" ] do read -p "Pleease input a username: " Username echo"The username you input is: $Username" done
上面的脚本,直到用户输入quit时,才会退出,要不然,会一直让你输入用户名,是一个死循环。
bash的流程控制语句
测试类型,根据比较时的操作数的类型
整型测试:整数比较
字符测试:字符创间的比较
文件测试:判断文件的存在性以及属性等
整型测试:
-gt:大于
-lt:小于
-ge:大于等于
-le:小于等于
-eq:等于
-ne:不等于
字符串测试:
>:大于
<:小于
>=:大于等于
<=:小于等于
==:等于
!=:不等于
单目:
-nstring:是否不为空,不为空则为真,空则为假
-zstring:是否为空,空则为真,不空则假
文件测试:
-eFILE:存在则为真,否则则为假
-fFILE:存在并且是普通文件,则是真,否则为假
-dFILE:存在并且是目录文件,满足为真,否则为假
-LFILE:存在且为符号链接文件,满足为真,否则为假
-b:判断是否为块设备
-c:判断是否为字符设备
-S:判断是否为套接字文件
-p:判断是否为命名管道
-sFILE:存在且为非空的文件,满足为真,否则为假
-rFILE:判断一个是否有读的权限
-wFILE:判断一个是否有写的权限
-xFILE:判断一个是否有执行的权限
1、 if…then…else
if语句用于判断和分支
判断示例:
if [ expression ]
then
staments
fi
实例:
#!/bin/bash #the firstexample of for if [ 2 –gt 1 ] then echo 2 is bigger fi
2、 if [ expression ]
then
statements
else
statements
fi
实例:
#!/bin/bash #the secondexample of for if [ a > b ] then echo “ a is bigger” else echo“b is bigger” fi
3、 多分支结构
if [expression ]
then
staments
elif
staments
…
else
stament
fi
实例:
#!/bin/bash #this is a loopwhile read -p"Enter a username: " Username UserID=`id -u $Username` if [ $UserID -eq0 ] then echo "System admin." elif [ $UserID-lt 500 -a $UserID -gt 0 ] then echo "System user." else echo "Normal user." fi
case语句:通过检测字符串的样式是否匹配,数目是否相等,进行相应不同的处理
case expression in
pattern1)
statements;;
pattern2)
statements;
…
esac
实例:
#!/bin/bash #the first example of case case $1 in start) echo "The service is start" ;; stop) echo "The service is stop" ;; restart) echo "The service is restart" ;; *) echo "Please input like {start|stop|restart}" esac
bash循环控制:
break和continue
break[n]:跳出当前的循环,可以跳出多步,用于条件语句中
实例:
#!/bin/bash #the example ofbreak read -p"Enter a username: " userName while true do if who | grep "\<$userName"&> /dev/null;then break fi echo"the user you input is not here,pelase wait" sleep 3 done echo "Theuser $userName is coming"
continue:跳过本次循环中的代码,直接跳回循环开始的位置
实例:打印1-10,3-5不打印
#!/bin/bash #the example ofcontinue for((i=1;i<10;i++)) do if [ $i -gt 2 ] && [ $i -lt 6 ] then continue fi echo "The number is: $i" done
bash的函数定义以及应用:
定义方法有两种:
1、 function func1 {
statements
}
2、 func1() {
statements
}
函数的返回值:
函数的执行结果返回值:代码的输出
函数中的打印语句:echo,print
函数中动用的系统命令执行后返回的结果
执行状态返回值:
函数体重最后一次执行的命令状态结果
自定义函数执行状态的返回值:return #
实例:
#!/bin/bash #using the return in a function function test { read -p "Enter a number: " numBer echo "doubling the value" return $[ $numBer * 2 ] } test echo "The new value i
给函数中传递变量
#!/bin/bash #trying toaccess parameters inside a function function send { echo $[ $1 * $2 ] } if [ $# -eq 2 ] then result=`send $1 $2` echo "The result is $result" else echo "Usage: scripts a b" fi
bash数组
数组的组成格式:
数组名+索引
数组的赋值:
一次一个元素赋值
a[0]=$RANDOM
一次对全部元素赋值
a=(linuxpython php perl)
按索引进行赋值
a=([0]=linux[4]=python [1]=perl)
数组的访问:
通过索引访问:
ARRAY[index]
数组的长度:
${#ARRAY[*]}
${#ARRAY[@]}
从数组中挑选出某元素
${ARRAY[@]:offset:number}
这是一种切片的方法:
offset:偏移元素的个数
number:取出元素的个数
${ARRAY[@]:offset}:取出偏移量后的元素
从数组中删除元素:
unsetARRAY[index]
bash字符串操作
字符串切片:
${string:offset:length}
实例:
[root@localhosttmp]# string=www.magedu.com [root@localhosttmp]# echo ${string:4:6} magedu
取尾部的指定个数的字符
${string:-length}
[root@localhost tmp]# string=www.magedu.com [root@localhost tmp]# echo ${string: -3} com
取子串:基于模式
${variable#*word}:在variable中存储字串上,自左而右,查找第一次出现word,删除字符开始至此word处的所有内容。
${variable##*word}:在variable中存储字串上,自左而右,查找最后一次出现word,删除字符开始至此word处的所有内容。
实例:
[root@localhost ~]#file=‘/var/lib/dhcp/dhcpd.release‘ [root@localhost ~]#${file#*/} #返回的结果var/lib/dhcp/dhcpd.release [root@localhost ~]#${file##*/} #返回的结果:dhcpd.release
${variable%word*}: 在variable中存储字串上,自右而左,查找第一次出现word,删除此word处至字串尾部的所有内容。
${variable%%world*}:在variable中存储字串上,自右而左,查找最后一次出现word,删除此word处至字串尾部的所有内容。
实例:
[root@localhost ~]#file=‘/var/lib/dhcp/dhcpd.release‘ [root@localhost ~]#${file%*/} #返回的结果为/var/lib [root@localhost ~]#${file%%*/} #返回的结果为空
变量赋值操作:
${variable:-string}
variable为空或是没有设定值时,返回string的值,如果有值的话,返回自己的值。
${variable:=string}
variable为空或是没有设定值时,返回string的值,同时,string的值会赋给variable,否则,返回variable本身的值
总结:bash编程是一门非常容易的编程语言,但是,也需要经常去练习它,多掌握bash的编程技巧,才能让你在生产环境下,让你处理linux系统问题时,得心应手。
本文出自 “牛叉的孩子光着屁屁” 博客,请务必保留此出处http://cshang.blog.51cto.com/6143980/1534972
原文地址:http://cshang.blog.51cto.com/6143980/1534972