1.1 shell 脚本的编写规范
1.2 变量与特殊变量应用
1.3局部变量与全局变量
1.4 条件测试表达式
------------------------------------------------------
背景:在一些复杂的Linux维护工作中,大量重复的输入和交互操作不但费时费力,而且容易出错.
编写脚本的好处:
批量的处理,自动化的完成维护,减轻管理员的负担.
linux的shell脚本是一种特殊的应用程序
常见的shell解释器有很多种
使用不同的shell解释器内部指令不同
/bin/bash是大多数linux中默认的shell解释器。
之后的所有脚本的编写都是bash脚本
查看我们的系统都有哪些shell解释器?
命令:chsh –l 或 cat /etc/shells
1、编写第一个Shell脚本
shell脚本就是将我们平时执行的命令集合到一个文件中,然后赋予文件执行权限,一次执行。
Linux系统中不以文件后缀名来区分文件,但是为了便于记忆和管理,我们习惯性将脚本文件以.sh结尾
vim first.sh
然后,保存退出即可!!!(在学编程的时候,一般我们的第一个程序都是Hello world!,这里我们也一次为例)
解释:
第一行:#!/bin/bash
指定运行这个脚本的解释器是/bin/bash
#表示这一行是注释,然后跟了一个!表示这一个非注释!!!赞
第二、三行:注释信息,标明这个脚本的功能
当写一个比较大的脚本时,如果没有一个好的注释,那么也就也就没有人都能够看懂其中的意思了
第四行:脚本功能的实现!(输入平时在shell中输入的命令即可)
脚本的执行方式:(五种)
1、对文件添加可执行权限,然后使用绝对路径执行
chmod +x first.sh
/root/first.sh
2、对文件添加可执行权限,然后使用相对路径执行--->./开头
./first.sh
3、使用sh命令执行
sh first.sh
[root@xiaogan ~]# sh --help
GNU bash, version 4.2.46(1)-release-(x86_64-redhat-linux-gnu)
Usage: sh [GNU long option] [option] ...
sh [GNU long option] [option] script-file ...
GNU long options:
--debug
--debugger
--dump-po-strings
--dump-strings
--help
--init-file
--login
--noediting
--noprofile
--norc
--posix
--protected
--rcfile
--rpm-requires
--restricted
--verbose
--version
Shell options:
-irsD or -c command or -O shopt_option (invocation only)
-abefhkmnptuvxBCHP or -o option
Type `sh -c "help set"' for more information about shell options.
Type `sh -c help' for more information about shell builtin commands.
[root@xiaogan ~]# sh -c help
GNU bash, version 4.2.46(1)-release (x86_64-redhat-linux-gnu)
These shell commands are defined internally. Type `help' to see this list.
Type `help name' to find out more about the function `name'.
Use `info bash' to find out more about the shell in general.
Use `man -k' or `info' to find out more about commands not in this list.
A star (*) next to a name means that the command is disabled.
job_spec [&] history [-c] [-d offset] [n] or hist>
(( expression )) if COMMANDS; then COMMANDS; [ elif C>
. filename [arguments] jobs [-lnprs] [jobspec ...] or jobs >
: kill [-s sigspec | -n signum | -sigs>
[ arg... ] let arg [arg ...]
[[ expression ]] local [option] name[=value] ...
alias [-p] [name[=value] ... ] logout [n]
bg [job_spec ...] mapfile [-n count] [-O origin] [-s c>
bind [-lpvsPVS] [-m keymap] [-f filen> popd [-n] [+N | -N]
break [n] printf [-v var] format [arguments]
builtin [shell-builtin [arg ...]] pushd [-n] [+N | -N | dir]
caller [expr] pwd [-LP]
case WORD in [PATTERN [| PATTERN]...)> read [-ers] [-a array] [-d delim] [->
cd [-L|[-P [-e]]] [dir] readarray [-n count] [-O origin] [-s>
command [-pVv] command [arg ...] readonly [-aAf] [name[=value] ...] o>
compgen [-abcdefgjksuv] [-o option] > return [n]
complete [-abcdefgjksuv] [-pr] [-DE] > select NAME [in WORDS ... ;] do COMM>
compopt [-o|+o option] [-DE] [name ..> set [-abefhkmnptuvxBCHP] [-o option->
continue [n] shift [n]
coproc [NAME] command [redirections] shopt [-pqsu] [-o] [optname ...]
declare [-aAfFgilrtux] [-p] [name[=va> source filename [arguments]
dirs [-clpv] [+N] [-N] suspend [-f]
disown [-h] [-ar] [jobspec ...] test [expr]
echo [-neE] [arg ...] time [-p] pipeline
enable [-a] [-dnps] [-f filename] [na> times
eval [arg ...] trap [-lp] [[arg] signal_spec ...]
exec [-cl] [-a name] [command [argume> true
exit [n] type [-afptP] name [name ...]
export [-fn] [name[=value] ...] or ex> typeset [-aAfFgilrtux] [-p] name[=va>
false ulimit [-SHacdefilmnpqrstuvx] [limit>
fc [-e ename] [-lnr] [first] [last] o> umask [-p] [-S] [mode]
fg [job_spec] unalias [-a] name [name ...]
for NAME [in WORDS ... ] ; do COMMAND> unset [-f] [-v] [name ...]
for (( exp1; exp2; exp3 )); do COMMAN> until COMMANDS; do COMMANDS; done
function name { COMMANDS ; } or name > variables - Names and meanings of so>
getopts optstring name [arg] wait [id]
hash [-lr] [-p pathname] [-dt] [name > while COMMANDS; do COMMANDS; done
help [-dms] [pattern ...] { COMMANDS ; }
4、使用. [文件名]执行 注:点的后面有个空格
. first.sh
5、使用source命令执行 注:一般source命令用于执行配置文件
source first.sh
注:前两种,需要文件具有可执行权限(在企业,不推荐使用,不安全)
后三种,不需要文件具有可执行权限(推荐使用)
-------------------------------------------------------
2.SHELL 变量
定义:可以存放一个可变的值的空间
默认情况下:Linux中可以将每个shell看成不同的执行环境,所以相同的变量名,在不同执行环境中变量值是不同的
2.1 变量的分类:自定义变量、环境变量、位置变量、预定义变量
2.2 变量的输出:echo $[变量名] # $是引用变量的特殊字符(固定格式)
2.3 变量的介绍:(注意,shell中区分大小写)
2.3.1 自定义变量:用户根据自己的环境,自己定义的变量,(最简单的变量)
声明格式:变量名=变量值
注意:=左右两边不要有空格;
变量名只能以字母和下划线开头,且名称中不能出现特殊符号
特殊符号:+-*/,.`\?%*等
举例:1、定义变量并输出
2、一起调用两个变量
3、{}的使用
read命令,对变量复制,通过文件或标准输入
read $xg $xiaogan
[root@xiaogan ~]# read -p "Input your password:" passwd
[root@xiaogan ~]# read -s -p "Input your password:" passwd #-s 选项 不回显
变量的作用域:
一般我们定义的变量都是只在当前shell中可以使用的,当到另外的shell中,就不能用了。
我们可以使用export命令,将这些变量声明为全局变量,这样在新的shell中仍然可以使用:
export xiaogan xg
set 用来显示本地变量
env 用来显示环境变量
export 用来显示和设置环境变量
区别:
set 显示当前shell的变量,包括当前用户的变量
env 显示当前用户的变量
export 显示当前导出成用户变量的shell变量
数值变量的运算
shell脚本的数值运算多用于脚本程序的过程控制(如循环次数,使用量比较等)
在shell环境中,只能进行比较简单的整数运算
运算符与变量之间必须有一个空格位,
整数的运算主要是通过内部命令expr 命令进行运算
Usage:变量1 运算符 变量2
其中 变量1 、变量2 ……对应的需要计算的数值变量(需要$符号调用)常用的几种运算符如下所示
加法运算:+
减法运算:-
乘法运算:\* #由于*还有一个意思,所以需要使用反斜杠转义
除法运算:/
求模(取余)运算:%
2.3.2 环境变量:
环境变量是指系统本身运行需要,由linux系统提前创建好的一类变量.
主要用于用户的工作环境,包括(用户的宿主目录HOME,命令的查找路径PATH,用户的当前目录PWD,登录的终端SHELL等)环境变量的值由操作系统本身自己维护,随着用户的状态改变而改变
env调取当前环境变量
环境变量的配置文件在/etc/profile(全局)
用户宿主目录/home/zhangsan/.bash_profile(局部)
PWD #pwd命令就是调用了这个变量才能进行输出
PATH
定义命令的默认搜索路径
我们讲的mysql可执行程序优化的时候我们是直接将程序路径写到了这个变量中才可以再任何目录下进行输入.
USER
SHELL
HOME
将我们所写的脚本放到$PATH的默认搜索路径中去
1.将/root目录写入到PATH的环境变量中,但是还没有永久生效
2.刷新一下/etc/profile 配置文件就可以永久生效了
3.之后/root下的可执行程序可以在任何目录下直接执行执行不许要任何命令去执行
注:为了方便运行当前目录的可执行文件,所以我把 .(当前目录) ---> 也添加到了PATH变量中
2.3.3 位置变量:
当执行命令行操作时第一个字段表示命令字或程序名,
其余的字符串参数按照从左到右的顺序依次给位置变量赋值
位置变量也称为位置参数,使用$1 $2 $3 …$9表示
例如:ls –a /root
其中ls表示命令字 -a 就是位置参数 $1 /root就是位置参数 $2
vim sum.sh
sh –x sum.sh 110 112
2.3.4 预定义变量:
$#:命令行中位置变量的个数(程序执行了几个位置参数)
$*:所有位置变量的内容(具体的内容 比如/boot就是一个具体的内容)
$?:上一条命令执行后返回的状态,当返回状态值为0时表示执行正常,非0值表示执行异常或出错
判断是否出现错误正常为0异常错误为非0 取值在1-127之间
$0:当前执行的进程/程序名(就是当前执行的命令或程序的名字)
!$:上一条命名的最后一个参数
[root@xiaogan ~]# sh backup.sh /root /boot
2.3.5 单引号:
要赋值的内容包括"$"、"\"等,
具有其他含义的特殊字符时,应使用单引号将其括起来;
在单引号范围内将无法引用其他的值,任何字符均作为普通字符看待,
但赋值 的内容包含单引号时需要使用\’符号进行转义以免冲突.
2.3.6 双引号:
1、当=号右边赋值出现空格的时候,需要使用双引号将其扩起
2、在双引号的范围内还可以引用其他的变量,从而能够将现有的变量赋值给新的变量
2.3.7 反撇号:取值,同$()
反撇号括起来的范围内必须是可执行的命令。否则将会出现错误
当发生嵌套时,反撇号就不太好使了,这是我们会选择使用$()取值符号
-------------------------------------------------------
条件表达式
1、使用test命令进行判断
2、使用 [ ]命令
Usage:test 条件表达式
Usage:[ 条件表达式 ]
1、文件测试
文件测试是指根据给定的路径名称,判断是文件还是目录,判断是具有读写执行的权限,判断文件目录是否存在
常用的选项如下
-d:测试是否为目录(Directory)或目录是否存在
-e:测试目录或文件是否存在(Exist)
-f:测试是否为文件(File)或文件是否存在
-r:测试当前用户是否有权限读取(Read)
-w:测试当前用户是否有权限写入(Write)
-x:测试当前用户是否有权限执行(eXcute)
举例:一般我们挂在光盘的时候习惯将光盘挂载在/media/cdrom这个目录,但是rhel系统默认不存在这个目录,这时我们可以先判断一下这个目录是否存在
我们使用[ ]的这种方式进行判断,这种也是最常用的一种格式注意两边最少需要一个空格位
使用echo 输出一下$? 可以看见返回值为非0通过判断的返回结果我们可以断定cdrom这个目录是不存在的。
当我将cdrom这个目录创建完成之后在进行判断就是条件成立返回值为0这个表达式是成立的。
通过查看变量$?的方式比较不直观我们可以使用逻辑测试中的&来进行判断
在表达式的后面执行 双&
如果前面的表达式成立则输出YES否则什么都不输出
[root@xiaogan ~]# [-d /media/cdrom]
bash: [-d: command not found...
[root@xiaogan ~]# [ -d /media/cdrom ]
[root@xiaogan ~]# echo $?
1
[root@xiaogan ~]# test -d /media/cdrom
[root@xiaogan ~]# echo $?
1
[root@xiaogan ~]# mkdir /media/cdrom
[root@xiaogan ~]# [ -d /media/cdrom ]
[root@xiaogan ~]# echo $?
0
[root@xiaogan ~]# [ -d /media/cdrom ] && echo "YES" YES
[root@xiaogan ~]# rm -rf /medis/cdrom
[root@xiaogan ~]# rm -rf /media/cdrom
[root@xiaogan ~]# [ -d /media/cdrom ] && echo "YES"
[root@xiaogan ~]#