Shell 是什么
- Shell是linux的一外壳,它包在linux内核的外面,为用户和内核之间的交互提供了一个接口
- 当用户下达指令给操作系统的时候,实际上是把指令告诉shell,经过shell解释,处理后让内核做出相应的动作
- 系统的回应和输出的信息也由shell处理,然后显示在用户的屏幕上
Shell 是一个命令行解释器,它为用户提供了一个向 Linux 内核发送请求以便运行程序的界面系统级程序, 用户可以用 Shell 来启动、 挂起、 停止甚至是编写一些程序.
什么是shell脚本
- 简单的说,当命令或者程序不在命令行执行,而是通过一个程序文件来执行,这个程序就被称为shell脚本
- 也就是在shell脚本里内置了多条命令,语句,循环控制,然后将这些命令一次性执行完毕,这种通过文件执行命令的方式称为非交互式
为什么使用shell脚本
- 适合处理操作系统底层的业务,有众多系统命令为其做支撑(还有文本处理三兄弟grep,sed,awk)
- 适合处理纯文本文件,linux中许多服务配置文件,启动脚本,都是纯文本(httpd,nfs,mysql,nginx,lvs)
- linux系统脚本用shell开发更简单
Shell脚本开发规范
- 一个完整的shell脚本需要有以下几个部分:
脚本名:最好以.sh结尾
第一行: #!/bin/bash
指定解释器:指定由哪个shell解释器来执行脚本内容,linux自带的bash
#!:幻数
注意:#!/bin/bash必须写在第一行,否则会被认为是注释
有用户判断,否则任何用户都可以执行这个脚本
有流程控制,否则只是把简单的命令进行顺序操作,没有成功与否的判断
注释:可以命令后,也可以自成一行(方便自己也方便他人)
此外,执行一个脚本,该脚本需要有可执行的权限!!
编写第一个 Shell 脚本
- 需求说明
创建一个 Shell 脚本, 输出hello world!
脚本的常用执行方式
(1)输入脚本的绝对路径或相对路径
1)首先要赋予脚本的+x 权限(可执行权限)
2)执行脚本
(2)sh+脚本 这种方式不推荐
不用赋予脚本+x 权限, 直接执行即可
shell 的变量
Shell 的变量的介绍
1) Linux Shell 中的变量分为: 系统变量和用户自定义变量;
2) 系统变量或环境变量: $HOME、 $PWD、 $SHELL、 $USER 等等;
3) bash 中,变量默认都是字符串类型,不论是否使用引号赋值,都以字符串的方式存储;
4)set 用于显示当前 shell 中所有变量,包括用户自定义变量和环境变量
5)如果要将自定义变量临时升级为环境变量,可以使用 setenv 或者 export 关键字,格式如下:
export str
这样的话 str 就可以在当前shell 和 子 shell 中使用,但是退出脚本或者重新登录 shell 都会取消 export 效果;
shell 变量的定义
- 基本语法
1)定义变量 变量名=值 (=两边不能有空格)
2)撤销或删除变量 unset 变量名
3) 声明静态变量 readonly 变量名=值 注意不能用 unset 撤销静态变量,静态变量的值也不能改变
同时,变量名的命名须遵循如下规则:
- 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头
- 中间不能有空格,可以使用下划线(_)
- 不能使用标点符号
- 不能使用bash里的关键字(可用help命令查看保留关键字)
使用变量
使用一个定义过的变量,只要在变量名前面加美元符号$即可,如:
#!/bin/bash
your_name="tom"
echo $your_name
your_name="alibaba"
echo $your_name
也可以将变量名用大括号包起来,如下:
将命令的返回值赋给变量
1) A=`ls -la` 反引号, 运行里面的命令, 并把结果返回给变量 A
2) A=$(ls -la) 等价于反引号
3)反引号只有在将命令的返回值赋给变量时才需要使用
例子:
变量名外面的花括号或括号是可选的,加不加都行,加花括号是为了帮助解释器识别变量的边界.
设置环境变量
- 基本语法
1) export 变量名=变量值 (功能描述: 将 shell 变量输出为环境变量)
2) source 配置文件 (功能描述: 让修改后的配置信息立即生效)
3) echo $变量名 (功能描述: 查询环境变量的值)
环境变量类似于其他语言中的全局变量,也就是说在其他shell脚本中也是可见的.
定义环境变量的步骤如下:
1) 在/etc/profile 文件中定义名为 TOMCAT 环境变量
通过 vim /etc/profile 进入到该文件下,然后在该文件中定义环境变量:
2)使用source /etc/profile 刷新该文件
3)使用该环境变量
注意: 在使用 环境变量前, 需要让其生效,也就是对 /etc/profile 文件进行source刷新;
位置参数变量
当我们执行一个 shell 脚本时, 如果希望获取到终端中命令行的参数信息, 就可以使用到位置参数变量, 比如 : ./myshell.sh 100 200 , 这个就是一个执行 shell 的命令行, 可以在 myshell 脚本中获取到参数100 和 200
- 基本语法
$n (功能描述: n 为数字, $0 代表命令本身(shell 脚本名), $1-$9 代表第一到第九个参数, 十以上的参数, 十 以上的参数需要用大括号包含, 如${10})
$* (功能描述: 这个变量代表命令行中所有的参数, $*把所有的参数看成一个整体)
$@ (功能描述: 这个变量也代表命令行中所有的参数, 不过$@把每个参数区分对待)
$# (功能描述: 这个变量代表命令行中所有参数的个数)
例子:编写一个 shell 脚本, 在脚本中获取到命令行的各个参数信息
shift 轮替变量
位置参数可以使用 shift 命令左移,命令格式如下:
shift [n] #默认为1
当执行完第一次循环后,将前3个变量移出,所以第一个位置参数就变为了4,然后经过第二次循环后第一个位置参数就变为了7;
预定义变量
预定义变量就是shell 设计者事先已经定义好的变量, 可以直接在 shell 脚本中使用
- 基本语法
$$ (功能描述: 当前进程的进程号(PID) )
$! (功能描述: 后台运行的最后一个进程的进程号(PID) )
$? (功能描述: 最后一次执行的命令的返回状态, 如果这个变量的值为 0, 证明上一个命令正确执行; 如果这个变量的值为非 0(具体是哪个数, 由命令自己来决定) , 则证明上一个命令执行不正确了 )
例子:在一个 shell 脚本中简单使用一下预定义变量
获取变量的长度
前面说到过 shell 都是将变量作为字符串来处理的,通过 ${#str}的方式可以获取变量的长度,如下例子:
Shell 字符串
字符串是shell编程中最常用最有用的数据类型(除了数字和字符串,也没啥其它类型好用了),字符串可以用单引号,也可以用双引号,也可以不用引号;
单引号
str='this is a string'
单引号字符串的限制:
- 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
- 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用;
#!/bin/bash
your_name="runoob"
# 使用单引号拼接
greeting_2='hello, '$your_name' !'
greeting_3='hello, ${your_name} !'
echo $greeting_2
echo $greeting_3
单引号字符串只能用单引号来进行拼接,其余符号都会原样输出!!
双引号
your_name='runoob'
str="Hello, I know you are \"$your_name\"! \n" #转义字符\,保证""输出
echo -e $str
输出结果如下:
双引号的优点:
- 双引号里可以有变量
- 双引号里可以出现转义字符
来看下面例子:
#!/bin/bash
your_name="runoob"
# 使用双引号拼接
greeting="hello, "$your_name" !"
greeting_1="hello, ${your_name} !"
echo $greeting
echo $greeting_1
获取字符串长度
#!/bin/bash
your_name="runoob"
# 使用双引号拼接
greeting="hello, "$your_name" !"
echo $greeting
echo ${#greeting}
字符串长度为15,说明字符串中的空格也占一个位置!!
提取子字符串
以下实例从字符串第 2 个字符开始截取 4 个字符:
string="runoob is a great site"
echo ${string:1:4} # 输出 unoo
查找子字符串
查找字符 i 或 o 的位置(哪个字母先出现就计算哪个):
string="runoob is a great site"
echo `expr index "$string" io` # 输出 4
注意: 以上脚本中 ` 是反引号,而不是单引号 '
Shell 数组
bash支持一维数组(不支持多维数组),并且没有限定数组的大小;
类似于 C 语言,数组元素的下标由 0 开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于 0;
在 Shell 中,用括号来表示数组,数组元素用"空格"符号分割开。定义数组的一般形式为:
数组名=(值1 值2 ... 值n)
例如:
array_name=(value0 value1 value2 value3)
还可以单独定义数组的各个分量:
array_name[0]=value0
array_name[1]=value1
array_name[n]=valuen
可以不使用连续的下标,而且下标的范围没有限制;
读取数组
读取数组元素值的一般格式是:
${数组名[下标]}
例如:
valuen=${array_name[n]}
使用 @ 符号可以获取数组中的所有元素,例如:
echo ${array_name[@]}
获取数组的长度
获取数组长度的方法与获取字符串长度的方法相同,例如:
# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}
Shell 注释
以 # 开头的行就是注释,会被解释器忽略。
通过每一行加一个 # 号设置多行注释,像这样:
##### 用户配置区 开始 #####
#
#
# 这里可以添加脚本描述信息
#
#
##### 用户配置区 结束 #####
多行注释
多行注释还可以使用以下格式:
:<<EOF
注释内容...
注释内容...
注释内容...
EOF
EOF 也可以使用其他符号:
:<<'
注释内容...
注释内容...
注释内容...
'
:<<!
注释内容...
注释内容...
注释内容...
!