一、Bash脚本编程风格 二、Bash条件测试: 三、脚本的状态返回值 四、练习脚本: 五、if 语句
一、Bash脚本编程风格
脚本格式:
#!/bin/bash
#description: say hello
#version 0.0.1 //注释信息
#author:xiaoming //代码注释
#date:2017-01-01
缩进:适度添加空白行;
语法:编程语法格式、库调用(类库)、算法、数据结构
编程思想:
问题空间-->解空间
变量:
局部变量:当前shell
本地变量:local,函数内部
环境变量:当前shell及其子进程
位置参数变量:$1,$2,$3
特殊变量:$#,[email protected]
变量的数据类型://弱类型,默认都为字符型
字符型
数值型
算数运算:+,-,*,/,%,**
expr,let
let VAR=expression
$((expression))
$[expression]
var=$(expr argu1 + argu2) //一个小括号,命令引用
注意:有些时候,乘法符号需要转义
animal=dog;echo "${animal}s" //用花括号分开即可
PATH=“$PATH:/usr/locale/apache/bin" //引用原有的值,然后重新赋值
增强型赋值:变量做某种算术运算后回至此变量中
declare -i a=1 //
i=$[$i+1]
let i+=2 //这样也可以的:增强型复制机制
let +=,-=,*=,/=,%= //一般使用let进行
let ++,-- //自己加上/减去 1
let var=$[$var+1]
let var+=1
let var++
脚本1:添加user1
#!/bin/bash
# first_scrpit
id user1 &> /dev/null || useradd user1
id user2 &> /dev/null || useradd user2
user_id1=$(id -u user1)
user_id2=$(id -u user2)
id_sum=$[$user_id1+$user_id2]
echo "sum is :$id_sum"
练习:
1.写一个脚本,计算/etc/passwd文件中第10个用户和第20个用户的id号之和
2.计算/etc/rc.d/init.d/functions和/etc/inittba文件的空白行数之和
1.
id1=$(head -10 /etc/passwd | tail -1 | cut -d: -f3}
id2=$(head -20 /etc/passwd | tail -1 | cut -d: -f3}
2.
b1=$(grep "^$" /etc/rc.d/init.d/functions | wc -l)
b1=$(grep "^[[:space:]]*$" /etc/rc.d/init.d/functions | wc -l)
二、Bash条件测试:
判断某需求是否满足,需要测试机制来实现
||,&&,! //或,非,与
测试方法:
1.执行命令,并利用命令状态返回值来判断
0:成功
1-255:失败
echo $?
2.测试表达式
test -[d,e,f,h,p,r,s,S,w,N] a.txt
d目录,f普通文件,e存在,h|-L符号文件,
r可读,w可写,-s非空,-S套接字,-N上次读取之后修改过
[ expression ]
[[ expression ]]
注意:expression两端必须有空格,否则为语法错误
bash测试类型:
数值测试
字符串测试
文件测试
1.数值测试:数值比较
-eq,-gt,-lt
-ge,-le,-ne
test 3 -gt 4 && echo True || echo false
2.字符串测试:根据ascii表,尽可能定义在[[ ]]中
== 是否相当
>
《
!= 是否不等于
=- :左侧的字符串是否能够被右侧的pattern匹配
name=tom; [[ "$name" =~ t ]] ;echo $? //tom是否包含 t字母
//单目
-z “STRING” 判断子串是否为空,空则为真,否则为假
-n “STRING” 是否不空
[ -n "$name" ];echo $?
注意:[[ “a” > “b” ]] ;echo $?
//一定要使用两个中括号,否则会出错
(1)字符串要加引用
(2)要使用[[ ]]
3.文件测试
d目录,-S套接字,-p 管道文件
f普通文件,
a|e存在,
h|-L符号文件,
-b 块设备文件
-s非空,
-N上次读取之后修改过 //上次读取后,是否被修改过
4.文件权限测试:
r可读,是否存在且对当前用户可读
w可写,
x可执行
-g 是否存在,并且拥有sgid权限
-u 是否存在,并且拥有suid权限
-k sticky权限
[ -u /bin/passwd ] ; echo $?
5.从属关系测试
-O FILE 当前用户是否为文件的属主
-G FILE 当前用户是否为屋内安的属组
6.双目运算
FILE1 -ef FILE2 //file1与file2是否指向同一个fs的相同inode
file1 -nt filr2 //file1是否新于file2
file1 -ot file2 //file1是否旧于file2
7.组合测试:
逻辑运算:
第一种方式:
a && b
a || b
! a //取反
[ -O file ] && [ -r file ] //当前用户为属主并且可读
[ -O file -a -x file ]
expression -a expression2 //
expression -o expression2
! expression
test "a" != "$HOME" -a 3 -ge 4 ; echo $?
[ ! \( "a" = "$HOME" -o 3 -lt 4 \) ]; echo $?
[ ! \( "a" = "$HOME" -o ‘(‘ 3 -lt 4 ‘)‘ ")" ]; echo $?
三、脚本的状态返回值
默认是脚本中执行的最后一条命令的状态返回值
自定义状态返回值
exit [n] //自定义状态返回值,状态码
注意:shell进程遇到exit会终止,因此整个脚本将会结束
一般判断条件是否满足,再执行exit
注意:XShell的锁定和接触锁定
vim
ctrl + s 锁定后,
ctrl + q 取消锁定
四、练习脚本:
脚本1:
将当前主机名称保存至hostName变量中:
主机名为空,或者为localhost.localdomain,则将其设置为www.mt.com
#!/bin/bash
hostName=$(hostname)
[ -z "$hostName" -o "$hostName"=="localhost.localdomain" -o hostName=="localhost" ] && hostname www.xt.com
注意:
//必须是 [] ,而不能是 [[ ]] ,或者
//== 前后不需要空格
// [ ] 前后都需要空格,
//$hostname 得需要“ ”
//[ ** -o|-a| ** ] 判断内部 // && || ! 判断[]外部
脚本2.向脚本传递参数
位置参数变量;
引用:
$1,$2,...$(12)
shift 轮替
shift n :位置参数变量
特殊变量:
$0:脚本文件名
$#: 获取参数个数总和
$*: 所有参数
[email protected]: 所有参数
引用变量计算数值
bash sum.sh 23 78
#!/bin/bash
#
echo $[$1 + $2]
//判断文件空白行行数
#!/bin/bash
[ $# -lt 2 ] && echo "At least two files" && exit 1
b1=$(grep "^$" $1 | wc -l)
b2=$(grep "^$" $2 | wc -l)
echo "sum of blank is : $[b1+b2]"
五、if 语句
过程式编程语言的代码执行顺序
顺序执行:逐条执行
选择执行:
代码有一个分支:条件满足则执行
两个以上的分支:只会执行其中一个满足条件的执行
循环执行:
代码片段(循环体)要执行0,1或多个来回
选择执行:
if 测试条件 ; then //需要分号
代码分支
fi
if 测试条件 //then单独分行,不需要分号
then
代码分支
fi
双分支if语句
if 测试条件; then
条件为真时运行
else
条件为假时执行
fi
脚本3:通过参数传递一个用户名给脚本,此用户不存在时添加该用户
#!/bin/bash
if [ $# -lt 1 ]; then
echo "At least one user_name"
exit 1
fi
if ! [ grep "$1\>" /etc/passwd ] &> /dev/null; then
useradd $1
echo $1 | passwd --stdin $1
echo "USER $1 added succeed!"
exit 0
else
echo "Failure ..."
exit1
fi
脚本4:通过键盘给定两个数字,输出其中较大的值
#!/bin/bash
#
if [ $# -lt 2 ] ; then
echo "Two intergers."
exit 2
fi
if [ $1 -ge $2 ] ;then
echo "max number is: $1"
else
echo "max number is: $2"
fi
脚本5:通过命令参数传递给定两个文件名,如果某文件不存在,则结束脚本
返回每个文件的行数,并说明其中行数最多的文件
[[email protected] test]# cat 2.sh
#!/bin/bash
#AUthor xt
#date 2017-07-22
declare -i f1 f2
if [ $# -lt 2 ] ; then echo "At least two files " exit 1 ; fi
#if [ ! -f $1 ] || [ ! -f $2 ] ; then
if ! [ -f $1 -a -f $2 ] ; then
echo "At least one is not a primary file" exit 2 ;
else
f1=$(wc -l $1 | cut -d‘ ‘ -f1)
f2=$(wc -l $2 | cut -d‘ ‘ -f1)
if [ $f1 -gt $f2 ] ;then
max=$f1
else
max=$f2
fi
echo "First file‘s line is $f1"
echo "Second file‘s line is $f2"
echo "Max is line is $max"
fi