Shell笔记
文章目录
- 0 前言
- 1 概述
- 1.1 查看系统支持的Shell解析器
- 1.2 bash与shell关系
- 1.3 CentOs系统的默认解析器是Bash:
- 2 Shell脚本入门
- 2.1 脚本格式
- 2.2 创建第一个脚本:HelloWorld
- 2.3 执行脚本
- bash / sh 执行脚本
- 直接输入脚本位置
- source / 。
- 3. Shell变量
- 3.1 基本语法
- 1 定义 重新赋值 打印 撤销
- 2 显示所有变量 set
- 3 定义全局变量 explort
- 4 声名静态变量 readonly
- 3.2 特殊变量
- $n 位置参数
- $#
- $* $@
- $?
- 4 运算符
- 4.1 基本语法
- 4.2 使用expr + 符号 测试
- 4.3 使用 $(()) , $[] 测试
- 4.4 expr 使用转义方式赋值
- 4.5 计算(2+3)X4的值
- 5 条件判断
- 5.1 条件判断前置知识
- 不使用脚本,使用$?获取test命令测试值
- 使用[[]] 注意:没有$
- 拓展
- 5.2 常用判断条件
- 两个整数之间比较
- 按照文件权限进行判断
- 按照文件类型进行判断
- 5.3 多条件组合判断
- 6 流程控制
- 6.1 if
- 基本语法
- 测试:不用脚本
- 测试:简单脚本
- 测试:条件判断+基本运算符
- 测试 if else
- 6.2 case
- 基本语法
- 测试
- 6.3 for循环
- 基本语法
- 测试
- ==补充(()) ,{}==
- 测试
- ==补充$* , $@*==
- 6.4 while循环
- 基本语法
- 测试
- 7 read 读取控制台输入
- 7.1 基本语法
- 7.2 read测试
- 8 函数
- 8.1 系统函数
- 小demo
- basename 获取文件名
- 测试
- dirname 获得路径名
- 测试
- 8.2 自定义函数
- 基本语法
- 测试
- 9 正则表达式
- 10 文本处理工具
- 11 综合应用案例
- 11.1 归档文件
- 需求
- 实现
0 前言
1 参考网站:Shell菜鸟教程:https://www.runoob.com/linux/linux-shell.html
2 参考笔记:尚硅谷课上文档:https://pan.baidu.com/s/1_nBKUjE57MB2c96wmfSD5A 提取码:yyds
3 学习视频:B站尚硅谷:https://www.bilibili.com/video/BV1WY4y1H7d3?p=66
Shell是 Linux总要组成部分,学习 Shell需要掌握 Linux基础知识。
这篇笔记是跟随B站尚硅谷课程学习,结合课上文档整理与自我总结总结而来。
与课上文档相比,删减浓缩了些废话,增添了些扩展知识,保持了课上文档的大体结构。
所有代码全部手敲运行过,相信你遇到的坑我都踩过,欢迎纠错。
1 概述
-
Shell 是一个命令行解释器,接受用户与程序的命令,然后调用系统内核
-
Shell 也是一个功能强大的编程语言,容易编写,调试,灵活。
-
C语言编写,可以编写脚本,Shell是弱语言类型。
1.1 查看系统支持的Shell解析器
[root@abc:~]# cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/sh
/usr/bin/bash
本质是查看/etc/shells这个文件里的内容
1.2 bash与shell关系
[root@abc:~]# cd /bin
[root@abc:/bin]# ll | grep bash
-rwxr-xr-x 1 root root 964536 Nov 25 2021 bash
lrwxrwxrwx 1 root root 10 Apr 26 10:40 bashbug -> bashbug-64
-rwxr-xr-x 1 root root 6964 Nov 25 2021 bashbug-64
lrwxrwxrwx 1 root root 4 Apr 26 10:40 sh -> bash
由此可得,上面/bin/sh 与 /bin/bash其实是一样的。
1.3 CentOs系统的默认解析器是Bash:
[root@abc:/bin]# echo $SHELL
/bin/bash
CentOs系统的默认解析器是Bash
2 Shell脚本入门
2.1 脚本格式
- 脚本以 #!/bin/bash 开头
#! 是一个约定的标记,它告诉系统这个脚本需要什么解释器来执行,即使用哪一种 Shell。
2.2 创建第一个脚本:HelloWorld
# 创建一个文件夹,防止混乱,位置随意
[root@abc:~/shell]# pwd
/root/shell
# .sh后缀不是强制的,约定俗成,可以不写,自己看懂就行。
[root@abc:~/shell]# touch helloworld.sh
[root@abc:~/shell]# vim helloworld.sh
[root@abc:~/shell]# cat helloworld.sh
#!/bin/bash
echo "Hello world" # 使用echo输出
2.3 执行脚本
bash / sh 执行脚本
[root@abc:~/shell]# bash helloworld.sh
Hello world
[root@abc:/]# bash /root/shell/helloworld.sh
Hello world
[root@abc:~/shell]# sh helloworld.sh
Hello world
直接输入脚本位置
[root@abc:~/shell]# pwd
/root/shell
[root@abc:~/shell]# ll
total 4
-rw-r--r-- 1 root root 32 Jun 8 14:51 helloworld.sh
[root@abc:~/shell]# /root/shell/helloworld.sh
-bash: /root/shell/helloworld.sh: Permission denied
这里报错提示权限不够,因为没有操作权限
[root@abc:~/shell]# chmod 777 helloworld.sh
[root@abc:~/shell]# /root/shell/helloworld.sh
Hello world
source / 。
这两种方式是通过主shell执行,而不是子shell,看不到子shell的环境变量
[root@abc:~/shell]# source helloworld.sh
Hello world
[root@abc:~/shell]# . helloworld.sh
Hello world
-----------------------------------------------------------------------
这个比较特殊,命令只有一个".",后面空格+脚本名称即可,
"."是一种命令。
3. Shell变量
3.1 基本语法
- 定义变量:变量=值
- 撤销变量:unset 变量
- 声明静态变量:readonly 变量,注意:不能unset
- 变量规则与Java类似,字母数字下划线开头,不能使用系统变量。
- 定义变量时,变量名前不加$ num=123 ,使用变量时需要加上$ echo $num
- 常用系统变量 HOME、PWD、SHELL、USER等
- 显示所有变量 set
- 定义全局变量 export num1=123
- 变量名称可以由字母、数字和下划线组成,但是不能以数字开头,环境变量名建议大写。
- 在bash中,变量默认类型都是字符串类型,无法直接进行数值运算。
- 变量的值如果有空格,需要使用双引号或单引号括起来。
- 默认的定义是字符串 $((运算式))才可以计算数字
- 变量是临时存贮在内存中的,关掉终端就没有了
1 定义 重新赋值 打印 撤销
[root@abc:~/shell]# a=123 定义不用$
[root@abc:~/shell]# echo $a 打印需要$
123
[root@abc:~/shell]# clear
[root@abc:~/shell]# echo $num1
这里是空的,说明没有
[root@abc:~/shell]# num1=123
[root@abc:~/shell]# echo $num1
123
[root@abc:~/shell]# num1=123456
[root@abc:~/shell]# echo $num1
123456
[root@abc:~]# num1=1
[root@abc:~]# echo $num1
1
[root@abc:~]# unset num1
[root@abc:~]# echo $num1
2 显示所有变量 set
[root@abc:~/shell]# set
BASH=/bin/bash
……………………中间有很多,省略,按照首字母顺序排列的。
a=123
colors=/root/.dircolors
num1=123456
----------------------------------
显示指定变量
[root@abc:~/shell]# set | grep num1
num1=123456
3 定义全局变量 explort
[root@abc:~]# export num2=2
[root@abc:~]# echo $num2
2
父shell创建的全局变量子shell可以访问到,但是子shell创建的变量父shell不可以
类似java的值传递一样,子shell的作用范围是局部的。
[root@abc:~/shell]# cat hello.sh
#!/bin/bash
echo "This is HelloWorld"
echo $num1
echo $num2
[root@abc:~/shell]# . hello.sh
This is HelloWorld
# 这里没有打印时因为系统中没有变量,打印个吉尔。
[root@abc:~/shell]# num1=1
[root@abc:~/shell]# . hello.sh
This is HelloWorld
1
4 声名静态变量 readonly
readonly num1=1;
不可修改,不可删除
3.2 特殊变量
$n 位置参数
1、基本语法
$n (功能描述:n 为数字,$0 代表该脚本名称,$1- 9 代表第一到第九个参数,十以上的参数,十以上的参数需要用大括号包含,如 9 代表第一到第九个参数,十以上的参数,十以上的参数需要用大括号包含,如 9代表第一到第九个参数,十以上的参数,十以上的参数需要用大括号包含,如{10})
2、案例实操
(1)输出该脚本文件名称、输入参数1和输入参数2 的值
[root@abc:~/shell]# cat special1.sh
#!/bin/bash
echo "Li Ming"
echo "Hello,I am $1"
[root@abc:~/shell]# . special1.sh
Li Ming
Hello,I am
[root@abc:~/shell]# . special1.sh name1 name2
Li Ming
Hello,I am name1
[root@abc:~/shell]# cat special1.sh
#!/bin/bash
echo "Li Ming" 普通打印
echo "Hello,I am $1" 双引号内打印
echo "====$1===="
echo '====S1====' 单引号之内无法识别
echo script name $0 打印
echo "脚本名称:"$0
echo 1st paramater:$1
[root@abc:~/shell]# . special1.sh 111 223
Li Ming
Hello,I am 111
====111====
====S1====
script name -bash 这里查询不到名称时因为使用的时. 启动,实在主shell中启动的
脚本名称:-bash
1st paramater:111
[root@abc:~/shell]# ./test.sh
Li Ming
Hello,I am
========
====S1====
script name ./test.sh
脚本名称:./test.sh
1st paramater:
$#
1、基本语法
$# (功能描述:获取所有输入参数个数,常用于循环)
2、案例实操
(1)获取输入参数的个数
[root@abc:~/shell]# cat test.sh
#!/bin/bash
echo "==$#=="
[root@abc:~/shell]# ./test.sh 11 222
==2==
$* $@
1、基本语法
-
功能描述:这个变量代表命令行中所有的参数,*把所有的参数看成一个整体
-
功能描述:这个变量也代表命令行中所有的参数,不过@把每个参数区分对待
2、案例实操
(1)打印输入的所有参数
[root@abc:~/shell]# cat test.sh
#!/bin/bash
echo "==$*=="
echo "==$@=="
[root@abc:~/shell]# ./test.sh 11 222
==11 222==
==11 222==
$?
1、基本语法
$?: (功能描述:最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值为非0(具体是哪个数,由命令自己来决定),则证明上一个命令执行不正确了。)
2、案例实操
(1)判断helloworld.sh脚本是否正确执行
[root@abc:~/shell]# ./test.sh
Li Ming
Hello,I am
========
====S1====
script name ./test.sh
脚本名称:./test.sh
1st paramater:
==0==
====
====
[root@abc:~/shell]# echo $?
0 0代表执行成功,无错误
[root@abc:~/shell]# ./sadsdsadas 这是胡乱说输入的
-bash: ./sadsdsadas: No such file or directory
[root@abc:~/shell]# echo $?
127 127代表出错,找不到
4 运算符
4.1 基本语法
(1)((运算式))”或“[运算式]”
(2)expr + , - , *, /, % 加,减,乘,除,取余
注意:expr运算符间要有空格
4.2 使用expr + 符号 测试
[root@abc:~/shell]# expr 1+2 加号之间需要空格
1+2
[root@abc:~/shell]# expr 2 + 4
6
[root@abc:~/shell]# expr 2 - 4
-2
[root@abc:~/shell]# expr 2 * 4 Linux中*代表特殊意思
expr: syntax error
[root@abc:~/shell]# expr 2 \* 4 使用\*进行转义
8
[root@abc:~/shell]# expr 2 / 4 像Java一样只保留整数
0
[root@abc:~/shell]# expr 4 / 2
2
[root@abc:~/shell]# expr 4 % 2
0
[root@abc:~/shell]# expr 3 % 2
1
4.3 使用 $(()) , $[] 测试
[root@abc:~/shell]# echo $[1+2]
3
[root@abc:~/shell]# echo $[1*2]
2
[root@abc:~/shell]# echo $((1+3*3))
10
4.4 expr 使用转义方式赋值
方式1:
[root@abc:~/shell]# a=$((1+2))
[root@abc:~/shell]# echo $a
3
-----------------------------------------------------------------
方式2:
[root@abc:~/shell]# a=`expr 1 + 1` 注意这不是单引号,是TM主键盘区第一个按键,也就是间隔号,Tab键上面的哪个键
[root@abc:~/shell]# echo $a
2
4.5 计算(2+3)X4的值
- expr一步完成计算
$ expr `expr 2 + 3` \* 4
20
- 采用$[运算式]方式
S=$[(2+3)*4]
echo $S
- 脚本方式
[root@abc:~/shell]# vim 123.sh
[root@abc:~/shell]# cat 123.sh
#!/bin/bash
num1=$[$1+$2]
num2=$(($1+$2))
#num3=expr $1 + $2
num4=$[($1+$2)*$3]
num5=$((($1+$2)*$3))
#num6=expr `expr $1 + $2` \* $3
# 开始打印
echo num1=$num1
echo num2=$num2
echo num4=$num4
echo num5=$num5
[root@abc:~/shell]# ./123.sh 1 2 3
num1=3
num2=3
num4=9
num5=9
5 条件判断
5.1 条件判断前置知识
不使用脚本,使用$?获取test命令测试值
[root@abc:~/shell]# a=123
[root@abc:~/shell]# echo $a
123
[root@abc:~/shell]# test $a = 123
[root@abc:~/shell]# echo $?
0 测试通过时候显示0
[root@abc:~/shell]# test $a = 1234
[root@abc:~/shell]# echo $?
1 测试失败时候显示1
使用[[]] 注意:没有$
[root@abc:~/shell]# a=123
[root@abc:~/shell]# [ $a=123 ] =无空格
[root@abc:~/shell]# echo $?
0
[root@abc:~/shell]# [ $a=1234 ] =无空格
[root@abc:~/shell]# echo $?
0
[root@abc:~/shell]# [ $a = 123 ] =有空格
[root@abc:~/shell]# echo $?
0
[root@abc:~/shell]# [ $a = 1234 ] =有空格
[root@abc:~/shell]# echo $?
1
要求:
1. [ XXX ]中括号里面,表达式的两边必须有空格;即XXX两边必须有空格
2. 等号两边必须空格
拓展
- 如果没有东西的话,$?=1 ,有东西,且东西不是表达式 $?=0,可用来判断是否非空
- 判断A=B : [ A = B ],这里是因为吧A B当作字符串处理了
5.2 常用判断条件
两个整数之间比较
= 字符串比较
-
-lt 小于(less than)
-
-le 小于等于(less equal)
-
-eq 等于(equal)
-
-gt 大于(greater than)
-
-ge 大于等于(greater equal)
-
-ne 不等于(Not equal)
[root@abc:~/shell]# a=123
[root@abc:~/shell]# echo [ 1 + 1 ]
[ 1 + 1 ]
[root@abc:~/shell]# echo $[1 + 1]
2
[root@abc:~/shell]# echo $?
0
[root@abc:~/shell]# echo $[a=123]
123
[root@abc:~/shell]# echo $?
0
[root@abc:~/shell]# echo $[a=1234]
1234
[root@abc:~/shell]# echo $?
0
[root@abc:~/shell]# echo $a
1234
[root@abc:~/shell]# echo $[$a=1234]
-bash: 1234=1234: attempted assignment to non-variable (error token is "=1234")
[root@abc:~/shell]# echo $[ $a = 1234 ]
-bash: 1234 = 1234 : attempted assignment to non-variable (error token is "= 1234 ")
[root@abc:~/shell]# echo [ $a = 1234 ]
[ 1234 = 1234 ]
[root@abc:~/shell]# echo $?
0
[root@abc:~/shell]# [ 123 -lt 124 ]
[root@abc:~/shell]# echo $?
0
[root@abc:~/shell]# [ 125 -lt 124 ]
[root@abc:~/shell]# echo $?
1
[root@abc:~/shell]# [ 125 -gt 124 ]
[root@abc:~/shell]# echo $?
0
[root@abc:~/shell]# [ 125 -le 124 ]
[root@abc:~/shell]# echo $?
1
[root@abc:~/shell]# [ 125 -ge 124 ]
[root@abc:~/shell]#
[root@abc:~/shell]# echo $?
0
按照文件权限进行判断
- -r 有读的权限(read)
- -w 有写的权限(write)
- -x 有执行的权限(execute)
[root@abc:~/shell]# ll
total 20
-rwxrwxrwx 1 root root 214 Jun 9 16:44 123.sh
[root@abc:~/shell]# [ -r hello.sh ]
[root@abc:~/shell]# echo $?
0
[root@abc:~/shell]# [ -w hello.sh ]
[root@abc:~/shell]# echo $?
0
[root@abc:~/shell]# [ -x hello.sh ]
[root@abc:~/shell]# echo $?
1
按照文件类型进行判断
-
-f 文件存在并且是一个常规的文件(file)
-
-e 文件存在(existence)
-
-d 文件存在并是一个目录(directory)
[root@abc:~/shell]# ll
total 20
-rwxrwxrwx 1 root root 214 Jun 9 16:44 123.sh
-rw-r--r-- 1 root root 62 Jun 8 16:25 hello.sh
-rw-r--r-- 1 root root 149 Jun 8 16:49 special1.sh
-rwxrwxrwx 1 root root 75 Jun 9 09:36 test2.sh
-rwxrwxrwx 1 root root 193 Jun 9 15:32 test.sh
[root@abc:~/shell]# [ -e 123.sh ]
[root@abc:~/shell]# echo $?
0
[root@abc:~/shell]# [ -e 1234.sh ]
[root@abc:~/shell]# echo $?
1
[root@abc:~/shell]# [ -f hello.sh ]
[root@abc:~/shell]# echo $?
0
[root@abc:~/shell]# [ -f hello123.sh ]
[root@abc:~/shell]# echo $?
1
[root@abc:~/shell]# [ -d hello.sh ]
[root@abc:~/shell]# echo $?
1
[root@abc:~/shell]# mkdir dir1
[root@abc:~/shell]# [ -d dir1 ]
[root@abc:~/shell]# echo $?
0
5.3 多条件组合判断
-
&& 表示前一条命令执行成功时,才执行后一条命令
-
|| 表示上一条命令执行失败后,才执行下一条命令
[root@abc:~/shell]# a=123
[root@abc:~/shell]# [ $a -eq 1234 ] && echo $a || a=123 && echo $a
123
[root@abc:~/shell]# [ $a -eq 1234 ] && echo yes || a=123 && echo stillyes
stillyes
6 流程控制
6.1 if
基本语法
# (1)单分支
if [ 条件判断式 ];then ;代表一行中多行命令的分隔符
程序 then代表 { } (大括号)的意思
fi
或者
if [ 条件判断式 ]
then
程序
fi
# (2)多分支
if [ 条件判断式 ]
then
程序
elif [ 条件判断式 ];then
程序
elif [ 条件判断式 ]
then
程序
else
程序
fi
测试:不用脚本
[root@abc:~]# if [ $a -gt 100 ] ; then echo "a>" ; fi
a>
-----------------------------------------------------------2.
[root@abc:~/shell]# echo $a
8
[root@abc:~/shell]# if [ $a -ge 100 ]
> then
> echo "100"
> elif [ $a -ge 10 ];then echo "10"
> elif [ $a -eq 8 ]
> then echo "8"
> else echo "0" ;fi
8
----------------------------
1. 一行多命令,";"是分隔符
2. 条件判断的中括号之前与";"之间可以有空格。
3. then必须有,不可省略
测试:简单脚本
未优化版
[root@abc:~/shell]# cat if.sh
#!/bin/bash
if [ $1 = LiMing ]
then
echo "welcome LiMing"
else
echo "welcome $1"
fi
[root@abc:~/shell]# ./if.sh LiMing
welcome LiMing
[root@abc:~/shell]# ./if.sh Li
welcome Li
[root@abc:~/shell]# ./if.sh 这里会报错是因为没有输入参数,下面测试代码不会引起此报错
./if.sh: line 3: [: =: unary operator expected
welcome
--------------------------------------------------------
优化版
[root@abc:~/shell]# cat if.sh
#!/bin/bash
if [ "$1"x = "LiMing"x ] 注意这里参数被“”括起来了,后面有个字符X
then
echo "welcome LiMing"
else
echo "welcome $1"
fi
[root@abc:~/shell]# ./if.sh
welcome
测试:条件判断+基本运算符
注意:这里的条件判断里面用的是两个中括号,中间是运算符
if [ $a -ge 18 ] && [ $a -le 35 ] ; then echo ok ; else echo notok ;fi
notok
[root@abc:~/shell]# a=19
if [ $a -ge 18 ] && [ $a -le 35 ] ; then echo ok ; else echo notok ;fi
ok
[root@abc:~/shell]# a=35
if [ $a -ge 18 ] && [ $a -le 35 ] ; then echo ok ; else echo notok ;fi
ok
[root@abc:~/shell]# a=36
if [ $a -ge 18 ] && [ $a -le 35 ] ; then echo ok ; else echo notok ;fi
notok
-------------------------------------------------------------------------
注意:这里的条件判断里面只有一个中括号,运算符用参数来代替了
&& -a and
|| -0 or
if [ $a -ge 18 -a $a -le 35 ] ; then echo ok ; else echo notok ;fi
notok
测试 if else
[root@abc:~/shell]# cat if.sh
#!/bin/bash
if [ "$1"x = "LiMing"x ]
then
echo "welcome LiMing"
else
echo "welcome $1"
fi
echo "-----------------------------------"
if [ $2 -lt 18 ];then
echo "<18"
elif [ $2 -le 30 ]
then
echo "<=30"
else
echo ">30"
fi
[root@abc:~/shell]# ./if.sh 111 17
welcome 111
-----------------------------------
<18
[root@abc:~/shell]# ./if.sh 111 18
welcome 111
-----------------------------------
<=30
[root@abc:~/shell]# ./if.sh 111 29
welcome 111
-----------------------------------
<=30
[root@abc:~/shell]# ./if.sh 111 30
welcome 111
-----------------------------------
<=30
[root@abc:~/shell]# ./if.sh 111 31
welcome 111
-----------------------------------
>30
6.2 case
基本语法
case $变量名 in
"值1")
如果变量的值等于值 1,则执行程序 1
;;
"值2")
如果变量的值等于值 2,则执行程序 2
。。。。。。此处省略。。。。。。
*)
如果变量的值都不是以上的值,则执行此程序
;;
esac
注意:
1. case 行尾必须为单词“in”,每一个模式匹配必须以右括号 )结束
2. 双分号 ;; 表示命令序列结束,相当于 java 中的 break
3. 最后的 *)表示默认模式,相当于 java 中的 default
测试
[root@abc:~/shell]# cat case.sh
#!/bin/bash
case $1 in
1)
echo "111"
;;
2)
echo "222"
;;
*)
echo "反正不是1或者2"
;;
esac
[root@abc:~/shell]# ./case.sh 1
111
[root@abc:~/shell]# ./case.sh 2
222
[root@abc:~/shell]# ./case.sh 23
反正不是1或者2
6.3 for循环
基本语法
for (( 初始值;循环控制条件;变量变化 )) # for((a=1;a<=5;++a))与 for(( a=1 ; a<=5 ; ++a ))都对
do # 小括号不要求空格
程序
done
-----------------------------------
for 变量 in 值 1 值 2 值 3…
do
程序
done
-------------------------------------
1. 中括号里面判断两边必须有空格,小括号没必要,可以无空格
2.
测试
[root@abc:~/shell]# cat for.sh
#!/bin/bash
for(( a=1 ; a<=5 ; ++a )) # for((a=1;a<=5;++a))不保留空格也是对的,小括号不要求空格
do # 小括号里可以不用$符号,因为这是双小括号
sum=$[ $sum + $a ] # 中括号要求空格,赋值时候需要使用中括号与$符号
done
echo $a
echo a
echo $sum
echo sum
[root@abc:~/shell]# ./for.sh
6
a
15
sum
------------------------------------------------
[root@abc:~/shell]# cat ./for.sh
#!/bin/bash
for num in 1 2 3
do
echo $num
done
[root@abc:~/shell]# ./for.sh
1
2
3
---------------------------------------
[root@abc:~/shell]# cat for.sh
#!/bin/bash
for num in {1..10}
do
echo $num
done
[root@abc:~/shell]# ./for.sh
1
2
3
4
5
6
7
8
9
10
补充(()) ,{}
1. 双小括号里面可以使用 > < =
2. 可以直接使用变量而不需要 $ 符号
3. 可以不用刻意空格
测试
a=2
if (($a>1)) ;then echo ">" ;else echo "错了" ;fi
>
a=4
if (($a>1)) ;then echo ">" ;else echo "错了" ;fi
>
a=-1
if (($a>1)) ;then echo ">" ;else echo "错了" ;fi
错了
if ((a>1)) ;then echo ">" ;else echo "错了" ;fi
错了
a=8
if ((a>1)) ;then echo ">" ;else echo "错了" ;fi
>
------------------------------------------------------
[root@abc:~/shell]# cat for.sh
#!/bin/bash
for num in {1..10}
do
echo $num
done
[root@abc:~/shell]# ./for.sh
1
2
3
4
5
6
7
8
9
10
补充$* , $@*
cat for1.sh
#!/bin/bash
echo "===$*==="
echo '===$*==='
echo "===$@==="
echo '===#@==='
for num in $*
do
echo $num
done
for num in $@
do
echo $@
done
[root@abc:~/shell]# ./for1.sh 1 2 3 4
= = =1 2 3 4= = =
= = =$* = = =
= = =1 2 3 4= = =
= = =#@= = =
1
2
3
4
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
6.4 while循环
基本语法
while [ 条件判断式 ]
do
程序
done
测试
测试: 1+2+……+10;
方法1:
[root@abc:~/shell]# clear
[root@abc:~/shell]# cat while.sh
#!/bin/bash
a=1
sum=0
while [ $a -le $1 ]
do
sum=$[ $sum + $a ]
a=$[ $a + 1 ]
done
echo "sum= $sum "
echo "a= $a "
[root@abc:~/shell]# ./while.sh 10
sum= 55
a= 11
-----------------------------------------------------------
方法2:
[root@abc:~/shell]# cat while.sh
#!/bin/bash
a=1
sum=0
while [ $a -le $1 ]
do
# sum=$[ $sum + $a ]
# a=$[ $a + 1 ]
let sum+=a # 这是一种新的语法糖,也就是新版本特性
let a++ # Shell语法太反人类了
done
echo "sum= $sum "
echo "a= $a "
[root@abc:~/shell]# ./while.sh 10
sum= 55
a= 11
---------------------------------------------------------
注意
1. 循环体里面 sum=[] ,不可以sum = [] ,linux会误认为是一条命令。
2. [ ]里面,中括号与表达式之间需要有空格
7 read 读取控制台输入
7.1 基本语法
read (选项) (参数)
①选项:
-p:指定读取值时的提示符;
-t:指定读取值时等待的时间(秒)如果-t 不加表示一直等待
②参数
变量:指定读取值的变量名
7.2 read测试
[root@abc:~/shell]# cat read.sh
#!/bin/bash
read -t 20 -p "请20秒内输入" str1
echo "输入的信息是 $str1"
[root@abc:~/shell]# ./read.sh
请20秒内输入 123
输入的信息是 123
8 函数
8.1 系统函数
- 命令都可以看成是系统函数
- 可以看成就是命令替换
小demo
[root@abc:~/shell]# cat cmd1.sh
#!/bin/bash
filename="$1"_log_$(date +%s) 小括号的语法$()属于命令替换
echo $filename
[root@abc:~/shell]# ./cmd1.sh 123
123_log_1654845669
basename 获取文件名
basename 参数1 参数2
参数1必须 内容是字符串格式的路径
参数2可选 内容是想取消的后缀名称,会从后缀尾巴开始删除
测试
[root@abc:~/shell]# basename 1
1
[root@abc:~/shell]# basename 1/
1
[root@abc:~/shell]# basename 1/2
2
[root@abc:~/shell]# basename 1/2.txt
2.txt
[root@abc:~/shell]# basename 1/2.txtada/sdsadsa/fsafsa/dfsaf/.
.
[root@abc:~/shell]# basename 1/2/3.sh
3.sh
[root@abc:~/shell]# basename 1/2/3.sh .sh
3
[root@abc:~/shell]# basename 1/2/3.sh .shsh
3.sh
--------------------------------------------
[root@abc:~/shell]# basename 1/2/33.sh .s
33.sh
[root@abc:~/shell]# basename 1/2/33.sh h
33.s
[root@abc:~/shell]# basename 1/2/33.sh sh
33.
[root@abc:~/shell]# basename 1/2/33.sh s
33.sh
修改之前的test.sh内容
[root@abc:~/shell]# cat test.sh
#!/bin/bash
echo "Li Ming"
echo "Hello,I am $1"
echo "====$1===="
echo '====S1===='
echo script name $0
echo "脚本名称:"$0
echo "使用basename处理后的脚本名称$(basename $0 .sh)"
echo 1st paramater:$1
echo "==$#=="
echo "==$*=="
echo "==$@=="
[root@abc:~/shell]# ./test.sh
Li Ming
Hello,I am
========
====S1====
script name ./test.sh
脚本名称:./test.sh
使用basename处理后的脚本名称test
1st paramater:
==0==
====
====
dirname 获得路径名
dirname 参数1
参数1是文件路径
可以理解为取文件路径的绝对路径名称
测试
[root@abc:~/shell]# dirname 1/2/3
1/2
[root@abc:~/shell]# dirname 1/2/3.sj
1/2
[root@abc:~/shell]# dirname ../1/2/3
../1/2
[root@abc:~/shell]# dirname 1 # 这个特殊
.
[root@abc:~/shell]# dirname / # 这个特殊
/
[root@abc:~/shell]# dirname . # 这个特殊
.
root@abc:~/shell]# clear
[root@abc:~/shell]# cat dirname.sh
#!/bin/bash
echo "打印文件启动路径:$0"
echo "打印文件名称: $( basename $0 .sh ) "
cd $(dirname $0)
echo "打印文件实际路径:$(pwd)"
# echo "即打印又跳转路径:$( cd $(dirname $0) ; pwd )"
[root@abc:~/shell]# ./dirname.sh
打印文件启动路径:./dirname.sh
打印文件名称: dirname
打印文件实际路径:/root/shell
8.2 自定义函数
基本语法
[ function ] funname[()]
{
Action;
[return int;]
}
------------------------------------------
(1)在调用函数之前,先声明 shell 脚本是逐行运行。不会像其它语言一样先编译。
(2)函数返回值,只能通过$?系统变量获得,可以显示加:return 返回,
如果不加,将以最后一条命令运行结果,作为返回值。return 后跟数值 n(0-255)
测试
[root@abc:~/shell]# cat myadd.sh
#!/bin/bash
function myadd()
{
s=0;
s=$[$1+$2]
echo $s
}
read -p "输入参数1: " num1
read -p "输入参数2: " num2
myadd $num1 $num2
[root@abc:~/shell]# ./myadd.sh
输入参数1: 1
输入参数2: 2
3
[root@abc:~/shell]# cat myadd.sh
#!/bin/bash
function myadd()
{
s=0;
s=$[$1+$2]
return $s # 这里使用了return 返回值,返回数字
} # 因为下面的$? 输出的是0 ~ 255的数字
read -p "输入参数1: " num1
read -p "输入参数2: " num2
myadd $num1 $num2
echo $? # 不可以用
[root@abc:~/shell]# ./myadd.sh
输入参数1: 1
输入参数2: 4
5
[root@abc:~/shell]# cat myadd.sh
#!/bin/bash
function myadd()
{
num=$[$1+$2]
echo $num
}
read -p "输入参数1: " num1
read -p "输入参数2: " num2
endData=$(myadd $num1 $num2)
echo $endData
echo $[$endData * $endData]
[root@abc:~/shell]# ./myadd.sh
输入参数1: 11
输入参数2: 19
30
900
9 正则表达式
10 文本处理工具
11 综合应用案例
11.1 归档文件
需求
实现一个每天对指定目录归档备份的脚本,输入一个目录名称(末尾不带/),将目录下所有文件按天归档保存,并将归档日期附加在归档文件名上,放在/root/archive 下。
- 用到了归档命令:tar 后面可以加上-c 选项表示归档,加上-z 选项表示同时进行压缩,得到的文件后缀名为.tar.gz。
实现