概念:
Shell 脚本(shell script),是一种为 shell 编写的脚本程序。
Shell 脚本(Shell Script)又称 Shell 命令稿、程序化脚本,是一种计算机程序使用的文本文件,内容由一连串的 shell 命令组成,经由 Unix Shell 直译其内容后运作
Shell 被当成是一种脚本语言来设计,其运作方式与解释型语言相当,由 Unix shell 扮演命令行解释器的角色,在读取 shell 脚本之后,依序运行其中的 shell 命令,之后输出结果。利用 shell 脚本可以进行系统管理,文件操作等。
在 Unix 及所有的系统中,如 Linux、FreeBSD 等操作系统,都存在 shell 脚本。依照 Unix shell 的各种不同类型,shell 脚本也有各种不同方言。在 DOS、OS/2、Microsoft Windows 中的批处理文件,跟 shell
脚本有类似的功能。
总结说shell就是操作系统和应用程序之间的一个命令翻译工具,它在操作系统外,应用程序内,是应用程序和操作系统的接口。
shell环境:
- java需要虚拟机解释器, 同理 shell脚本也需要解释器
- Shell 编程跟 JavaScript、php 编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了。
Bourne Again Shell由于易用和免费,Bash 在日常工作中被广泛使用。同时,Bash 也是大多数Linux 系统默认的Shell
Linux 的 Shell 种类众多,常见的有:
- Bourne Shell(/usr/bin/sh或/bin/sh)
- Bourne Again Shell(/bin/bash)
- C Shell(/usr/bin/csh)
- K Shell(/usr/bin/ksh)
- Shell for Root(/sbin/sh)
- 等等……
查看解释器
# 查看解释器
cat /etc/shells
# 查看Linux中默认的shell
echo $SHELL
shell的使用方式:
手动:直接输入命令,逐行执行
脚本:先写到文件然后运行文件,也叫脚本文件
第一个shell脚本:
先新建一个文件
# 先新建一个文件
touch a.sh
# 编辑a.sh文件
vim a.sh
编辑a.sh文件
# 这里是指定使用的shell是bash
#!/bin/bash
echo '我想要好多好多小姐姐和玩'
wq!退出后执行脚本文件
./a.sh
# 如果遇到权限不够就修改权限
chmod 777 a.sh
shell注释:
单行注释
# 这是单行注释
多行注释
:<< 字符
这是多行注释,必须是指定的字符开始和结束,一般都是用!
字符
:<<!
这是多行注释
!
shell变量:
变量名和等号之间不能有空格,同时,变量名的命名须遵循如下规则:
- 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头
- 中间不能有空格,可以使用下划线(_)
- 不能使用标点符号
- 不能使用bash里的关键字(可用help命令查看保留关键字)
定义变量方式一:
变量名 = 变量值
说明:变量值只能是一个整体,不能有特殊字符,适合用于数字类型的变量
定义变量方式二:
变量名 = '变量值'
说明:把单引号的内容原样的赋值给左边
定义变量方式三:
变量名 = "变量值"
说明:双引号里有其他变量,会先把变量获取出来再赋值给左边,非数字类型的变量都可以用双引号比较好
使用变量:
使用一个定义过的变量,只要在变量名前面加美元符号即可
方式一:
$变量名
# 非标准写法
方式二:
$"变量名"
# 非标准写法
方式三:
${变量名}
# 用于字符串拼接的时候使用
方式四:
$"{变量名}"
# 标准写法
编写a.sh
#!/bin/bash
# 第一行是要指定shell脚本
b = 1
echo $b
a = '2'
echo $a
a = '$b'
echo $a
c = "3"
each $c
name="itzhuzhu${c}"
echo $"{name}"
写完运行 bash a.sh
命令变量:
会先执行命令,然后把命令结果赋值赋值给变量
方式一:
变量名=`命令`
# 这个不单引号,是反引号
方式二:
变量名=$(命令)
# 尽量用这种方式,阅读性比较高
演示:
#!/bin/bash
# 第一行是要指定shell
a=`date`
echo $"{a}"
b=$(date)
echo $"{b}"
result="现在的时间是:${b}"
echo "${result}"
只读变量:
这里的只读变量其实有点类似java的final变量,即在程序的上下文中不允许被程序修改,使用
readonly
命令可以将变量定义为只读变量,只读变量的值不能被改变。
演示:
readonly result
# readonly:只读,定义了只读就不能再赋值,下面的赋值会报错
result="aaa"
删除变量:
- 使用 unset 命令可以删除变量
- 变量被删除后不能再次使用
- unset 命令不能删除只读变量。
语法:
unset variable_name
演示:
a=`date`
unset a
echo "${a}"
# 如上面的shell脚本,定义了一个a变量,通过unset删除这个变量,然后通过echo进行输出,结果是就是为空,没有任何的结果输出。
shell数组:
bash支持一维数组(不支持多维数组),并且没有限定数组的大小。定义数组在 Shell 中,用括号来表示数组,数组元素用"空格"符号分割开。
定义数组:
# 数组名=(值1 值2 …)
arr=(1 2 3 4 5)
给数组的元素赋值:
# 数组名[索引]=值
arr[0]=1
获取元素:
# $(数组名[下标])
$(arr[0])
获取长度:
# 方式一:$(#数组名[*])
$(#arr[*])
# 方式二:$(#数组名[@])
$(#arr[@])
演示:
#!/bin/bash
# 定义一个数组
arr=(a b c d)
# 给数组中的元素赋值
arr[0]=A
# 获取数组中的元素
echo ${arr[0]}
# 获取数组的长度
echo "数组的长度:${#arr[*]}"
echo "数组的长度:${#arr[@]}"
shell运算符:
- Shell 和其他编程一样,支持包括:算术、关系、布尔、字符串等运算符。
- 原生 bash **不支持 **简单的数学运算,但是可以通过其他命令来实现,例如expr。
- expr 是一款表达式计算工具,使用它能完成表达式的求值操作。
- true的结果会用0表示,false会用1表示
算数运算符:
表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2。
完整的表达式要被 ` 包含,注意不是单引号。
下表列出了常用的算术运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
---|---|---|
+ | 加法 | expr $a + $b 结果为 30。 |
- | 减法 | expr $a - $b 结果为 -10。 |
* | 乘法 | expr $a \* $b 结果为 200。 |
/ | 除法 | expr $b / $a 结果为 2。 |
% | 取余 | expr $b % $a 结果为 0。 |
= | 赋值 | a=$b 将把变量 b 的值赋给 a。 |
== | 相等。用于比较两个数字,相同则返回 true | [ $a == $b ] 返回 false。 |
!= | 不相等。用于比较两个数字,不相同则返回 true。 | [ $a != $b ] 返回 true。 |
演示:
#!/bin/bash
# 整数相加
num1=`expr 2 + 2`
echo "相加之后的结果为:$num1"
# 整数相减
num2=`expr 2 - 2`
echo "相减之后的结果为:$num2"
# 整数相乘
num3=`expr 2 \* 2`
echo "相乘之后的结果为:$num3"
# 整数相乘
num4=`expr 2 / 2`
echo "相除之后的结果为:$num4"
# 变量相加
a=10
b=20
num5=`echo $a + $b`
echo "变量a和变量b相加结果为$num5"
# 赋值
c=30
num6="${c}"
echo "变量c的值赋值给num6,打印结果为:$num6"
# 自增
d=1
((d++))
echo "变量d为1,自增后的结果为:$d"
# 自减
e=1
((e--))
echo "变量e为1,自减后的结果为:$e"
# ==
[ $a==$b ]
echo "判断两个数字是否相等,相等返回0:$?"
# !=
[ $a!=$b ]
echo "判断两个数字是否不相等,不同返回0:$?"
字符串运算符:
条件表达式要放在方括号之间,并且要有空格,例如:
[a==a==b]
是错误的,必须写成[ $a == $b ]
。
下表列出了常用的字符串运算符,假定变量 a 为 “abc”,变量 b 为 “efg”:
运算符 | 说明 | 举例 |
---|---|---|
= | 检测两个字符串是否相等,相等返回 true。 | [ $a = $b ] 返回 false。 |
!= | 检测两个字符串是否相等,不相等返回 true。 | [ $a != $b ] 返回 true。 |
-z | 检测字符串长度是否为0,为0返回 true。 | [ -z $a ] 返回 false。 |
-n | 检测字符串长度是否为0,不为0返回 true。 | [ -n “$a” ] 返回 true。 |
$ | 检测字符串是否为空,不为空返回 true。 | [ $a ] 返回 true。 |
# | 获取字符串的长度 |
演示:
#!/bin/bash
a="aaa"
b="bbb"
# 判断两个字符串是否相等
# $?:可以获取上一条语句的执行结果
[ "${a}"="${b}" ]
echo "判断两个字符串是否相等,0为真,1为假:$?"
# 判断两个字符串是否不相等
[ "${a}"!="${b}" ]
echo "判断两个字符串是否不相等,0为真,1为假:$?"
# 判断字符串的长度是否为0
[ -z "${a}" ]
echo "判断字符串的长度是否为0,0为真,1为假:$?"
# 判断字符串的长度是否不为0
[ -n "${a}" ]
echo "判断字符串的长度是否不为0,0为真,1为假:$?"
# 判断字符串是否为空
[ $"${a}" ]
echo "判断字符串是否为空,不为空返回0,为空返回1:$?"
# 获取字符串的长度
echo "返回字符串的长度:${#a}"
关系运算符:
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
---|---|---|
-eq | 检测两个数是否相等,相等返回 true。 | [ $a -eq $b ] 返回 false。 |
-ne | 检测两个数是否不相等,不相等返回 true。 | [ $a -ne $b ] 返回 true。 |
-gt | 检测左边的数是否大于右边的,如果是,则返回 true。 | [ $a -gt $b ] 返回 false。 |
-lt | 检测左边的数是否小于右边的,如果是,则返回 true。 | [ $a -lt $b ] 返回 true。 |
-ge | 检测左边的数是否大于等于右边的,如果是,则返回 true。 | [ $a -ge $b ] 返回 false。 |
-le | 检测左边的数是否小于等于右边的,如果是,则返回 true。 | [ $a -le $b ] 返回 true。 |
演示:
#!/bin/bash
a=10
b=20
[ $a -eq $b ]
echo "判断两个变量是否相等$?"
[ $a -ne $b ]
echo "判断两个变量是否不相等$?"
[ $a -gt $b ]
echo "判断左边的数是否大于右边$?"
[ $a -lt $b ]
echo "判断左边的数是否小于右边$?"
[ $a -ge $b ]
echo "判断左边的数是否大于等于右边$?"
[ $a -le $b ]
echo "判断左边的数是否小于等于右边$?"
布尔运算符:
下表列出了常用的布尔运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
---|---|---|
! | 非运算,表达式为 true 则返回 false,否则返回 true。 | [ ! false ] 返回 true。 |
-o | 或运算,有一个表达式为 true 则返回 true。 | [ $a -lt 20 -o $b -gt 100 ] 返回 true。 |
-a | 与运算,两个表达式都为 true 才返回 true。 | [ $a -lt 20 -a $b -gt 100 ] 返回 false。 |
演示:
#!/bin/bash
a=10
b=20
# 取反
[ ! "$a" -eq 10 ]
echo "获取判断之后的结果$?"
# 或运算
# 解释:a < 20 或 b > 100
[ "${a}" -lt 20 -o "${b}" -gt 100 ]
echo "或运算的结果为:$?"
# 与运算
# 解释:a < 20 且 b > 100
[ "${a}" -lt 20 -a "${b}" -gt 100 ]
echo "与运算的结果为:$?"
逻辑运算符:
假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
---|---|---|
&& | 逻辑的 AND | [[ $a -lt 100 && $b -gt 100 ]] 返回 false |
|| | 逻辑的 OR | [[ $a -lt 100 || $b -gt 100 ]] 返回 true |
演示:
#!/bin/bash
a=10
b=20
# a < 100 && b > 100
[[ "${a}" -lt 100 && "${b}" -gt 100 ]]
echo "&&运算后的结果为:$?"
# a < 100 || b > 100
[[ "${a}" -lt 100 || "${b}" -gt 100 ]]
echo "||运算后的结果为:$?"
shell流程控制:
在shell编程中,有和java中流程控制一样的作用,只是语法和java SE有所区别,但是目的是一样的。
if 语句:
主要用于判断,相当于java se中的if
then:符合条件执行
fi:结束标记
格式:
if [条件]
then
语句体
fi
演示:
# 查找一个进程如果这个进程存在就打印true
if [ $(ps -ef | grep -c "ssh") -gt 1 ]
then
echo "true"
fi
if else 语句:
主要用于判断,相当于java se中的if else
else:不满足条件执行的语句
格式:
if [条件]
then
语句体
else
语句体
fi
演示:
# 查找一个进程如果这个进程存在就打印true,否则打印false
if [ $(ps -ef | grep -c "ssh") -gt 1 ]
then
echo "true"
else
echo "false"
fi
if else-if else 语句:
主要用于判断,相当于java se中的if else-if else
格式:
if [条件1]
then
语句体
elif [条件2]
语句体
else
语句体
fi
演示:
# 定义a和b两个变量,对于大于等于小于提示不同内容
a=10
b=20
if [ "${a}" -eq "${b}" ]
then
echo "相等"
elif [ "${a} -lt ${b}" ]
then
echo "a小于b"
else
echo "a大于b"
fi
for 循环:
主要用于循环,相当于java se中的for循环
do:固定格式表示走循环体
done:结束标记
格式:
for 变量 in 范围
do
循环体
done
演示:
# 顺序输出当前列表中的字母
# loop就是一个初始变量,会依次执行范围然后走循环体,走完就结束
for loop in A B C D E F G
do
echo "顺序输出字母为: $loop"
done
while循环:
主要用于循环,相当于java se中的while循环,while循环用于不断执行一系列命令,也用于从输入文件中读取数据
格式:
while 条件
do
循环体
done
演示:
# 定义一个变量为1,判断如果1小于等于10就会输出当前i的值,然后i做++,直到i的值大于10才结束
i=1
while(( $i<=10 ))
do
echo "${i}"
((i++))
done
case ... esac语句:
主要用于分支条件选择,相当于java se中的switch case循环
case … esac与其他语言中的 switch … case 语句类似,是一种多分枝选择结构,每个 case 分支用右圆括号开始,用两个分号;;
表示 break,即执行结束,跳出整个 case … esac 语句,esac(就是 case 反过来)作为结束标记。
格式:
case 值 in
模式1)
语句体1
;;
模式2)
语句体2
;;
esac
演示:
v="itzhuzhu"
case "$v" in
"itzhuzhu")
echo "帅的一批"
;;
"baidu")
echo "baidu 搜索"
;;
"google")
echo "google 搜索"
;;
esac
shell函数:
- 可以使用function fun() 定义函数,也可以直接fun() 定义,不带任何参数。
- 函数参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255
- 调用方法直接写方法名就可以了
无参无返回值:
格式:
函数名 (){
函数体
}
演示:
#!/bin/bash
method(){
echo "函数执行了!"
}
echo "-----这里是函数开始执行-----"
method
echo "-----这里是函数执行完毕-----"
有参无返回值:
格式:
函数名 (){
函数体
}
# 调用
函数名 参数1 参数2
演示:
#!/bin/bash
# 传递的两个变量a和b依次被echo接收,先是把a给第一个参数,再把b给第二个参数
method2(){
echo "接收到的第一个参数$1"
echo "接收到的第二个参数$2"
}
method2 a b
有参有返回值:
函数返回值在调用该函数后通过 $? 来获得。
注意:所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。
read:键盘录入
function method3(){
echo "对输入的两个数字进行相加运算..."
echo "输入第一个数字: "
read aNum
echo "输入第二个数字: "
read anotherNum
echo "两个数字分别为 $aNum 和 $anotherNum !"
return $(($aNum+$anotherNum))
}
method3
echo "输入的两个数字之和为 $? !"