bash脚本编程
脚本文件格式:
第一行顶格:#!bin/bash (shebang)
注释信息:以#开头
代码注释:好的程序员必备
适量的添加缩进或添加空白行以示分割
语言:编程语言格式:库,算法和数据结构
编程思想:
能够把学到的编程语言的语法格式随时转换为解决问题的思路
问题空间–》解空间
什么是变量
变量是bash环境或脚本编程中是非常重要的东西,linux是多用户多任务的的操作环境,用户需要调用变量的只来进行操作
变量就是一些特定的字符串,只不过不表示原有的意思, 比如:“name=magedu” 就是一个变量,就用一个简单的字符来代替另一个比较复杂或则比较容易更改变动的值,这就是变量
系统自带有很多变量,可使用set或declare查看。
变量:
局部变量:作用域为某代码片段
本地变量:作用域为当前shell进程
环境变量:作用域为当前shell及其子shell
位置参数变量:向执行脚本的shell教程传递参数
特殊变量:shell内置的有特殊功能的便令
变量的命名规则
1.变量名称不能以数字开头,可使用字母数字下划线
2.变量命令尽量见名知义
3.使用标准命名规则:驼峰命令法
4.不能使用系统中只带的关键字(如cd、if、ehco……)
数据类型;
字符型,数值型,(精确数值,整数,近似数值(浮点数(单精度、双精度)))
shell:弱类型,默认把所有字符都表示为字符型
注:shell本身不支持浮点数运算,只能借助其他工具
#animal=dog
#echo “${animal}s”
引用:#PATH=“$PATH:/usr/local/apche/bin”
算术运算:+、-、*、/、%
1、let var=$num1 op $num2 == let var=expression
op:操作运算符(+、-、*、/、%)
2、var=$[experssion]
3、var=$((experssion))
4、var=$(expr arg1 arg2 arg3)
注意: 一个小括号表示命令引用
有些时候乘法需要转义
不加var则表示直接运算
增强型赋值:变量做某种算术运算后,回存到此变量中
1、declare -i i=1
i=$[$i+1] 在自身加1
2、let i=$i+# #=数字
let i+=#
+=、-=、*=、/=、%= //此用法一般用在let在shell脚本中
自增
var=$[$var+1]
let var+=1
let var++
自减
var=$[$var-1]
let var-=1
let var–
条件测试:
判断某需求是否满足,需要由测试机制来实现
如何编写测试表达式实现所需的测试
(1)执行命令,并利用命令状态返回值来判断
0:成功
1~255:失败
#who | grep "^centos\>"
#echo $?
#1
(2)测试表达式
test expression
#test 2 > 3
#echo $?
#1
[experssion]
[[ experssion ]]
注意:experssion两端必须有空白字符,否则为语法错误
bash的测试类型
数值类型:
比较数值
-eq :是否等于 #[ $num1 -eq $num2 ]
-ne:是否不等于
-gt:是否大于
-ge:是否大于等于
-lt:是否小于
-le:是否小于等于
字符串测试:(ascll)码表来判断比较
字符比较(通常来判断字符是否为空)
== 是否等于 #[ tom == Tom ] 判断str1是否等于str2
>:是否大于 [[ “a” > “b”]]
!=:是否不等于
=~:左侧字符串是否能够被右侧的PATTERN所匹配
注意:比较表达式要写在中括号中,赋值不写在中括号中
注意:1、在进行字符串比较时尽可能使用双中括号 "[[ ]]",单中括号有时不能识别
2、字符串要加引号 (如果有变量则双引,无则单引)
3、作比较时要使用双中括号 “[[ ]]”
#name=tom
# [[ "$name" =! "o" ]] //注意此为字符O
#echo $?
#0 注意:匹配是只要包含有一部分字符即可
-z “string” :判断指定的字符串是否为空,空则真,不空则假
-n "string" :判断指定的字符串是有不空,不空则真,空则假
脚本的返回值:
默认是脚本中执行的最后一条命令的状态返回值
自定义状态范围值(退出状态码)
exit n :n为自己指定的状态码
0:成功
!0:失败
注意:shell进程遇到exit时即会终止,因此整个脚本执行即为结束
文件测试:做文件的存在性、权限、等相关测试
存在性测试:
-a file
-e file
#[ -e /path/to/somefile ]
//测试文件的存在性测试,存在则为真,否则为假
文件存在性及类型测试:
-b file :是否存在并且为块设备文件
-c file :是否存在并且为字符文件
-d file :是否存在并且为目录文件
-f file :是否存在并且为普通文件
-h 或 -L file :是否存在并且为符号链接文件
-p file :是否存在并且为管道文件
-s file :是否存在并且为套接字文件
# [ -b /dev/sda ]
文件权限测试:
-r file:是否存在并且可读(针对当前用户可读)
-w file:是否存在并且可写(针对当前用户可写)
-x file:是否存在并且可执行(针对当前用户可执行)
文件特殊权限测试:
-g file :是否存在并且拥有SGID权限
-u file :是否存在并且拥有SUID权限
-k file :是否存在并且拥有STICKY权限
#[ -k /usr/bin/passwd ]
#echo $?
#0
文件是否有内容:
-s file :是否有内容 (有则真,无则假)
时间戳做测试:
-o file :当前用户是否为文件的属主(owner)
-G file :当前用户是否为文件的属组
双目测试:
file1 -ef file2 :file1与file2是否为指向同一个文件系统的相同inode的硬链接
file1 -nt file2 : file1 与file2 谁更新(指修改时间(mtime)距离这一刻的时间)
file1 -nt file2 : file1 是否旧于 file2 (指修改时间(mtime)距离这一刻的时间)
组合条件测试:
逻辑运算
第一种方式:
COMMAND1 && COMMAND2
//两者必须成立才为真,否则为假
COMMAND1 || COMMAND2
//l两者其中一个成立则为真
!COMMAND
//将原有得出的结果取反,则本来命令的状态结果为0,则取反为非0。(命令为真则为假,命令为假则为真)
#[ -o file ] && [ -r file ] //文件是否为属主并可读
第二种方式:
与(&&):[experssion -a experssion ] 可使用单中扩或双中扩
或(||): [experssion -a experssion ]
非(!):!experssion
#[ -o file -a -x file ] //的当前用户是否为指定文件的属主并且拥有执行权限
练习:将当前主机名称保存至hostname变量中:
1、判断主机名如果为空,或者为localhost.localdomain,则将其设置为www.magedu.com
#hostName=$(hostname)
#[ -z "hostname" -o "$hostname" == "localhost.localdomain" -o "$hostname" == "localhost" ] && hostname=www.magedu.com
向脚本传递参数:(就是用位置参数变量实现)
位置参数变量
当运行ls命令时,后面跟上/etc/var。这就是位置参数,
那我们在程序中怎么知道对方给我们的是什么参数呢,就把代码作用在参数上呢?
比如命令ls,必须要能够获取用户从命令行传递过来的参数,并且能够让ls内部的某些代码作用在这个参数上,而像这些传递给命令的参数,这就叫做位置参数
对于shell脚本来说确实是引用位置参数的
写脚本:muscripts.sh argu1 argu2 ….. 在脚本中可以直接引用,只要用户传递了就可以在直接引用他们,引用方式就是$1、$2
$1表示引用整个脚本的位置参数当中的第一个,自动的会保存在$1中
$2表示第二个参数
$3….
例:1.希望用户从命令行随便给两个参数,能够求出两个整数之和
#vi sum.sh
#!/bin/bash
echo $[ $1+$2 ]
#bash sum.sh 2 7
#9
注意:位置参数如果比较多,一直到10或以上,则需要使用花括号“{}” 如:${10}
轮替:
shift [n] :位置参数轮替
每一次shift就能踢掉此前的对应的第一位的参数,只踢第一个,n为2则踢前两个,不能指定为哪一位,4就是前3个
特殊变量:
$0:脚本文件路径(所执行的脚本路径本身)
#vim filename.sh
#!/bin/bash
basename $0 //取文件基名(文件本身的名字)
#chmod +x filename.sh
#./filename.sh
$#脚本参数的个数
#vim filename.sh
#!/bin/bash
echo $1 $2
echo $# //显示出参数的个数
#./filename.sh hello world
#hello world
# 2
注意:即使我们不显示$1、$2等对应的参数,依然也可以使用$#来引用脚本参数的个数
$*:脚本的所有参数
把所有参数当做一个分别的子符串
$@:脚本的所有参数
把所有参数当做一个整体的子符串
$?:上一个语句的状态返回值
过程式编程语言的代码执行顺序
顺序执行:逐条运行
选择执行;代码存在一个或多个分支,只执行其中一个
代码有一个分支:条件满足时才会执行
代码有两个或以上分支:只会执行其中一个满足其条件的分支
循环执行
代码片段(循环体)要执行0、1、或多个来回
选择执行:
单分支if语句:
if 测试条件;then
代码分支 //如果测试条件成立,则执行此代码分支
fi //结束
多分支if语句:
if 测试条件;then
条件为真时执行的分支
else
条件为假时执行的分支
fi
例:通过参数传递一个用户名给脚本,此用户不存在时,则添加
#vim useradd.sh
#!/bin/bash
if [$# -lt 1];then
echo "xxxx"
exit 100
fi
if ! grep "^$1\>" /etc/passwd &> /dev/null ;then
useradd $1
echo $1 | passwd --stdin $1 $> /dev/null
echo "xxxxx" $1 finished!"
fi
#./useradd.sh user1
多分支case条件语句
case语句和if elif else 语句一样都是多分支条件语句,不过和if多分支条件语句不同的是case语句只能判断一种条件关系,而if语句可以判断多种条件语句
case $变量名 in
”值1“) //如果变量的值等于值1,则执行程序1
;;
“值2”)//如果变量的值等于值2,则执行程序2
;;
“值3” ) //如果变量的值等于值3,则执行程序3
;;
*) //如果变量的值与之前的都不匹配,则执行此语句
;;
esac //case语句结束符
case支持glob风格的通配符
* :任意长度任意字符
?:任意单个字符
[]:指定范围内的任意单个字符
a|b:a或则b
查看当前shell中的变量
set
查看当前shell中的所有环境变量
printenv
env
export
定义环境变量:
ANIMALS=pig
ANIMALS=$ANIMALS:goat
ANIMALS=$ANIMALS:sheep
echo $ANIMALS
export PATH=$PATH:/usr/local/apache/bin
export PATH=/usr/local/apache/bin:$PATH
脚本:命令的堆砌,按实际需要,结合命令流程控制机制实现的源程序
ctrl+v [ 代替033 (033为隐藏不可见字符)
脚本调试
bash -n /p/t/some_script
检测脚本中的语法错误
bash -x /p/t/some_scripts
调试执行
root
PATH目录
.bash_profile
直接定义变量
name=XXX
撤销
unset name
原创文章,作者:Lii,如若转载,请注明出处:http://www.178linux.com/34306