Shell
什么是Shell
Shell是一个下令行解释器,它接收应用程序/用户下令,然后调用操纵系统内核
Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁
Shell还是一个功能相称强大的编程语言,易编写、易调试、灵活性强。
Shell 编程跟 java、php 编程一样,只要有一个能编写代码的文本编辑器和一个能解释执行的脚本解释器就可以了
入门
Linux 的 Shell 种类众多,常见的有:cat /etc/shells
<img alt="" loading="lazy">
Bash由于易用和免费,Bash 在日常工作中被广泛使用。同时,Bash 也是大多数 Linux 系统默认的 Shell。
echo $SHELL
输出默认shell
脚本以#!/bin/bash 开头(指定解析器)
案例
vim helloworld.sh 在 helloworld.sh 中输入如下内容- #!/bin/bash
- echo "helloworld"
复制代码 "#!" 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,纵然用哪一种 Shell
脚本的常用执行方式
第一种:采用 bash 或 sh+脚本的相对路径或绝对路径(不消赋予脚本+x 权限)
(1)sh+脚本的相对路径。sh ./helloworld.sh
helloworld
(2)sh+脚本的绝对路径。 sh /home/atguigu/helloworld.sh
helloworld
(3)bash+脚本的相对路径。 bash ./helloworld.sh
helloworld
(4)bash+脚本的绝对路径。 bash /home/atguigu/helloworld.sh
helloworld- 注意,一定要写成 ./test.sh ,而不是 test.sh ,运行其它二进制的程序也一样,直接写 test.sh ,linux 系统会去 PATH 里寻找有没有叫 test.sh 的,而只有 /bin, /sbin, /usr/bin,/usr/sbin 等在 PATH 里,你的当前目录通常不在 PATH里,所以写成 test.sh 是会找不到命令的,要用 ./test.sh 告诉系统说,就在当前目录找。
复制代码 第二种:采用输入脚本的绝对路径或相对路径执行脚本(必须具有可执行权限+x)
(1)首先要赋予 helloworld.sh 脚本的+x 权限 chmod +x helloworld.sh
(2)执行脚本
① 相对路径。 ./helloworld.sh
helloworld
② 绝对路径。 /home/atguigu/helloworld.sh
helloworld
留意:第一种执行方法,本质是 bash 解析器帮你执行脚本,以是脚本本身不需要执行 权限。
第二种执行方法,本质是脚本需要本身执行,以是需要执行权限。
变量
语法:$变量名
$和变量名之间不能有空格。
echo $HOME 检察系统变量的值
表现当前Shell中所有的变量 env/set
自定义变量
语法
(1)定义变量:变量名=变量值,留意,=号前后不能有空格。
(2)打消变量:unset 变量名。
(3)声明静态变量:readonly 变量,留意:不能 unset。
定义规则
(1)变量名称可以由字母、数字和下划线组成,但是不能以数字开头,情况变量名建 议大写。
(2)等号两侧不能有空格。
(3)在 bash 中,变量默认范例都是字符串范例,无法直接举行数值运算。
(4)变量的值假如有空格,需要使用双引号或单引号括起来。
案例实操
1 定义变量A
A=5
echo $A
2 给A重新赋值
A=8
echo $A
3 打消变量A
unset A
4 声明静态的变量B
readonly B=2
echo $B
设定好就修改不了
5 在bash中变量默认的范例都是字符串范例,无法直接举行数值运算
C=1+2
echo $C
6 变量的值假如有空格,需要用双引号或单引号括起来
如
D="I love banzhang"
echo $D
7 可把变量提升为全局情况变量
export B
在helloworld.sh中参加 echo $B
打印输出
./helloworld.sh
特殊变量
$n
(功能描述:n 为数字,$0 代表该脚本名称,$1-$9 代表第一到第九个参数,十以上 的参数需要用大括号包罗,如${10}。)
案例实操
vim parameter.sh- #!/bin/bash
- echo '==========$n=========='
- echo $0
- echo $1
- echo $2
复制代码 chmod 777 parameter.sh- ./parameter.sh cls xz
- ==========$n==========
- ./parameter
- .sh
- cls
复制代码 $#
(功能描述:获取所有输入参数个数,常用于循环,判断参数的个数是否精确)
在上述parameter.sh后面参加 $#
$*$@
$* (功能描述:这个变量代表下令行中所有的参数,$*把所有的参数看成一个团体。)
$@ (功能描述:这个变量也代表下令行中所有的参数,不外$@把每个参数区分对待。)
在上述parameter.sh后面参加 $*$@
echo $* $@
$*和$@的区别需要结合循环说明- 相同点:都是引用所有参数。
- 不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 1、2、3,,则 " * " 等价于 "1 2 3"(传递了一个参数),而 "@" 等价于 "1" "2" "3"(传递了三个参数)
复制代码 $?
(功能描述:末了一次执行的下令的返回状态。假如这个变量的值为 0,证明上一个 下令精确执行;假如这个变量的值为非 0(具体是哪个数,由下令本身来决定),则证明 上一个下令执行不精确了。)
执行上述脚本parameter.sh
输入echo $? 判断脚本是否精确的执行- atguigu@ubuntu:~$ ./helloworld.sh
- hello world
- atguigu@ubuntu:~$ echo $?
- 0
复制代码 运算符
Shell 和其他编程语言一样,支持多种运算符,包括:
- 算数运算符
- 关系运算符
- 布尔运算符
- 字符串运算符
- 文件测试运算符
根本语法
test condition
[ condition ](留意 condition 前后要有空格)
留意:条件非空即为 true,[ atguigu ]返回 true,[ ] 返回 false。
有两个 1是用test来举行测试 2 是用[ ]来举行测试 没有返回结果值 需要输入$? 来看结果对不对
1 算术运算符
下表列出了常用的算术运算符,假定变量 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。留意:条件表达式要放在方括号之间,而且要有空格,例如: [$a==$b] 是错误的,必须写成 [ $a == $b ]。
乘号(*)前边必须加反斜杠()才气实现乘法运算- "$((运算式))" 或 "$[运算式]"
- 1)计算(2+3)* 4 的值
- (1)$[]
- atguigu@ubuntu:~$ S=$[(2+3)*4]
- atguigu@ubuntu:~$ echo $S
- (2)$(())
- atguigu@ubuntu:~$ unset S
- atguigu@ubuntu:~$ S=$(((2+3)*4))
- atguigu@ubuntu:~$ echo $S
- 20
复制代码 2 关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
下表列出了常用的关系运算符,假定变量 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。- (1)判断23 是否大于等于 22
- 1 test
- test 23 -ge 22
- echo $? 0
- 2 [ condition ]
- [ 23 -ge 22 ]
- echo $?
- 0
复制代码 3 布尔运算符
下表列出了常用的布尔运算符,假定变量 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。4 逻辑运算符
以下介绍 Shell 的逻辑运算符,假定变量 a 为 10,变量 b 为 20:
运算符说明举例&&逻辑的 AND[[ $a -lt 100 && $b -gt 100 ]] 返回 false||逻辑的 OR[[ $a -lt 100 || $b -gt 100 ]] 返回 true- 多条件判断(&& 表示前一条命令执行成功时,才执行后一条命令,|| 表示上一条命令 执行失败后,才执行下一条命令)
- 1 testcondition
- test atguigu && echo OK || echo notOK OK
- test && echo OK || echo notOK notOK
- 2 [ condition ]
- [ atguigu ] && echo OK || echo notOK OK
- [ ] && echo OK || echo notOK notOK
复制代码 4 字符串运算符
下表列出了常用的字符串运算符,假定变量 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。str检测字符串是否为空,不为空返回 true。[ $a ] 返回 true。5 文件测试运算符
按照文件范例举行判断
- -e 文件存在(existence)
- -f 文件存在而且是一个通例的文件(file)
- -d 文件存在而且是一个目次(directory)
- 3)/home/atguigu/cls.txt 目录中的文件是否存在
- 1 test condition
- test -e /home/atguigu/cls.txt
- echo
- $?
- 1
- 2
- [ condition ]
- [ -e /home/atguigu/cls.txt ]
- echo $?
- 1
复制代码 6 文件的权限
按照文件权限举行判断 -r 有读的权限(read) -w 有写的权限(write) -x 有执行的权限(execute)- helloworld.sh 是否具有写权限
- 1 test
- -w helloworld.sh
- echo $?
- 0
- 2 [ condition ]
- [ -w helloworld.sh ]
- echo $?
- 0
复制代码 流程控制
if
if 判断
根本语法- (1)单分支 if [ 条件判断式 ];then
- 程序 fi
- 或者 if [ 条件判断式 ]
- then
- fi
- (2)多分支
- if [ 条件判断式 ]
- then
- 程序
- elif [ 条件判断式 ]
- then
- 程序
- else 程序
- fi
复制代码 留意事项: ① [ 条件判断式 ],中括号和条件判断式之间必须有空格 ② if 后要有空格
案例实操 输入一个数字,假如是 1,则输出 banzhang zhen shuai,假如是 2,则输出 cls zhen mei, 假如是其它,什么也不输出。
vim if.sh 写入以下内容- #!/bin/bash
- if [ $1 -eq 1 ]
- then
- echo "banzhang zhen shuai"
- elif [ $1 -eq 2 ]
- then
- echo "cls zhen mei"
- fi
复制代码- chmod 777 if.sh
- ./if.sh 1
- banzhang zhen shuai
- ./if.sh 2
- cls zhen mei
复制代码 case
case $变量名 in- "值 1")
- 如果变量的值等于值 1,则执行程序 1
- ;;
- "值 2")
- 如果变量的值等于值 2,则执行程序 2
- ;;
- …省略其他分支
- *)
- 如果变量的值都不是以上的值,则执行此程序 ;;
- esac
复制代码 留意事项:
(1)case 行尾必须为单词“in”,每一个模式匹配必须以右括号“)”结束。
(2)双分号“;;”表示下令序列结束,相称于 C 中的 break。
(3)末了的“)”表示默认模式,相称于 C 中的 default。
案例
输入一个数字,假如是 1,则输出 banzhang,假如是 2,则输出 cls,假如是其它,输出 renyao。 vim case.sh- #!/bin/bash
- case $1 in
- "1")
- echo "banzhang"
- ;;
- "2")
- echo "cls"
- ;;
- *)
- echo "renyao"
- ;;
- esac
复制代码 chmod 777 case.sh
./case.sh 1
./case.sh 2
./case.sh 3
**fore **
1 for ((初始值;循环控制条件;变量变革))
do 程序
done
vim for1.sh
[code]#!/bin/bashsum=0for((i=0;i |