Shell 脚本
一、走进 Shell 编程的大门
1)为什么要学 Shell?
学习 Shell 是为了提高我们自己工作效率,提高产出,让我们在更少的时间完成更多的事情。
一般 Shell 编程属于运维方面的知识,但我们做后端开发也是需要掌握的,对于 Shell 编程掌握程度的要求要比运维低。
目前 Linux 系统下最流行的运维自动化语言就是 Shell 和 Python 了。
两者区别
- Shell 几乎是 IT 企业必须使用的运维自动化编程语言,特别是在运维工作中的服务监控、业务快速部署、服务启动停止、数据备份及处理、日志分析等环节里,shell 是不可缺的。
- Python 更适合处理复杂的业务逻辑,以及开发复杂的运维软件工具,实现通过 web 访问等。
Shell 是一个命令解释器,解释执行用户所输入的命令和程序。一输入命令,就立即回应的交互的对话方式。
2)什么是 Shell?
Shell 编程就是对一堆 Linux 命令的逻辑化处理。
3)第一个 Shell 脚本
1.新建一个文件 helloworld.sh:touch helloworld.sh
,扩展名为 sh(sh 代表 Shell)
2.使脚本具有执行权限:chmod +x helloworld.sh
3.使用 vim 命令修改 helloworld.sh 文件:vim helloworld.sh
,内容如下 ↓
#!/bin/bash
echo "helloworld!!!"
shell 的第一行比较特殊,一般都会以
#!
开始来指定使用的 shell 类型。在 linux 中,除了 bash shell 以外,还有很多版本的 shell, 例如 zsh、dash 等等...不过 bash shell 还是我们使用最多的
4.执行脚本:./helloworld.sh
。
注意,一定要写成 ./helloworld.sh ,而不是 helloworld.sh ,运行其它二进制的程序也一样,直接写 helloworld.sh ,linux 系统会去 PATH 里寻找有没有叫 helloworld.sh 的,而只有 /bin, /sbin, /usr/bin,/usr/sbin 等在 PATH 里,你的当前目录通常不在 PATH 里,所以写成 helloworld.sh 是会找不到命令的,要用 ./helloworld.sh 告诉系统说,就在当前目录找。
二、Shell 变量
1)Shell 变量介绍
Shell 编程中一般分为三种变量
- 自定义变量: 仅在当前 Shell 实例中有效,其他 Shell 启动的程序不能访问局部变量。
- 环境变量:系统中已定义的环境变量,这类变量可以直接使用;
env 命令可以查看所有环境变量,set 命令查看所有环境变量与自定义变量
。 - Shell 变量:Shell 变量是由 Shell 程序设置的特殊变量。Shell 变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了 Shell 的正常运行
常用的环境变量
PATH:决定了 shell 将到哪些目录中寻找命令或程序
HOME:当前用户主目录
HISTSIZE:历史记录数
LOGNAME:当前用户的登录名
HOSTNAME:指主机的名称
SHELL:当前用户 Shell 类型
LANGUAGE:语言相关的环境变量,多语言可以修改此环境变量
MAIL:当前用户的邮件存放目录
PS1:基本提示符,对于 root 用户是#,对于普通用户是$
例:
#!/bin/bash
#自定义变量
hello="hello world"
echo $hello
echo "helloworld!"
#环境变量
echo $HOME
变量名命名规则
- 命名只能使用英文字母,数字和下划线,首个字符不能以数字开头
- 中间不能有空格,可以使用下划线 _
- 不能使用标点符号
- 不能使用bash里的关键字(可用help命令查看保留关键字)
2)Shell 字符串
Shell 中的字符串可以用单引号,也可以用双引号。这点和 Java 中有所不同。
区别
- 单引号:所有的特殊符号,如 $ 和反引号都没有特殊含义。
- 双引号:除了 "$","" 和反引号,其他的字符没有特殊含义。
单引号字符串:
#!/bin/bash
type_1='Single'
str1='This is $type_1 quotation marks!'
echo $str1
输出:This is $type_1 quotation marks!
双引号字符串:
#!/bin/bash
type_2="Double"
str2="This is $type_2 quotation marks!"
echo $str2
输出:This is Double quotation marks!
拼接字符串:
#!/bin/bash
joint="joint"
# 使用双引号拼接
joint1="Concatenation string,"$joint"!"
echo $joint1
joint2="Concatenation string,${joint}!"
echo $joint2
# 使用单引号拼接
joint3='Concatenation string,'$joint'!'
echo $joint3
joint4='Concatenation string,${joint}!' #单引号内所有特殊符号都无意义
echo $joint4
输出:
Concatenation string,joint!
Concatenation string,joint!
Concatenation string,joint!
Concatenation string,${joint}!
获取字符串长度:
#!/bin/bash
str="1234567"
echo ${#str}
输出:7
截取字符串:
#!/bin/bash
zimu="abcdefghijklmnopqrstuvwxyz"
echo ${zimu:0:10} # startIdx 包含、endIdx 不包含
输出:abcdefghij
表达式截取字符串
- %:表示删除从后匹配, 最短结果
- %%:表示删除从后匹配, 最长匹配结果
- #:表示删除从头匹配, 最短结果
- ##:表示删除从头匹配, 最长匹配结果
- 注: *为通配符, 意为匹配任意数量的任意字符
#!/bin/bash
var="https://www.runoob.com/linux/linux-shell-variable.html"
s1=${var%%t*}
echo $s1
s2=${var%t*}
echo $s2
s3=${var%%.*}
echo $s3
s4=${var#*/}
echo $s4
s5=${var##*/}
echo $s5
输出:h
https://www.runoob.com/linux/linux-shell-variable.h
https://www
/www.runoob.com/linux/linux-shell-variable.html
linux-shell-variable.html
3)Shell 数组
bash 支持一维数组(不支持多维数组),并且没有限定数组的大小。
下面演示创建数组、获取数组长度、获取/删除特定位置的数组元素、删除整个数组以及遍历数组。
#!/bin/bash
#创建数组,多个元素使用空格分开
array=(1 2 3 4 5);
for obj in ${array[@]};
do
echo $obj;
done
#获取数组长度
length1=${#array[@]}
length2=${#array[*]}
echo "--------------"
#输出数组长度
echo "length1="$length1
echo "length2="$length2
echo "--------------"
#获取指定下标元素
echo "array[2]="${array[2]}
echo "--------------"
#删除指定下标元素
unset array[1]
for i in ${array[@]};
do
echo $i ;
done
echo "--------------"
#删除数组中的所有元素
unset array;
for j in ${array[@]};
do
echo $j ;
done
echo "--------------"
三、Shell 运算符
shell 支持多种运算符:
- 算数运算符
- 关系运算符
- 布尔运算符
- 字符串运算符
- 文件测试运算符
表达式和运算符之间要有空格,例如 1+1
是不对的,必须写成 1 + 1
完整的表达式要被反引号 ``
包含(不是单引号)
1)算术运算符
例:
#!/bin/bash
a=3;b=3;
result=`expr $a + $b`
echo "$a + $b = $result"
输出:3 + 3 = 6
2)关系运算符
例:
#!/bin/bash
score=90;
maxscore=100;
if [ $score -eq $maxscore ]
then
echo "A"
else
echo "B"
fi
输出:B
3)逻辑运算符
例:
#!/bin/bash
flag=$(( 1 && 0))
echo $flag;
输出:0
4)布尔运算符
例:
#!/bin/bash
a1=10
a2=20
if [ $a1 != $a2 ]
then
echo "A"
else
echo "B"
fi
输出:A
5)字符串运算符
例:
#!/bin/bash
a3="abc";
b3="efg";
if [ $a3 = $b3 ]
then
echo "a3 等于 b3"
else
echo "a3 不等于 b3"
fi
输出:a3 不等于 b3
6)文件相关运算符
例:
#!/bin/bash
file="/var/tmp/20230501.txt"
if [ -r $file ]
then
echo "文件可读"
else
echo "文件不可读"
fi
if [ -d $file ]
then
echo "文件是个目录"
else
echo "文件不是个目录"
fi
if [ -e $file ]
then
echo "文件存在"
else
echo "文件不存在"
fi
输出:
文件可读
文件不是个目录
文件存在
四、Shell 流程控制
1)if条件语句
与 Java、PHP 等语言不一样,sh 的流程控制不能包含空语句也就是什么都不做的语句。
if(true){
System.out.println("Hello");
}else{
// 不做任何事情,这里是允许的
}
例:
#!/bin/bash
a1=2; b1=7;
if [ $a1 -eq $b1 ]
then
echo "a1 等于 b1"
elif [ $a1 -gt $b1 ]
then
echo "a1 大于 b1"
else
# echo "b1 小于 b1" # 注释后会出错,不允许什么也不做的语句
fi
输出:b1 小于 b1
2)for 循环语句
与其他编程语言类似,Shell支持for循环。
例:输出列表中的数据
#!/bin/bash
for val in 1 2 3 4 5
do
echo "The val is: $val"
done
输出:
The value is: 1
The val is: 2
The val is: 3
The val is: 4
The val is: 5
例:产生 10 个随机数
#!/bin/bash
for i in {0..9};
do
echo "random.val="$RANDOM;
done
输出:
random.val=5070
random.val=14653
random.val=31878
random.val=26394
random.val=9457
random.val=1887
random.val=5887
random.val=4853
random.val=9231
random.val=15433
例:输出 1 - 5
#!/bin/bash
for((i=1;i<=5;i++));
do
echo "out "$i;
done;
输出:
out 1
out 2
out 3
out 4
out 5
3)while 语句
while 语法格式为:
while condition
do
command
done
例:
#!/bin/bash
idx=1
while(( $idx<=5 ))
do
echo "while print > "$idx
let "idx++" # Bash let 命令,变量计算中不需要加上 $ 来表示变量
done
输出:
while print > 1
while print > 2
while print > 3
while print > 4
while print > 5
五、Shell 函数
linux shell 可以用户定义函数,然后在shell脚本中可以随便调用。
函数格式:
[ function ] funname [()]
{
action;
[return int;]
}
1)无参数无返回值
#!/bin/bash
hello(){
echo "this is my function"
}
echo "fun start"
hello
echo "fun end"
输出:
fun start
this is my function
fun end
2)无参数有返回值
函数返回值在调用该函数后通过 $? 来获得。
注意:所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至 shell 解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可。
#!/bin/bash
funWithReturn(){
echo -n "输入第一个数字: "
read a
echo -n "输入第二个数字: "
read b
echo "两个数字分别为 $a 和 $b !"
return $(($a+$b))
}
funWithReturn
echo "输入的两个数字之和为 $?"
输出:
输入第一个数字: 33
输入第二个数字: 7
两个数字分别为 33 和 7 !
输入的两个数字之和为 40
3)带参数的函数
#!/bin/bash
funWithParam(){
echo "Expression \$1 value = $1"
echo "Expression \$2 value = $2"
echo "Expression \$10 value = $10"
echo "Expression \${10} value = ${10}"
echo "Expression \$11 value = $11"
echo "Expression \${11} value = ${11}"
echo "Params size = $#"
echo "Out all params > $*"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73
输出:
Expression $1 value = 1
Expression $2 value = 2
Expression $10 value = 10
Expression ${10} value = 34
Expression $11 value = 11
Expression ${11} value = 73
Params size = 11
Out all params > 1 2 3 4 5 6 7 8 9 34 73
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~