一.【shebang】
二.【变量】
三.【逻辑运算】
四. 数值、字符串、文件测试、组合测试
五.【read命令】
【前言】
脚本文件需要拥有执行权限,不然它只是一个普通文件。
一.【shebang】
首先,创建文件:vim filename
,在文件的开头写一个命令:
这一行命令有一个统称,叫做”! shebang“ :
由上可知,”shebang“写在Unix系统的脚本第一行,指明了执行这个脚本文件的解释程序。如果我们没有指定shebang或者系统中没有所指定的shebang时,会出现以下情况:
- 如果脚本文件中没有#!这一行,那么它执行时会用默认Shell去解释这个脚本(即:$SHELL环境变量)。
- 如果#!指定的解释程序不是一个可执行文件,那么指定的解释程序会被忽略,转而交给当前默认的SHELL去执行这个脚本。
- 如果#!之后的解释程序是一个可执行文件,那么执行这个脚本时,它就会把文件名及其参数一起作为参数传给那个解释程序去执行。
- 如果#!指定的解释程序没有可执行权限,则会报错“bad interpreter: Permission denied”。
- 如果#!指定的解释程序不存在,那么会报错“bad interpreter: No such file or directory”。注意:#!之后的解释程序,需要写其绝对路径(如:#!/bin/bash),它是不会自动到$PATH中寻找解释器的。
- 当然,如果使用”bash test.sh ”这样的命令来执行脚本,那么#!这一行将会被忽略掉,解释器当然是用命令行中显式指定的bash。
er 二.【变量】
在Linux中变量定义规则:
1、不能使程序中的保留字:例如if, for
2、只能使用数字、字母及下划线,且不能以数字开头
3、见名知义
4、统一命名规则:驼峰命名法
我们通过一个例子来简单说明一个变量:
在bash中将变量分为几类:本地变量、环境变量、局部变量、位置变量、特殊变量。
在shell中,进程有父进程和子进程,如何开一个子进程如下:
本地变量:定义了一个变量,这个变量只在shell下显示,在子进程里不显示值。
环境变量:在变量前加export
,该变量可以在子shell下显示值。生效范围--当前shell进程及其子进程。
位置变量:$1, $2, …来表示,用于让脚本在脚本代码中调用通过命令行传递的参数。
参数 | 注释 |
---|---|
$1, $2, … | 对应第1、第2等参数,shift [n]换位置 |
$0 | 命令本身 |
$* | 传递给脚本的所有参数,全部参数合为一个字符串 |
$@ | 传递给脚本的所有参数,每个参数为独立字符串 |
$# | 传递给脚本的参数的个数(不包含$0) |
$@ $* | 只在被双引号包起来的时候才会有差异 不被双引号(" ")包含时,都以"$1" "$2" … "$n" 的形式输出所有参数。 被双引号(" ")包含时,"$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数; "$@" 会将各个参数分开,以"$1" "$2" … "$n" 的形式输出所有参数。 |
set – | 清空所有位置变量 |
特殊变量
参数 | 注释 |
---|---|
$0 | 命令本身 |
$? | 上个命令的退出状态(或函数的返回值) |
$$ | 当前shell进程ID |
$_ | 查看上一个命令的最后一个变量。 |
变量不仅可以赋值,还可以引用;
[root@localhost ~]# C1="root" 直接字符串引用
[root@localhost ~]# echo $C1
root
[root@localhost ~]# C1="$USER" 引用一个变量
[root@localhost ~]# echo $C1
root
[root@localhost ~]# C1=`ls /app/` 引用一个命令的执行结果,注意引用符号 这里应该用双引号吧??
[root@localhost ~]# echo $C1
bao.tar ceshi f1 file1 FILE1 fstab passwd profile.sh test.sh wan
单引号: 所见即所得:即将单引号内的内容原样输出,或者描述为单引号里面看见的是什么就会输出什么。
双引号: 把双引号内的内容输出出来;如果内容中有命令,变量等,会先把变量,命令解析出结果,然后在输出最终内容来。
双引号内命令或变量的写法为`命令或变量`或$(命令或变量)。
无引号:
如果内容中有命令,变量等,会先把变量,命令解析结果,然后在输出最终内容来。
如果字符串中带有空格等特殊字符,则视为一个整体,不能完整输出,需要改加双引号。
一般连续的字符串,数字,路径等可以用,不过最好用双引号替代之
练习一:编写脚本/root/bin/backup.sh,可实现每日将/etc/目录备份到/root/etcYYYY-mm-dd中。
[root@localhost bin]# vim /root/bin/backup.sh #!/bin/bash 首行写"shebang" # ------------------------------------------ # Filename: backup.sh # Revision: 1.1 # Date: 2017/06/01 其余以#开头的行为注释行,为了使自己也使别人 # Author:wanwanperfect 更加快速的了解脚本的内容 # Description: # ------------------------------------------ cp -a /etc /root/etc$(date +%F) 脚本需求 [root@localhost bin]# chmod u+x backup.sh 给脚本加上执行权限 [root@localhost bin]# ./backup.sh 执行这个脚本 [root@localhost bin]# cd /root/ [root@localhost ~]# ls a.log bin Desktop Downloads file.grep motd new.file Public
Videos anaconda-ks.cfg b.log Documents etc2017-08-10 initial-setup-ks.cfg
Music Pictures Templates 创建成功
shell中变量没有类型:根据表达式自动改变其类型!
表达式不能计算结果:变成了字符串的拼接!
算数运算:可以计算结果
在bash中,定义一个变量的值也可以使用算数运算,主要有以下几种方式:
(1) let var=算术表达式
(2) var=$[算术表达式]
(3) var=$((算术表达式))
(4) var=$(expr arg1 arg2 arg3 …) 乘法时要转译* ,即*
(5) declare –i var = 数值
(6) echo ‘算术表达式’ | bc (丢给计算机进行处理)
[root@localhost ~]# let a=2+3
[root@localhost ~]# echo $a
5
[root@localhost ~]# b=$[20*12]
[root@localhost ~]# echo $b
240
[root@localhost ~]# c=$((3+3))
[root@localhost ~]# echo $c
6
[root@localhost ~]# d=$(expr 4 \* 5 + 3)
[root@localhost ~]# echo $d
23
[root@localhost ~]# declare -i n=8
[root@localhost ~]# echo $n
8
[root@localhost ~]# echo 4*4 |bc
16
- 另外除了一些算数运算,变量还有自增赋值和自减赋值:
let var+=1 <表示自加1 后赋值>
let var++
let var-=1 <表示自减1 后赋值>
let var–
联系shell脚本2. 编写脚本/root/bin/sumspace.sh,传递两个文件路径作为参数给脚本,计算这两个文件中所有空白行之和
#!/bin/bash
#------------------------------------------------------
#Filename:sumspace47.sh
#Revision:
#Date:2017-08-02
#Author:wanwanperfect
#------------------------------------------------------
file1=$(cat $1 |grep -o "^[[:space:]]*$"|wc -l) 定义$1、$2作为参数 [:space:] 空白字符,包括空格,tab [空格 tab]
file2=$(cat $2|grep -o "^[[:space:]]*$"|wc -l) grep -o 只显示匹配的部分。wc -l统计内容行数
echo "空行之和为:"$[file1+file2]"" 使用算数运算来达到目的
unset file1 file2 别忘记使用unset命令来释放变量,不然会占取你的内存呦~
shell中$(( ))、$( )、``与${ }的区别
https://blog.csdn.net/jiaxiaokai/article/details/80870269
三.【逻辑运算】
在逻辑运算中,我们只定义两个值,即 true 和 false ,分别用 1 和 0 表示。
逻辑运算分为三种:
与:只要有一个假则为假 1 与 1 = 1 1 与 0 = 0 0 与 1 = 0 0 与 0 = 0
或:只要有一个真则为真 1 或 1 = 1 1 或 0 = 1 0 或 1 = 1 0 或 0 = 0
非:! ! 1 = 0 ! 0 = 1
短路与:前一个为假,则不再判断第二个值。 用 && 表示
短路或:前一个为真,则不再判断第二个值。 用 || 表示。
异或:异或的两个值,相同为假,不同为真 。 用 ^ 表示。
前两个符号我们常用于脚本中来判断一些条件的成立与否。
【 】~~~~~~~~~~
[root@localhost bin]# id root &> /dev/null && echo "user is exist" || echo "user is not exist"
user is exist 当返回结果为真时则执行&& 后的命令
[root@localhost bin]# id xiaoqiang &> /dev/null && echo "user is exist" || echo "user is not exist"
user is not exist 当返回结果为假时则执行||后的命令
【test命令】
test命令用来检测两个字符或者比较两个值的大小来返回&& 或者||的值。
其实,test 命令可以用 ”[“ 来表示,”[“命令还有一个参数为”]“ 。注意:它们一个是命令,一个是该命令的参数,并不是合体的~~ ”[ ]“ 表示将参数放入其中进行比较,与test 命令用法相同。例如:
[root@localhost bin]# a=aaa
[root@localhost bin]# b=aa
[root@localhost bin]# test "$a" == "$b" && echo true || echo false
false
[root@localhost bin]# [ "$a" == "$b" ] && echo true || echo false
false
【注意】在使用”[]” 左右大括号旁边必须有空格间隔。
四. 数值、字符串、文件测试、组合测试
数值测试:
参数 | 注释 |
---|---|
-gt | 是否大于 |
-ge | 是否大于等于 |
-eq | 是否等于 |
-ne | 是否不等于 |
-lt | 是否小于 |
-le | 是否小于等 |
字符串测试:
参数 | 注释 |
---|---|
== | 是否等于 |
> | ASCII码是否大于ASCII码 |
< | 是否小于 |
!= | 是否不等于 |
=~ | 左侧字符串是否能够被右侧所匹配【此表达式一般用于[[ ]]中;支持扩展的正则表达式】 |
-z | 字符串是否为空,空为真,不空为假 |
-n | 字符串是否不空,不空为真,空为假 |
文件测试:
参数 | 注释 |
---|---|
-a FILE | 文件存在性测试,存在为真,否则为假 |
-e FILE | 同-a |
-b FILE | 判断文件为块设备文件时为真 |
-c FILE | 判断文件为字符设备文件时为真 |
-d FILE | 判断文件为目录文件时为真 |
-f FILE | 判断文件为普通文件时为真 |
-h FILE 或 -L FILE | 判断文件为符号链接文件时为真 |
-p FILE | 判断文件为命名管道文件时为真 |
-S FILE | 判断文件为套接字文件时为真 |
-r FILE | 判断文件存在且可读时为真 |
-w FILE | 判断文件存在且可写时为真 |
-x FILE | 判断文件存在且可执行权限时为真 |
-u FILE | 判断文件且拥有suid权限时为真 |
-g FILE | 判断文件存在且拥有sgid权限时为真 |
-k FILE | 判断文件且拥有sticky权限时为真 |
-s FILE | 是否存在且非空时为真 |
-t fd | fd表示文件描述符是否已经打开且与某终端相关 |
-N FILE | 文件自动上一次被读取之后是否被修改过 |
-O FILE | 当前有效用户是否为文件属主 |
-G FILE | 当前有效用户是否为文件属组 |
【】~~~~~~~~~
[root@localhost bin]# b1=34
[root@localhost bin]# b2=12
[root@localhost bin]# [ $b1 -gt $b2 ] && echo true || echo false
true
[root@localhost bin]# [ $b1 -lt $b2 ] && echo true || echo false
false
[root@localhost bin]# [ $b1 -eq $b2 ] && echo true || echo false
false
练习:
编写脚本/root/bin/checkdisk.sh,检查磁盘分区空间和inode使用率,如果超过80%,就发广播警告空间将满
#!/bin/bash
var1=`df|egrep -o "[[:digit:]]{1,3}\b%"|cut -d '%' -f1|sort -nr|head -1`
var2=`df -i|egrep -o "[[:digit:]]{1,3}\b%"|cut -d '%' -f1|sort -nr|head -1`
[ $var1 -gt 80 ]&& wall warn:空间将满 ||wall 空间使用率不足80%
[ $var2 -gt 80 ]&& wall warn:inode空间将满 ||wall indoe空间使用率不足80%
unset var1 var2
【解题】将磁盘利用率和inode使用率的数字提取出来再与 80 进行比较就好了。
【bash 的组合测试条件】
(1)
命令1 && 命令2 表示并且
命令1 || 命令2 表示或者
! command 表示非
如:[[ -r file ]] && [[ -w file ]]
(2)
EXPRESSION1 -a EXPRESSION2 并且
EXPRESSION1 -o EXPRESSION2 或者
! EXPRESSION
必须使用测试命令进行
eg:[ -f /bin/cat -a -x /bin/cat ] && cat /etc/fstab
练练手:
编写脚本/root/bin/excute.sh ,判断参数文件是否为sh后缀的普通文件,如果是,添加所有人可执行权限,否则提示用户非脚本文件;
#!/bin/bash
#------------------------------------------------------
#Filename:excute.sh
#Author:wan
#Date:2017-08-04
#Description:判断文件是否为脚本文件
#-----------------------------------------------------
[ -f $1 ] && \
(varsh=`basename $1 |grep -o "\..*$"`
[[ "$varsh" == .sh ]] && [[ -f $1 ]] && (chmod u+x $1 && echo 该文件为脚本文件并且已添加可执行权限) || echo "该文件非脚本文件" )|| echo "该文件不存在"
unset varsh
【解题】首先判断这个文件是不是以 .sh
结尾的文件,然后判断是不是一个普通文件。
这两个条件都满足时,判断这个文件是否存在,存在则给这个文件加上执行权限并输出正确结果,不满足其上任何一个条件则返回一个错误结果。
五.【read命令】
与用户交互,提示用户需要输入的内容。把输入值分配给一个或多个shell变量。参数如下:
参数 | 注释 |
---|---|
-p | 指定要显示的提示 |
-s | 静默输入,一般用于密码 |
-n # | 指定输入的字符长度最大值# |
-d ‘字符’ | 输入结束符,当你输入的内容出现这个字符时,立即结束输入 |
-t N | 超出N秒没有进行输入,则自动退出。 |
【Ps】read 从标准输入中读取值,给每个单词分配一个变量,其余剩余的单词都被分配给最后一个变量。
[root@localhost ~]# read -p "请输入用户名 :" username && echo "您的用户名为$username"
请输入用户名 :tom
您的用户名为 tom
[root@localhost ~]# read -sp "请输入密码 :" passwd && echo "您的密码为:$passwd "
请输入密码 :您的密码为:123456