1.shell脚本简介
shell脚本是一种解释型语言,是shell命令的有序集合;
2.shell中的变量
shell允许用户建立变量存储数据,但不支持数据类型(整型、字符、浮点型),shell将任何赋给变量的值都解释为一串字符;
Shell有如下四种变量:
2.1 自定义变量
可以直接进行声明,赋值,不用依赖数据类型:
#!/bin/bash
COUNT=1
echo $COUNT
2.2 命令行变量
$0 与键入的命令行一样,包含脚本文件名
$1,$2,……$9 分别包含第一个到第九个命令行参数
代表执行shell脚本时,后面跟的输入参数的内容;需要注意的是,$0是脚本文件名本身,$1才是键入的第一个参数;
例如执行脚本 ./test.sh val1 val2 val3
则$1为val1,$2为val2,以此类推;
2.3 预定义变量
$# 包含命令行参数的个数
$@ 包含所有命令行参数:“$1,$2,……$9”
$? 包含前一个命令的退出状态
$* 包含所有命令行参数:“$1,$2,……$9”
$$ 包含正在执行进程的ID号
#!/bin/bash
echo "参数列表1:$*"
echo "参数列表2:$@"
echo "参数个数:$#"
echo "当前进程号:$$"
echo "命令执行结果:$?"
2.4 环境变量
常用环境变量:
HOME: /etc/passwd文件中列出的用户主目录
IFS:Internal Field Separator, 默认为空格,tab及换行符
PATH :shell搜索路径
PS1,PS2:默认提示符($)及换行提示符(>)
TERM:终端类型,常用的有vt100,ansi,vt200,xterm等
3.shell中的常用功能性语句
3.1 read语句
read从标准输入读入一行, 并赋值给后面的变量,其语法为:
read var
把读入的数据全部赋给var
read var1 var2 var3
把读入行中的第一个键入值赋给var1, 第二个单词赋给var2,以此类推;把其余所有的词赋给最后一个变量,如果执行read语句时标准输入无数据, 则程序在此停留等侯, 直到数据的到来或被终止运行。
示例
#!/bin/bash
# example1 for read
echo "Input your name: \c"
read username
echo "Your name is $username"
3.2 expr语句
算术运算命令expr主要用于进行简单的整数运算,包括加(+)、减(-)、乘(\*)、整除(/)和求模(%)等操作
#!/bin/bash
num=9
sum=`expr $num \* 6 `
echo $sum
乘(\*)需要用 ‘\’ 去掉 ’*‘ 原本的字符义;
3.3 test语句
test命令测试的条件成立时, 命令返回值为真(0值),否则返回值为假(非0值);
示例
#!/bin/bash
test $name -eq $1
echo $?
3.4 文件测试语句
-d name 测试name 是否为一个目录
-e name 测试一个文件是否存在
-f name 测试name 是否为普通文件
-L name 测试name 是否为符号链接
-r name 测试name 文件是否存在且为可读
-w name 测试name 文件是否存在且为可写
-x name 测试name 文件是否存在且为可执行
-s name 测试name 文件是否存在且其长度不为0
f1 -nt f2 测试文件f1 是否比文件f2 更新
f1 -ot f2 测试文件f1 是否比文件f2 更旧
4.shell中的分支语句
4.1 条件语句
语法结构:
if 表达式
then 命令表
fi
扩展:
if 表达式
then 命令表1
else 命令表2
fi
示例:测试命令行参数是否为已存在的文件或目录
#!/bin/bash
if [ -d $1 ]
then
echo "$1 is a directory"
#退出当前的shell程序
exit
else
if [ -f $1 ]
then
echo "$1 is a common file"
else
echo "unknown"
fi
fi
4.2 多路分支
多路分支语句case用于多重条件测试, 语法结构清晰自然. 其语法为:
case 字符串变量 in
模式1)
命令表1
;;
模式2 | 模式3)
命令表2
;;
……
模式n)
命令表n
;;
esac
示例
#!/bin/bash
# The statement of case…esac
if [ $# -eq 0 ]
then
echo "No argument is declared"
exit
fi
case $1 in
file1)
echo "User selects file1"
;;
file2)
echo "User selects file2"
;;
*)
echo "You must select either file1 or file2!"
;;
esac
注:
1)case语句只能检测字符串变量
2)各模式中可用文件名元字符,以右括号结束
3)一次可以匹配多个模式用“|”分开
4)命令表以单独的双分号行结束,退出case语句
5)模式 n常写为字符* 表示所有其它模式
6)最后一个双分号行可以省略
5.shell中的循环语句
5.1 循环语句for
格式为:
for 变量名 in 单词表
do
命令表
done
示例:拷贝当前目录下的所有文件到backup子目录下
#!/bin/bash
# The statement of for…do…done
if [ ! -d $HOME/backup ]
then
mkdir $HOME/backup
fi
flist=`ls`
for file in $flist
do
if [ $# = 1 ]
then
if [ $1 = $file ]
then
echo "$file found" ; exit
fi
else
cp $file $HOME/backup
echo "$file copied"
fi
done
echo ***Backup Completed***
5.2 循环语句while
结构为:
while 命令或表达式
do
命令表
done
示例:批量生成空白文件
#!/bin/bash
# The statement for while
if [ $# = 2 ]
then
#根据命令行的第二个参数来确定循环的次数
loop=$2
else
loop=5
fi
i=1
while [ $i -lt $loop ]
do
#建立以第一个参数指定的文件名前缀,例如以“file”开头, 变量i的值结尾的空文件名
> $1$i
i=`expr $i + 1`
done
6.shell中的函数
函数调用格式:
方式1:
value_name=`function_name [arg1 arg2 … ]`
函数的所有标准输出都传递给了主程序的变量
方式2:
function_name [arg1 arg2 … ]
echo $?
获取函数的返回的状态
示例:根据用户名查找用户
#!/bin/bash
#查找已登录的指定用户
check_user( )
{
user=`who | grep $1 | wc -l`
if [ $user –eq 0 ]
then
#未找到指定用户
return 0
else
#找到指定用户
return 1
fi
}
while true
do
echo "Input username: \c"
read uname
# 调用函数, 并传递参数uname
check_user $uname
# $?为函数返回值
if [ $? –eq 1 ]
then
echo "user $uname online"
else
echo "user $uname offline"
fi
done
7.应用示例
应用1 实现1到8的累加
#!/bin/bash
#实现1到8的累加
sum=0
for i in 1 2 3 4 5 6 7 8
do
sum=`expr $sum + $i`
done
echo "add 1 to 8, the result is : $sum"
应用2 根据键入成绩区分成绩等级
#!/bin/bash
read -p "please input score: " Score
if [ $Score -lt 0 -o $Score -gt 100 ]
then
echo "invalid input!"
exit
fi
temp=`expr $Score / 10`
case $temp in
9|10)
echo "rank A"
;;
8)
echo "rank B"
;;
*)
echo "rank C"
esac
应用3 将当前路径下的普通文件归档到hello.tar
#!/bin/bash
flist=`ls`
for file in $flist
do
if [ -f $file ]
then
tarlist="$tarlist $file"
fi
done
tar -cvf hello.tar $tarlist
应用4 用户输入一个用户名,查询系统中是否存在该用户,若有打印用户存在,若不存在添加该用户
#!/bin/bash
check_user() {
user=`cat /etc/passwd | cut -f1 -d':' | grep -w "$1" -c`
if [ $user -eq 0 ]
then
return 0
else
return 1
fi
}
echo "Input username:"
read username
check_user $username
if [ $? -eq 1 ]
then
echo "user $username online"
else
useradd $username
echo "useruser $username added "
fi