Shell脚本基础
Shell是一个命令解释器,它接收应用程序/用户命令,然后调用操作系统内核。
Shell还是一个功能相当强大的编程语言,易编写、易调试、灵活性强。
https://blog.csdn.net/Jackson00709/article/details/106086756
Shell概述
shell是一个命令行解释器,它接收应用程序/用户命令,然后调用操作系统内核
脚本入门
脚本格式
脚本以#!/bin/bash开头(指定解析器)
helloworld
# 创建脚本
[linux@localhost datas]$ cat helloworld.sh
#!/bin/bash
echo "hello huangxb"
# 执行脚本方式1
[linux@localhost datas]$ bash helloworld.sh
hello huangxb
# 执行脚本方式2
[linux@localhost datas]$ ./helloworld.sh
-bash: ./helloworld.sh: 权限不够
方式1,本质是bash解析器帮你执行脚本,所以脚本本身不需要执行权限;方式2,本质是脚本自己需要执行,所以需要执行权限
修改文件权限的命令是
chmod [option] filename
其中[option]表示各种权限选项。具体如下:
-
r(或4):读取权限
-
w(或2):写入权限
-
x(或1):执行权限
此外还可以指定权限的获取者,也就是指定将当前权限赋予之前提到的三个部分的左中右哪个部分:
-
u:文件所有者
-
g:文件所有者所在的组的用户
-
o:其他组的用户
权限的授予可采用操作符“+”,而“-”表示收回权限。
-
示例[1]:授予文件所有者以ex1-2.sh文件的执行权限
[root@linux chapter1]# chmod u+x ex1-2.sh
[root@linux chapter1]# 11
total 4
-rwxr--r-- l root root 116 Dec 18 23:11 ex1-2.sh
示例[2]:采用数字表示法来授予文件所有者以ex1-2.sh文件的执行权限
[root@linux chapter1]# chmod 744 ex1-2.sh
[root@linux chapter1]# 11
total 4
-rwxr--r-- l root root 116 Dec 18 23:11 ex1-2.sh
上面的第二份代码中的“744”分别表示文件所有者、文件所有者所在的组的用户、其他组的用户的权限。其中“7”表示了4+2+1也就是三个权限的数值之和,表明了“所有权限”。可见数值方法可以很方便地同时赋予用户权限。
多命令处理
- 在linux家目录下创建一个bangzhang.txt并在文件中写入"I IOVE YOU"字符
#!/bin/bash
cd /home/linux/
touch banzhang.txt
echo "I LOVE YOU" >> banzhang.txt
1234
Shell中的变量
常用系统变量
$HOME $PWD $SHELL $USER
[linux@localhost datas]$ echo $HOME
/home/linux
[linux@localhost datas]$ echo $PWD
/home/linux/datas
[linux@localhost datas]$ echo $SHELL
/bin/bash
[linux@localhost datas]$ echo $USER
linux
自定义变量
基本语法
- 定义变量:变量=值 等号两边不能留有空格
- 撤销变量:unset 变量
- 输出变量:echo $变量
- 声明静态变量: readonly 变量,注意:不能unset
[linux@localhost datas]$ A=1
[linux@localhost datas]$ echo $A
1
[linux@localhost datas]$ unset A
1234
自定义的变量是有作用范围的,通过
ps -f
查看当前bash,子类bash自定义的变量为局部变量,只能在自己的bash范围下有效,父类bash是看不到的
变量定义规则
- 变量名称可以由字母,数字和下划线组成,不能以数字开头,环境变量名建议大写
- 等号两侧不能有空格
- 在bash中,变量默认类型都是字符串类型,无法直接进行数值运算
- 变量的值如果有空格,需要使用双引号或单引号括起来
[linux@localhost datas]$ D="A B C"
[linux@localhost datas]$ echo $D
A B C
123
- 可把变量提升为全局变量,可供其他shell程序使用
export 变量
特殊变量
$n-获取控制台输入的参数
$n (描述:n为数字,$0代表脚本名称,10以内参数用$1-9 表 示 , 10 以 上 的 需 要 用 大 括 号 包 含 ${10})
[atguigu@hadoop101 shells]$ touch parameter.sh
[atguigu@hadoop101 shells]$ vim parameter.sh
#!/bin/bash
echo '==========$n=========='
echo $0
echo $1
echo $2
[atguigu@hadoop101 shells]$ chmod 777 parameter.sh
[atguigu@hadoop101 shells]$ ./parameter.sh cls xz
==========$n==========
./parameter.sh
cls
xz
echo '$n'使用单引号而不是双引号,使用双引号括起来时,会以为$n为一个变量,我们要让他原封不动的输出来
$#-获取输入参数个数
$# (功能描述:获取所有输入参数个数,常用于循环,判断参数的个数是否正确以及加强脚本的健壮性)
[atguigu@hadoop101 shells]$ vim parameter.sh
#!/bin/bash
echo '==========$n=========='
echo $0
echo $1
echo $2
echo '==========$#=========='
echo $#
[atguigu@hadoop101 shells]$ chmod 777 parameter.sh
[atguigu@hadoop101 shells]$ ./parameter.sh cls xz
==========$n==========
./parameter.sh
cls
xz
==========$#==========
2
$* 和$@
- $* (描述:代表命令行中所有的参数,把所有参数看成一个整体)
- $@ (描述:也代表命令行中所有的参数,不过把每个参数区分对待)
[atguigu@hadoop101 shells]$ vim parameter.sh
#!/bin/bash
echo '==========$n=========='
echo $0
echo $1
echo $2
echo '==========$#=========='
echo $#
echo '==========$*=========='
echo $*
echo '==========$@=========='
echo $@
[atguigu@hadoop101 shells]$ ./parameter.sh a b c d e f g
==========$n==========
./parameter.sh
a
b
==========$#==========
7
==========$*==========
a b c d e f g
==========$@==========
a b c d e f g
$?
$? (描述:最后一次执行命令的状态,如果这个变量的值为 0,证明上一 个命令正确执行;如果这个变量的值为非 0(具体是哪个数,由命令自己来决定),则证明 上一个命令执行不正确了。)
[atguigu@hadoop101 shells]$ ./helloworld.sh
hello world
[atguigu@hadoop101 shells]$ echo $?
0
运算符
- $((运算式)) 或 $[运算式]
- expr +,-,*,/,% 加减乘除取余
expr运算符间要有空格
# 计算2+3
[linux@localhost datas]$ expr 2 + 3
5
# 计算(2+3)*4
## 方式1
[linux@localhost datas]$ expr `expr 2 + 3` \* 4
20
## 方式2
[linux@localhost datas]$ s=$[(2+3)*4]
[linux@localhost datas]$ echo $s
20
12345678910111213
expr进行乘运算时不能直接用 * ,需要进行转义:\*
如果要进行计算整体划分,还需要用反引号括起来``
条件判断
基本语法
test condition
[ condition ]
(注意 condition前后要有空格)
注意:条件非空即为 true,[ atguigu ]返回 true,[ ] 返回 false。
# test condition判断
[root@hadoop111 ~]# a=hello
[root@hadoop111 ~]# test $a = hello
[root@hadoop111 ~]# echo $?
0
[root@hadoop111 ~]# test $a = Hello
[root@hadoop111 ~]# echo $?
1
# [ condition ]判断
[root@hadoop111 ~]# [ $a = hello ]
[root@hadoop111 ~]# echo $?
0
[root@hadoop111 ~]# [ $a = Hello ]
[root@hadoop111 ~]# echo $?
1
通过$?来判断test condition、[ condition ]的返回值,进而达到判断真假
使用[ condition ]来判断,不仅括号两边要有空格,内部的等号也要有空格
常用判断条件
两个整数之间比较
符号 | 描述 |
---|---|
-lt | (less than)小于 |
-le | (less equal) 小于等于 |
-eq | (equal)等于 |
-gt | (greater than) 大于 |
-ge | (greater equal) 大于等于 |
-ne | (not equal) 不等于 |
文件权限判断
- -r 有读的权限
- -w 有写的权限
- -x 有执行的权限
文件类型判断
- -f 文件存在并且是一个常规文件
- -e 文件存在
- -d 文件存在并且是一个目录
# 判断23是否大于2
[linux@localhost datas]$ [ 23 -gt 2 ]
[linux@localhost datas]$ echo $?
0
# 判断helloworld.sh是否有写入权限
[linux@localhost datas]$ [ -w hellowrld.sh ]
[linux@localhost datas]$ echo $?
1
# 判断目录中文件是否存在
[linux@localhost datas]$ [ -e /home/linux/datas ]
[linux@localhost datas]$ echo $?
0
多条件判断
&& ||
[atguigu@hadoop101 ~]$ [ atguigu ] && echo OK || echo notOK
OK
[atguigu@hadoop101 shells]$ [ ] && echo OK || echo notOK
notOK
流程控制
IF判断
基本语法:
# 单分支
if [ 条件判断式 ];then
程序
fi
#或者
if [ 条件判断式 ]
then
程序
fi
# 多分支
if [ 条件判断式 ]
then
程序
elif [ 条件判断式 ]
then
程序
else
程序
fi
注意事项:
①[ 条件判断式 ],中括号和条件判断式之间必须有空格
②if 后要有空格
实例:
[linux@localhost datas]$ cat if.sh
#!/bin/bash
if [ $1 -eq 1 ]
then
echo "你好"
elif [ $1 -eq 2 ]
then
echo "世界"
fi
[linux@localhost datas]$ bash if.sh 2
世界
case 语句
基本语法:
case $变量名 in
"值 1")
如果变量的值等于值 1,则执行程序 1
;;
"值 2")
如果变量的值等于值 2,则执行程序 2
;;
…省略其他分支…
*)
如果变量的值都不是以上的值,则执行此程序
;;
esac
注意事项:
(1)case 行尾必须为单词“in”,每一个模式匹配必须以右括号“)”结束。
(2)双分号“;;”表示命令序列结束,相当于 java 中的 break。
(3)最后的“*)”表示默认模式,相当于 java 中的 default。
[linux@localhost datas]$ cat case.sh
#!/bin/bash
case $1 in
1)
echo "班长"
;;
2)
echo "学习委员"
;;
3)
echo "体育委员"
;;
esac
[linux@localhost datas]$ bash case.sh 2
学习委员
for循环
语法1
语法:
for (( 初始值;循环控制条件;变量变化 ))
do
程序
done
实例:
[linux@localhost datas]$ cat for.sh
#!/bin/bash
s=0
for((i=1;i<=100;i++))
do
s=$[$s+$i]
done
echo $s
[linux@localhost datas]$ bash for.sh
5050
语法2
语法:
for 变量 in 值 1 值 2 值 3…
do
程序
done
实例:
[linux@localhost datas]$ cat for2.sh
#!/bin/bash
for i in $*
do
echo $i
done
[linux@localhost datas]$ bash for2.sh 1 2
1
2
(2)比较$*和$@区别
$*和$@都表示传递给函数或脚本的所有参数,不被双引号“”包含时,都以$1 $2 …$n 的形式输出所有参数。
[atguigu@hadoop101 shells]$ touch for3.sh
[atguigu@hadoop101 shells]$ vim for3.sh
#!/bin/bash
echo '=============$*============='
for i in $*
do
echo "ban zhang love $i"
done
echo '=============$@============='
for j in $@
do
echo "ban zhang love $j"
done
[atguigu@hadoop101 shells]$ chmod 777 for3.sh
[atguigu@hadoop101 shells]$ ./for3.sh cls mly wls
=============$*=============
banzhang love cls
banzhang love mly
banzhang love wls
=============$@=============
banzhang love cls
banzhang love mly
banzhang love wls
当它们被双引号“”包含时,$*会将所有的参数作为一个整体,以“$1 $2 …$n”的形式输 出所有参数;$@会将各个参数分开,以“$1” “$2”…“$n”的形式输出所有参数。
[atguigu@hadoop101 shells]$ vim for4.sh
#!/bin/bash
echo '=============$*============='
for i in "$*"
#$*中的所有参数看成是一个整体,所以这个 for 循环只会循环一次
do
echo "ban zhang love $i"
done
echo '=============$@============='
for j in "$@"
#$@中的每个参数都看成是独立的,所以“$@”中有几个参数,就会循环几次
do
echo "ban zhang love $j"
done
[atguigu@hadoop101 shells]$ chmod 777 for4.sh
[atguigu@hadoop101 shells]$ ./for4.sh cls mly wls
=============$*=============
ban zhang love cls mly wls
=============$@=============
ban zhang love cls
ban zhang love mly
ban zhang love wls
WHILE循环
语法:
while [ 条件判断式 ]
do
程序
done
实例:
[linux@localhost datas]$ cat while.sh
#!/bin/bash
s=0
i=1
while [ $i -le 100 ]
do
s=$[$s + $i]
i=$[$i + 1]
done
echo $s
[linux@localhost datas]$ bash while.sh
5050
read读取控制台输入
read (选项) (参数)
选项:
- -p 指定读取值时的提示符
- -t 指定读取值时等待的时间(秒)如果-t 不加表示一直等待
参数:
- 变量:指定读取值的变量名
# 提示7秒内,读取控制台输入的名称
[atguigu@hadoop101 shells]$ touch read.sh
[atguigu@hadoop101 shells]$ vim read.sh
#!/bin/bash
read -t 7 -p "Enter your name in 7 seconds :" NN
echo $NN
[atguigu@hadoop101 shells]$ ./read.sh
Enter your name in 7 seconds : atguigu
atguigu
函数
系统函数
basename
basename [string / pathname] [suffix] (描述:basename命令会删掉所有的前缀包括最后一个‘/’字符,然后将字符串显示出来)
basename 可以理解为取路径里的文件名称
选项:
suffix为后缀,如果suffix被指定了,basename会将pathname或string中的suffix去掉
# 方式1
[linux@localhost datas]$ basename /home/linux/banzhang.txt
banzhang.txt
# 方式2
[linux@localhost datas]$ basename /home/linux/banzhang.txt .txt
banzhang
dirname
dirname 文件绝对路径 (描述:从给定的包含绝对路径的文件名中去除文件名(非目录的部分),然后返回剩下的路径(目录的部分))
dirname 可以理解为取文件路径的绝对路径名称
[linux@localhost datas]$ dirname /home/linux/banzhang.txt
/home/linux
自定义函数
# 格式
[ function ] funname[()]
{
Action:
[return int;]
}
# DESC 计算输入两个参数的值
[linux@localhost datas]$ cat sum.sh
#!/bin/bash
function sum(){
s=0;
s=$[$1 + $2]
echo $s
}
read -p "input your param1:" P1
read -p "input your param2:" P2
sum $P1 $P2
[linux@localhost datas]$ bash sum.sh
input your param1:1
input your param2:2
正则表达式入门
正则表达式使用单个字符串来描述、匹配一系列符合某个语法规则的字符串。在很多文 本编辑器里,正则表达式通常被用来检索、替换那些符合某个模式的文本。在 Linux 中,grep, sed,awk 等文本处理工具都支持通过正则表达式进行模式匹配。
常规匹配
一串不包含特殊字符的正则表达式匹配它自己,例如:
[atguigu@hadoop101 shells]$ cat /etc/passwd | grep atguigu
就会匹配所有包含atguigu 的行
常用匹配
1)特殊字符:^
^
匹配一行的开头,例如:
[atguigu@hadoop101 shells]$ cat /etc/passwd | grep a^
会匹配出所有以 a 开头的行
2)特殊字符:$
$
匹配一行的结束,例如
[atguigu@hadoop101 shells]$ cat /etc/passwd | grep t$
会匹配出所有以t结尾的行
3)特殊字符:.
.
匹配一个任意的字符,例如
[atguigu@hadoop101 shells]$ cat /etc/passwd | grep r..t
会匹配包含rabt,rbbt,rxdt,root等的所有行,类似SQL中Like的_
作用
4)特殊字符:*
*
不单独使用,他和上一个字符连用,表示匹配上一个字符 0 次或多次,例如
[atguigu@hadoop101 shells]$ cat /etc/passwd | grep ro*t
会匹配rt,rot,root,rooot,roooot等所有行
5)字符区间(中括号):[ ]
[ ] 表示匹配某个范围内的一个字符,例如
[6,8]------匹配 6 或者 8
[0-9]------匹配一个 0-9 的数字
[0-9]*------匹配任意长度的数字字符串 *
[a-z]------匹配一个 a-z 之间的字符
[a-z]* ------匹配任意长度的字母字符串
[a-c, e-f]-匹配 a-c 或者 e-f 之间的任意字符
[atguigu@hadoop101 shells]$ cat /etc/passwd | grep r[a,b,c]*t
会匹配 rt,rat, rbt, rabt, rbact,rabccbaaacbt 等等所有行
6)特殊字符:\
\ 表示转义,并不会单独使用。由于所有特殊字符都有其特定匹配模式,当我们想匹配 某一特殊字符本身时(例如,我想找出所有包含 '$' 的行),就会碰到困难。此时我们就要 将转义字符和特殊字符连用,来表示特殊字符本身,例如
[atguigu@hadoop101 shells]$ cat /etc/passwd | grep 'a\$b'
就会匹配所有包含 a$b 的行。注意需要使用单引号将表达式引起来。
shell工具
cut
cut命令从文件的每一行剪切字节,字符和字段并将这些字节,字符和字段输出
cut [选项参数] filename
默认分隔符时制表符
选项参数说明
- -f 列号,提取第几列
- -d 分隔符,按照指定分隔符分隔列,默认是制表符"\t"
- -c 按字符进行切割 后加 n 表示取第几列 比如
-c 1
[linux@localhost datas]$ cat cut.txt
dong shen
guan zhen
wo wo
lai lai
le le
# DESC 切割cut.txt第一列
[linux@localhost datas]$ cut -d " " -f 1 cut.txt
dong
guan
wo
lai
le
# 切割 cut.txt 第二、三列
[atguigu@hadoop101 shells]$ cut -d " " -f 2,3 cut.txt
shen
zhen
wo
lai
le
# DESC 获取第三行第一个单词
[linux@localhost datas]$ cat cut.txt | grep guan | cut -d " " -f 1
guan
sed
sed是一种流编辑器,它一次处理一行内容,处理时,把当前处理的行存储在临时缓冲区中,成为“模式空间”,接着sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕,接着处理下一行,这样不断重复,知道文件末尾,文件内容并没有改变,除非你使用重定向存储输出
sed [选项参数] ‘command’ filename
- -e 直接在指令列模式上进行sed的动作编辑
命令功能描述
- a 新增
- d 删除
- s 查找并替换
# DESC 在第二行后增加mei nv字符
[linux@localhost datas]$ sed -e "2a mei nv" sed.txt
dong zhen
guan zhen
mei nv
wo wo
lai lai
1234567
awk
awk 一个强大文件分析工具,把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理
awk [选项参数] 'pattern1 {action1} pattern2{action2}..' filename
1
- -F 指定输入文件分隔符
- -v 赋值一个用户定义变量
sort
sort 命令是在Linux里非常有用,它将文件进行排序,并将排序结果标准输出
sort [选项] (参数)
参数 | 描述 |
---|---|
-n | 依照数值大小排序 |
-t | 以相反的顺序排序 |
-t | 设置排序时使用的分隔字符 |
-k | 指定需要排序的列 |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)