1.什么是Shell脚本
Shell脚本是利用 shell 的功能所写的一个程序 program,这个程序是使用纯文本文件,将一些 shell 的语法与指令(含外部指令)写在里面, 搭配正则表达式、管线命令与数据流重导向等功能,以达到我们所想要的处理目的。
Shell 脚本可以简单的被看成是批处理文件, 也可以被说成是一个程序语言,且这个程序语言由于都是利用 shell 与相关工具指令, 所以不需要编译即可执行,且拥有不错的除错 (debug) 工具,所以,shell可以帮助系统管理员快速的管理好主机。
2.Shell脚本特性
自动化常用命令
追踪与管理系统的重要工作
简单入侵检测功能
连续指令单一化
简易的数据处理
跨平台支持与学习历程较短
3.创建shell 脚本
第一步:使用文本编辑器(vim)来创建文本文件
第一行必须包括shell 声明序列:#!
#!/bin/bash (告诉系统执行的时候要调用什么解释器)
添加注释
注释以# 开头 (# 都是批注用途,加在#后面的数据都被当做批注文字)
第二步:运行脚本
给予执行权限,在命令行上指定脚本的绝对或相对路径
直接运行解释器,将脚本作为解释器程序的参数运行
例:计算/etc/passwd文件中的第10个用户和第20个用户的ID之和
#!/bin/bash #Filename:ID.sh 文件名:ID.sh #Description:Test 描述:测试 #Author:Rookie 作者:菜鸟 # Program: This program shows "ID sum!" in your screen. 程序:这个程序显示“ID和!“在你的屏幕上 #Email:xxx@126.com 电子邮件:xxx@126.com #Revision:3.1 修订号:3.1 #Date:2017-04-14 日期:2017-04-14 #Note:Test #The 10th in the/etc/passwd file ID of the user 在/etc/passwd文件中第10个用户的ID id1=$(head -10 /etc/passwd | tail -1 | cut -d: -f3) #The 20th in the/etc/passwd file ID of the user 在/etc/passwd文件中第20个用户的ID id2=$(head -20 /etc/passwd | tail -1 | cut -d: -f3) #Calculate a 10th of the/etc/passwd file users and 20th the sum of the user's ID 计算/etc/passwd文件中的第10个用户和第20个用户的ID之和 sum=$((id1+id2)) echo ${sum}
按 i 键进入输入模式进行编辑
编辑完成后按 ESC键,进入编辑模式后按 ;输入wq保存退出
[root@station29 scripts]# bash ID.sh sum=180 执行结果 ID和为180
变量:命名的内存空间
数据存储方式:
字符:
数值:整型,浮点型
变量:变量类型
作用:
1 、数据存储格式
2 、参与的运算
3 、表示的数据范围
类型:
字符
数值:整型、浮点型
变量
强类型 :变量 不经过强制转换,它永远是这个数据类型,不允许隐式的类型 转换。一般定义变量时必须指定类型、参与运算必须符合类型要求;调用未声明变量会产生错误如 java,c#
弱类型:语言的运行时会隐式做数据类型 转换。无须指定类型,默认均为字符型;参与运算会自动进行隐式类型转换;变量无须事先定义可直接调用
如:bash 不支持浮点数,php
变量命名法则:
1 、不能使程序中的保留字:例如if, for
2 、只能使用数字、字母及下划线,且不能以数字开头
3 、见名知义
4 、统一命名 规则:驼峰命名法
bash 中变量的种类:
根据变量的生效范围等标准:
本地变量:生效范围为当前shell 进程;对当前shell 之外的其它shell 进程,包括当前shell 的子shell 进程均无效
环境变量:生效范围为当前shell 进程及其子进程
位置变量:$1 $2…表示,用于让脚本在脚本代码中调用通过命令行传递给他的参数
局部变量:生效范围为当前shell 进程中某代码片断( 通常指函数)
——–shell—–父shell —————-
| |
|———–bash 子shell—–|
子shell只会继承环境变量 并不会继承父shell中的变量
. 或者 source /etc/profile 只在当前的shell环境中执行,一般用来校对环境变量
set:显示已经定义的所有变量
unset name:删除变量
export name=将一个变量声明为环境变量
readonly name=将一个变量声明为只读变量
last arg is ${10} 当位置参数达到10或10以上时需要加{}
变量引用:$name ${name}
位置变量:$1, $2, … 来表示,用于让脚本在脚本代码中调用通过命令行传递给它的参数
特殊变量:$?, $0, $*, $@, $#,$$
$0:命令本身
$*:传递给脚本的所有参数,全部参数合为一个字符串
$@:传递给脚本的所有参数,每个参数为独立字符串
$#:传递给脚本的参数的个数
$* $@在被双引号包起来的时候才会有差异
seet –:清空所在行以下所有位置变量
shift:踢掉变量 shift 5:踢掉5个变量
bash 中的算术运算:help let
+, -, *, /, % 取模(取余), ** (乘方)
实现算术运算:
(1) let var= 算术表达式
(2) var=$[ 算术表达式]
(3) var=$(( 算术表达式))
(4) var=$(expr arg1 arg2 arg3 …)
(5) declare –i var = 数值
(6) echo ‘ 算术表达式’ | bc
乘法符号有些场景中需要转义 ,如*
[root@localhost ~]# x=100 [root@localhost ~]# y=200 [root@localhost ~]# let z=$x+$y [root@localhost ~]# echo $z 300
bash 有内建的随机数生成器:
echo $RANDOM (0-32767)
echo $[$RANDOM%50] :0-49
[root@station29 scripts]# echo $[$RANDOM%50] 0 [root@station29 scripts]# echo $[$RANDOM%50] 44 [root@station29 scripts]# echo $[$RANDOM%50] 3 [root@station29 scripts]# echo $RANDOM 28979 [root@station29 scripts]# echo $RANDOM 22390 [root@station29 scripts]# echo $RANDOM 1374
增强型赋值:
+=, -=, *=, /=, %=
自增,自减:
let var+=1
let var++
let var-=1
let var–
逻辑运算
非:!
! 1 = 0
! 0 = 1
短路运算
短路与
第一个为0 ,结果必定为0
第一个为1 ,第二个必须要参与运算
短路或
第一个为1 ,结果必定为1
第一个为0 ,第二个必须要参与运算
异或:^
异或的两个值, 相同为假,不同为真
bash 的测试类型
数值测试:
-gt |
是否大于 |
-ge |
是否大于等于 |
-eq |
是否等于 |
-ne |
是否不等于 |
-lt |
是否小于 |
-le |
是否小于等于 |
字符串测试:
== :是否等于;
>: ascii 码是否大于ascii码 码
<: 是否小于
!=: 是否不等于
=~: 左侧字符串是否能够被右侧的PATTERN所匹配
注意: 此表达式一般用于[[ ]] 中;扩展的正则表达式
-z “STRING” :字符串是否为空,空为真,不空为假
-n “STRING” :字符串是否不空,不空为真,空为假
注意:用于字符串比较时的用到的操作数都应该使用引号
存在性测试:
-e或-a |
文件存在性测试,存在为真,否则为假 |
-f |
是否存在且为普通文件 |
-d |
否存在且为目录文件 |
-b |
是否存在且为块设备文件 |
-c |
是否存在且为字符设备文件 |
-s |
是否存在且为套接字文件 |
-p |
是否存在且为命名管道文件 |
-h/-l |
是否存在且为符号链接文件 |
[root@localhost ~]# [ -e /etc/passwd -a -r /etc/passwd ] && echo ok ok [root@localhost ~]# [ -e /etc/passwd -a -r /etc/pas ] && echo ok 不存在 [root@localhost ~]# [ -e /etc/passwd -a -r /etc/passwd ] || echo ok 存在
首先,现判断是否是链接文件,再判断其它类别 [root@localhost ~]# [ -b /etc/passwd ] && echo ok [root@localhost ~]# [ -b /dev/cdrom ] && echo ok ok [root@localhost ~]# ll /dev/cdrom lrwxrwxrwx. 1 root root 3 May 16 21:46 /dev/cdrom -> sr0 [root@localhost ~]# [ -L /dev/cdrom ] && echo ok ok [root@localhost ~]# [ -d test/ ] && echo ok ok [root@localhost ~]# [ -f f1 ] && echo ok ok
文件权限测试:
-r |
是否存在且可读 |
-w |
是否存在且可写 |
-x |
是否存在且可执行 |
-u |
是否存在且拥有suid 权限 |
-g |
是否存在且拥有sgid 权限 |
-k |
是否存在且拥有sticky 权限 |
-s(文件大小测试) |
是否存在且非空 |
[root@localhost ~]# [ -r /etc/passwd ] && echo ok ok [root@localhost ~]# [ -w /etc/passwd ] && echo ok ok [root@localhost ~]# [ -x /bin/cat ] && echo ok ok [root@localhost ~]# [ -u /usr/bin/passwd ] && echo ok ok [root@localhost ~]# chmod 2755 /bin/cat [root@localhost ~]# [ -g /bin/cat ] && echo ok ok [root@localhost ~]# chmod o+t /app [root@localhost ~]# [ -k /app ] && echo ok ok [root@localhost ~]# chmod 777 /app 去掉黏滞位权限 查看既有读权限又有写权限
[root@localhost ~]# [ -s /etc/passwd ] && echo ok ok [root@localhost ~]# [ -r /etc/passwd -a -w /etc/passwd ] && echo ok ok 判断文件不能执行 [root@localhost ~]# [ ! -x /etc/passwd ] && echo ok
文件是否打开:
-t fd: fd 表示文件描述符是否已经打开且与某终端相关
-N FILE :文件自动上一次被读取之后是否被修改过
-O FILE :当前有效用户是否为文件属主
-G FILE
[root@localhost ~]# [ -N l1 ] && echo ok ok [root@localhost ~]# [ -O mbr ] && echo ok ok [root@localhost ~]# [ -G mbr ] && echo ok ok
双目测试:
FILE1 -ef FILE2: FILE1 与FILE2 是否指向同一个设备
上的相同inode
FILE1 -nt FILE2: FILE1 是否新于FILE2
FILE1 -ot FILE2: FILE1 是否旧于FILE2
组合测试条件
第一种方式:
命令1 && 命令2 并且
命令1 || 命令2 或者
[ "$1" -gt "$2" ] && echo "$1 > $2" || echo "$1 <= $2" $1如果大于$2,就打印“$1>$2”,若不大于,就打印“$1<=$2”
如:[[ -r FILE ]] && [[ -w FILE ]]
第二种方式:
EXPRESSION1 -a EXPRESSION2 并且
EXPRESSION1 -o EXPRESSION2 或者
[ $a -gt 60 -a $a -lt 100 ] && echo Pass 如果a大于60小于100就打印Pass
必须使用测试命令
bash 的配置文件:
按生效范围划分,存在两类:
全局配置:
/etc/profile
/etc/profile.d/*.sh
/etc/bashrc
个人配置:
~/.bash_profile
~/.bashrc
交互式登录:
(1) 直接通过终端输入账号密码登录;
(2) 使用“ “su – UserName” 切换的用户
执行顺序:
/etc/profile –> /etc/profile.d/*.sh –>~/.bash_profile –> ~/.bashrc –> /etc/bashrc
非交互式登录:
(1)su UserName
(2) 图形界面下打开的终端
(3) 执行脚本
执行顺序:
~/.bashrc –> /etc/bashrc –>/etc/profile.d/*.sh
编辑配置文件生效:
修改profile 和bashrc 文件后需生效
两种 方法:
1 重新启动shell 进程
2 或source
例: . ~/.bashrc
条件性的执行操作符:
将多个条件写入一个中括号内的情况之外, 可以多个中括号来隔开喔!而括号与括号之间,则以 && 或 || 来隔开,他们的意义是:
&& :与
命令1成功,就执行命令2
命令1 失败,就不执行命令2
|| :或
命令1成功,就不执行命令2
命令1失败,就执行命令2
例:
1. 这个文件是否存在,若不存在则给予一个『Filename does not exist』的讯息,并中断程序;
2. 若这个文件存在,则判断他是个文件或目录,结果输出『Filename is regular file』或 『Filename is directory』
3. 判断一下,执行者的身份对这个文件或目录所拥有的权限,并输出权限数据!
#!/bin/bash #Filename:quanxian.sh #Description:Test #Author:Rookie # Program: # User input a filename, program will check the flowing: # 1.exist? 2.file/directory? 3.file permissions #Email:xxx@126.com #Revision:3.2 #Date:2017-04-14 PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH # 1. 让使用者输入档名,并且判断使用者是否真的有输入字符串? echo -e "Please input a filename, I will check the filename's type and permission. \n\n" read -p "Input a filename : " filename test -z ${filename} && echo "You MUST input a filename." && exit 0 # 2. 判断文件是否存在?若不存在则显示讯息并结束脚本 test ! -e ${filename} && echo "The filename '${filename}' DO NOT exist" && exit 0 # 3. 开始判断文件类型与属性 test -f ${filename} && filetype="regulare file" test -d ${filename} && filetype="directory" test -r ${filename} && perm="readable" test -w ${filename} && perm="${perm} writable" test -x ${filename} && perm="${perm} executable"
输出结果
[root@station29 scripts]# bash quanxian.sh Please input a filename, I will check the filename's type and permission. 请输入文件名,我将检查文件名的类型和权限 Input a filename : /etc The filename: /etc is a directory 文件名:/etc是目录 And the permissions for you are : readable writable executable 你的权限:可读可写可执行
一个条件判断,分成功进行与失败进行 (else)
if [ 条件判断式 ]; then
当条件判断式成立时,可以进行的指令工作内容;
else
当条件判断式不成立时,可以进行的指令工作内容;
Fi
多个条件判断 (if … elif … elif … else) 分多种不同情况执行
if [ 条件判断式一 ]; then
当条件判断式一成立时,可以进行的指令工作内容;
elif [ 条件判断式二 ]; then
当条件判断式二成立时,可以进行的指令工作内容;
else
当条件判断式一与二均不成立时,可以进行的指令工作内容;
Fi
elif 也是个判断式,因此出现 elif 后面都要接 then 来处理
例:
1. 当执行一个程序的时候,这个程序会让用户选择 Y 或 N ,
2. 如果用户输入 Y 或 y 时,就显示OK, continue
3. 如果用户输入 n 或 N 时,就显示 Oh, interrupt !
4. 如果不是 Y/y/N/n 之内的其他字符,就显示 I don’t know what your choice is
#!/bin/bash #Filename:panduanshi.sh #Description:Test #Author:Rookie # Program:shows the user's choice #Email:xxx@126.com #Revision:3.2 #Date:2017-04-14 PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin export PATH read -p "Please input (Y/N): " yn if [ "${yn}" == "Y" ] || [ "${yn}" == "y" ]; then 如果输入y 那么 echo "OK, continue" 继续 elif [ "${yn}" == "N" ] || [ "${yn}" == "n" ]; then 如果输入n 那么 echo "Oh, interrupt!" 中断 else echo "I don't know what your choice is" 输入其它字符,显示我不知道你选择什么 fi [root@station29 scripts]# bash panduanshi.sh Please input (Y/N): y OK, continue 继续 [root@station29 scripts]# bash panduanshi.sh Please input (Y/N): n Oh, interrupt! 中断 [root@station29 scripts]# bash panduanshi.sh Please input (Y/N): q I don't know what your choice is 我不知道你的选择是什么
原创文章,作者:Linux.rookie,如若转载,请注明出处:http://www.178linux.com/73351
评论列表(1条)
主要介绍了bash编程的基础特性及基础用法,内容写的很不错,排版也很好,加油,加油!