shell脚本基础及编程练习

shell基础语法

变量
变量定义:命名的内存空间,变量指向内存空间,引用的时候直接调用变量而不需考虑具体的内存空间,系统中echo $可以列出很多变量,引用的时候加$。重新定义变量时,变量名称不变,变量的指针发生变化,重新指向新的内存空间,原来的内存空间会被系统收回。

变量类型:
1、字符
2、数值
变量作用:
1、数据存储格式
2、参与的运算
3、表示的数据范围
变量命名法则:
1、不能使用程序中的保留字:例如if, for,内部外部命令
使用type显示if is a shell keyword(关键字)
2、只能使用数字、字母及下划线,且不能以数字开头
n1可以,1n就不行
3、见名知义
看见名字就能知道含义。
4、统一命名规则:驼峰命名法
首字母大写,单词两个以上,首字母都大写
bash中变量的种类
根据变量的生效范围等标准划分下面变量类型:
局部变量(普通变量):
生效范围为当前shell进程;对当前shell之外的其它shell进程,包括当前shell的子shell进程均无效,上级shell进程变量影响不了下级,下级shell进程变量影响不了上级。
定义变量: [set]Var_Name=”Value”
引用变量: ${Var_Name}
删除变量: unset Var_Name
环境(全局)变量:
生效范围为当前shell进程及其子进程,允许上级向下级传,下级可以临时更改,更改不能上传到父进程
定义方法:
1.直接定义 export name=VALUE,declare -x name=VALUE
2.间接定义,先定义局部变量,然后再定义全局变量。
引用变量: ${name}
删除变量:unset name
bash内建的环境变量:
PATH 命令的存放路径
SHELL 系统的默认shell
USER 当前的用户
UID root的uid
HOME 用户家目录
PWD 当前工作目录
SHLVL bash嵌套深度
LANG 语系
MAIL 用户的邮箱目录
HOSTNAME 主机名
HISTSIZE 历史命令的最大存放数
— 上一个命令的最后的参数
只读和位置变量
只读变量:只能声明,但不能修改和删除(程序结束变量也就结束,exit)
声明只读变量:
readonly name
declare -r name(readonly -p) 显示系统中的常量
查看只读变量:
readonly –p
位置变量:在脚本代码中调用通过命令行传递给脚本的参数,通过输入的参数,实现更为强大的功能。
$1, $2, …:对应第1、第2等参数,shift [n]换位置。
$0: 命令本身。
$*: 传递给脚本的所有参数,全部参数合为一个字符串
$@: 传递给脚本的所有参数,每个参数为独立字符串
$#: 传递给脚本的参数的个数
$@ $* 只在被双引号包起来的时候才会有差异
set — 清空所有位置变量
例如:backup.sh a b c $1为a,$2为b,$3为c,$*为a b c,$#为3,$0为 backup.sh(默认带路径)
示例:复制本机的文件到远程主机可以用位置参数实现
scp $* wang@172.20.102.77:/home/wang/bin
格式:scp 要发送的文件 登陆远程主机的身份@远程主机的IP:要发送到的目录
写个脚本scp.sh:
#!/bin/bash
echo “copy will be start”
scp $* wang@172.20.102.77:/home/wang/bin
echo “copy is finished”
以后复制文件时直接./scp.sh f1…即可
退出状态
进程使用退出状态来报告成功或失败
0 代表成功,1-255代表失败
$? 变量保存最近的命令退出状态
bash自定义退出状态码
exit [n]:自定义退出状态码 将状态码传到$?
注意:脚本中一旦遇到exit命令,脚本会立即终止;终止退出状态取决于exit命令后面的数字
注意:如果未给脚本指定退出状态码,整个脚本的退出状态码取决于脚本中执行的最后一条命令的状态码
运行脚本时,实际上是在当前shell中创建了子shell。在父进程中创建的局部变量在脚本中无效。让其有效要定义成全局变量export

算术运算
bash中的算术运算:help let
+, -, *, /, %取模(取余), **(乘方)
实现算术运算:
(1) let var=算术表达式 例如:x=10;y=20;let z=x+y(加上$也行);echo $z 输出30
(2) var=$[算术表达式] 例如:m=2;n=3;sum=$[m+n]或者sum=$[$m+$n];echo $sum 输出5
(3) var=$((算术表达式)) 例如:m=2;n=3;sum=$((m+n))或者sum=$(($m+$n));echo $sum 输出5
(4) var=$(expr arg1 arg2 arg3 …) 例如:sum=$(expr 1 + 3);echo $sum 输出4
(5) declare –i var = 数值 例如:declare -i x=10;declare -i y=20;declare -i z=x+y;echo $z 输出为30
(6) echo ‘算术表达式’ | bc
取模:let result=100%或者result=$[100%3];echo $result 输出为1
例子:使文字带随机的颜色
COLOR=$[RANDOM%7+31];echo -e “\e[1;${COLOR}mcolor\e[0m”
COLOR=$((RANDOM%7+31));echo -e “\e[1;${COLOR}mcolor\e[0m”
乘法符号有些场景中需要转义,如*
bash有内建的随机数生成器:$RANDOM(0-32767)
echo $[$RANDOM%50] :0-49之间随机数
expr为命令可以直接进行加减乘除运算,需注意空格例如expr 1 + 2 expr 3 \* 2(需要转义) expr 3 / 2(只能取整,没有余数)
算数运算练习
1、编写脚本/root/bin/sumid.sh,计算/etc/passwd文件中的第10个用户和第20用户的ID之和
#!/bin/bash
ct1=”/etc/passwd”
ct2=”tail -n1″
ct3=”cut -d “:” -f3″
number1=head -n$1 ${ct1}|${ct2}|${ct3}
number2=head -n$2 ${ct1}|${ct2}|${ct3}
sum=$[number1+number2]
echo “the sum is ${sum}!”
2、编写脚本/root/bin/sumspace.sh,传递两个文件路径作为参数给脚本,计算这两个文件中所有空白行之和
#!/bin/bash
number1=grep -c "^$" $1
number2=grep -c "^$" $2
sum=$[number1+number2]
echo “the sumspace is ${sum}!”
3、编写脚本/root/bin/sumfile.sh,统计/etc, /var, /usr目录中共有多少个一级子目录和文件
sumfile=tree -L 1 $1|wc -l
echo “the $1 sumfile is ${sumfile}!”
shift
sumfile1=tree -L 1 $1|wc -l
echo “the $1 sumfile is ${sumfile1}!”
shift
sumfile2=tree -L 1 $1|wc -l
echo “the $1 sumfile is ${sumfile2}!”

条件测试
判断某需求是否满足,需要由测试机制来实现
专用的测试表达式需要由测试命令辅助完成测试过程
评估布尔声明,以便用在条件性执行中
若真,则返回0
若假,则返回1
测试命令格式:
test EXPRESSION
[ EXPRESSION ]
[[ EXPRESSION ]]
注意:EXPRESSION前后必须有空白字符
字符串运算
判断字符串长度
-z STRING(为空返回为真)
例如:str1=xxx;[ -z $str1 ];echo $?=1
str1=;[ -z $str1 ];echo $?=0
-n STRING(不为空返回为零,-n可忽略不写)
例如:str1=xyz;[ $str1 ];echo $?=0
str1=;[ $str1 ];echo $?=1
判断字符串相等
STRING1 = STRING2(字符串相等,相等返回为真)
例如:
str1=aaa;str2=bbb;[ $str1 = $str2 ];echo $?=1
str1=aaa;str2=aaa;[ $str1 = $str2 ];echo $?=0
STRING1 != STRING2(字符串不等,不等返回为真)
例如:
str1=aaa;str2=bbb;[ $str1 = $str2 ];echo $?=0
str1=aaa;str2=aaa;[ $str1 = $str2 ];echo $?=1
字符判断练习:
x=haha;y=xixi;[ $x = $y ] && echo equal || echo no equal
判断字符串是否相等,相等打印equal,不相等打印no equal,此处不相等
m=10;n=20;[ $m -eq $n ] && echo equal || echo no equal
判断数字是否相等,相等打印equal,不相等打印no equal,此处不相等
test还可以进行数字比较,常用的选项是-eq(相等), -ne(不等),-lt(小于), -le(小于等于), -gt(大于), -ge(大于等于)

test文件判断
-a FILE True if file exists.(文件是否存在)
-b FILE True if file is block special.(是块文件)
-c FILE True if file is character special.(是字符文件)
-d FILE True if file is a directory.(是目录)(如果判断的是目录的链接文件,判断的是连接到的目录,而非连接文件本身,例如[ -d /bin/ ])
-e FILE True if file exists.(是否存在)
-f FILE True if file exists and is a regular file.(存在且是普通文件)
-h FILE True if file is a symbolic link.(测试文件是否为符号连接文件)
-p FILE True if file is a named pipe.(是否为管道文件)
-r FILE True if file is readable by you.(是否可读,测试执行者的权限)
-s FILE True if file exists and is not empty.(是否存在且不空)
-w FILE True if the file is writable by you.(看的是实际权限,而非ls -l显示的权限,执行者的权限)
-x FILE True if the file is executable by you.(是否可执行,执行者的权限)
练习
1、创建账户并给与密码,当用户存在时,退出并显示此目录已存在,不存在时创建用户,并给与初始密码
#!/bin/bash
id $1 &>/dev/null
[ $? -eq 0 ] && echo “the user is exist” && exit
[ $? -ne 0 ] && useradd $1 && echo “magedu”|passwd –stdin $1
echo “$1 user is created”
2、编写脚本/root/bin/argsnum.sh,接受一个文件路径作为参数;如果参数个数小于1,则提示用户“至少应该给一个参数”,并立即退出;如果参数个数不小于1,则显示第一个参数所指向的文件中的空白行数
#!/bin/bash
[ $# -lt 1 ] && echo “you must be input 1 arg” && exit
[ $# -ge 1 ] && echo “the file space line is grep -c "^$" $1
3、编写脚本/root/bin/hostping.sh,接受一个主机的IPv4地址做为参数,测试是否可连通。如果能ping通,则提示用户“该IP地址可访问”;如果不可ping通,则提示用户“该IP地址不可访问”
#!/bin/bash
ping -c1 $1 > /dev/null && echo “the ip can access” || echo “the ip not to access”
4、编写脚本/root/bin/checkdisk.sh,检查磁盘分区空间和inode使用率,如果超过80%,就发广播警告空间将满
#!/bin/bash
a=”df|grep "sd"|tr -s " " "%"|cut -d "%" -f5|sort -nr|head -n1
[ $a -ge 80 ] && echo “The disk will be full”
5、编写脚本/bin/per.sh,判断当前用户对指定参数文件,是否不可读并且不可写
#!/bin/bash
[ -r $1 -a -w $1 ] && echo “the user can read and write” || echo “the user not read and write”
6、编写脚本/root/bin/excute.sh ,判断参数文件是否为sh后缀的普通文件,如果是,添加所有人可执行权限,否则提示用户非脚本文件
#!/bin/bash
[ -f $1 ] && [[ $1 =~ .+\.sh$ ]] && chmod +x $1 || echo “the file is not script”
7、编写脚本/root/bin/nologin.sh和login.sh,实现禁止和充许普通用户登录系统
#!/bin/bash
[ -a /etc/noloin ] && echo “the file is exist” || touch /etc/nologin
[ -a /etc/nologin ] && rm -f /etc/nologin || echo “you can access”

使用read命令来接受输入
read本身的命令是用来给变量赋值
使用read来把输入值分配给一个或多个shell变量
-p 指定要显示的提示 read -p “please input your name: ” name;echo “your name is $name”
-s 静默输入,一般用于密码 read -s -p “please input your name: ” passwd (可以隐藏)
-n N 指定输入的字符长度N
-d ‘字符’ 输入结束符
-t N TIMEOUT为N秒
read 从标准输入中读取值,给每个单词分配一个变量
所有剩余单词都被分配给最后一个变量
read -p “Enter a filename: “ FILE

本文来自投稿,不代表Linux运维部落立场,如若转载,请注明出处:http://www.178linux.com/96092

联系我们

400-080-6560

在线咨询

工作时间:周一至周五,9:30-18:30,节假日同时也值班

QR code