Day15 Shellスクリプト
1.Shell简介
bash 是 Linux 的默认 Shell,它是 sh 的增强版,提供了更丰富的功能和更好的交互界面。
Bash 是 Linux 的默认 Shell,它支持大量的命令和参数。
基本的 Bash 脚本写法如下:
- 以 "#!" 开头,表示这是一个脚本文件,后面接上脚本的解释器地址, 一般是 /bin/bash
- 使用命令和参数来控制和访问操作系统服务,如文件管理、进程管理等。
- 注释以"#"开头
- 脚本文件需要有可执行权限,可以使用 chmod +x script.sh来给脚本文件增加可执行权限
注意几点⚠️:
- 运行脚本的时候会从上往下执行
- echo的时候会读取上面最近的变量
执行的命令:
每次运行记得先给sh添加执行权限
chmod +x 文件名.sh
sh 文件名.sh
bash 文件名.sh
./ 文件名.sh
2.变量
在 Linux/Unix 系统中,环境变量是一种非常重要的概念。环境变量是一种特殊的变量,用于储存在系统中运行时使用的配置信息。它们可以在系统的所有用户之间共享,并且可以被各种程序使用。
在 shell 中,变量是通过赋值语句来定义的。语法如下:
variable_name=value
例如:
name=tutu
这样就会创建一个名为 name 的变量,并将其值设置为 tutu 。
要使用变量的值,可以在变量名前面加一个 $ 符号。例如:
echo $name
这将输出 "John"
3.传递参数
在 shell 中,可以通过传递参数来向脚本或命令传递额外的信息。这些参数可以在脚本或命令中被使用。
在 shell 中,参数可以通过特殊的变量来引用。这些变量名分别是 $1, $2, $3, … $n。其中 $0 表示脚本或命令本身的名称。
例如,脚本 test.sh 接受两个参数,可以这样运行:
sh test.sh arg1 arg2
在脚本中可以通过$1和$2来访问这两个参数
另外,在脚本中还可以使用特殊变量$#来获取参数的个数,$@或$*来获取所有的参数。
$#表示传递给脚本或命令的参数个数 $@或$*表示所有的参数。
例如:
#!/bin/bash
echo "The script name is $0"
echo "The total number of parameters is $#"
echo "The parameters are $@ or $*"
执行上面的脚本
sh test.sh arg1 arg2 arg3
结果将会是
The script name is test.sh
The total number of parameters is 3
The parameters are arg1 arg2 arg3 or arg1 arg2 arg3
看看例子
#!/bin/bash
echo "Shell 传递参数实例!";
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";
我们运行时添加参数运行结果为
sh 2.sh a b c
Shell 传递参数实例!
执行的文件名:2.sh
第一个参数为:a
第二个参数为:b
第三个参数为:c
echo $(expr 3 \* 4) # 输出12
echo $(expr 3 + 4) # 输出7
echo $(expr 1 + 1) # 输出2
echo $(expr 10 + 1000) # 输出1010
echo $(expr 100 / 10) # 输出10
4.运算符
expr命令是一种在Linux和Unix系统中使用的命令行工具。它可以用来执行整数和字符串运算。
expr命令最常用的用途是在shell脚本中执行简单的算术运算,比如加减乘除以及比较两个数字的大小。
例如:
expr 3 + 4 # 输出 7
expr 20 - 10 # 输出 10
expr 5 \* 6 # 输出 30
expr 20 / 5 # 输出 4
expr命令还可以用来比较字符串的长度,判断两个字符串是否相等。
例如:
expr length "Hello World" # 输出 11
expr index "Hello World" "Wor" # 输出 7
expr "Hello" == "Hello" # 输出 1 (true)
expr "Hello" == "World" # 输出
练习
echo "3*4 = $(expr 3 \* 4)" # 输出 "3*4 = 12"
echo "3+4 = $(expr 3 + 4)" # 输出 "3+4 = 7"
echo "1+1 = $(expr 1 + 1)" # 输出 "1+1 = 2"
echo "100/10 = $(expr 100 / 10)" # 输出 "100/10 = 10"
5.条件分歧IF
在bash中,使用if条件可以根据一个特定条件来执行不同的命令。
语法格式如下:
if [ condition ]; then
commands
fi
其中,condition是条件表达式,比如整数比较、字符串比较、文件属性检测等,commands是条件成立时执行的命令。
例如:
#!/bin/bash
a=10
b=20
if [ $a -lt $b ]; then
echo "$a is less than $b"
fi
这个例子中,条件为 $a -lt $b, 如果成立那么就会输出"10 is less than 20"
还可以使用if-else条件,当if条件不成立时执行else中的命令
#!/bin/bash
a=10
b=20
if [ $a -lt $b ]; then
echo "$a is less than $b"
else
echo "$a is greater than or equal to $b"
fi
上面的这个例子中, 如果 $a -lt $b 条件不成立,那么就会输出"10 is greater than or equal to 20"
还有if-elif-else,用于检测多种可能性,如果第一个if条件不成立,就执行第一个elif中的条件,如果都不成立执行else中的命令。
比较符
-lt 是 bash 中用来进行整数比较的比较符之一,它的含义是 less than,即小于。在条件表达式 $a -lt $b 中,如果变量 $a 的值小于变量 $b 的值,那么条件就成立了。
在整数比较中,bash 支持以下常用的比较符:
- -eq : equal (等于)
- -ne : not equal (不等于)
- -gt : greater than (大于)
- -lt : less than (小于)
- -ge : greater than or equal (大于等于)
- -le : less than or equal (小于等于)
比较符前面要加空格,如 [ $a -lt $b ] 。
-lt是一种比较符,用来判断一个数字是否小于另一个数字,在bash中使用整数比较时常用到。
其他if参数
还有比如这样的情况
if [ -s $FILE_PATH ]
then
echo "File exists and is not empty"
fi
如果文件存在并且不是0字节大小,那么就会输出 "File exists and is not empty"。
Bash中if判断的时候有很多参数可以使用,
常用的有:
- -e: 判断文件是否存在
- -f: 判断文件是否是普通文件
- -d: 判断文件是否是目录
- -s: 判断文件是否非空 -r: 判断文件是否可读
- -w: 判断文件是否可写
- -x: 判断文件是否可执行
- -z: 判断字符串是否为空
- -n: 判断字符串是否非空
练习1
#!/bin/bash
#如果a小于b就打印666
a=10
b=15
if [ $a -lt $b ]; then
echo "666"
fi
#------------------------------
#如果A等于B就打印A等于0,不是就打印A不等于0
A=10
B=0
if [ $A -eq $B ]; then
echo "A等于0"
else
echo "A不等于0"
fi
#-------------------------------
#read可以录入键盘
echo "请输入一个数字"
read A
if [ $A -eq 6 ]; then
echo "A等于6"
elif [ $A -le 100 ]; then
echo "A小于等于100"
else
echo "A不等于6,大于100"
fi
read -p 命令中的-p选项是用来在读取数据之前显示提示信息的。它会在标准输入之前显示一个指定的字符串,并等待用户输入。
练习2
echo "请输入水的价格"
read S
if [ $S -eq 150 ]; then
echo "正常"
elif [ $S -le 200 ]; then
echo "普通"
else
echo "贵死了!"
fi
6.while循环
在bash中,while循环用来重复执行一组命令,直到指定的条件不成立为止。
语法格式如下:
while [ condition ]; do
commands
done
在这个语法中,condition是循环条件,commands是循环体,do和done是循环的开始和结束符。
当条件成立时,循环体中的命令会被重复执行,直到条件不成立为止。
例如:
#!/bin/bash
n=1
while [ $n -le 5 ]; do
echo "Welcome $n times"
n=$((n+1))
done
在这个例子中,变量n的初始值是1,循环条件是n小于等于5,当条件成立时,循环体中的命令会被重复执行5次,每次循环后n的值会增加1,当n的值大于5时,条件不成立,循环结束。
练习1
运用while循环连续输入5次ls -all命令:
n=1
while [ $n -le 5 ]; do
ls -all
n=$((n+1))
done
在这个例子中,我们定义了变量n,初始值为1. while循环条件是 $n -le 5 ,当条件成立时会执行循环体中的命令 ls -all,并将n加1,重复执行5次,每次循环后n的值会增加1,当n的值大于5时,条件不成立,循环结束。
练习2
while true; do
read -p "请输入水的价格: " A
if [ $A -le 0 ]; then
echo "请输入正确价格"
break
elif [ $A -eq 150 ]; then
echo "正常"
elif [ $A -lt 200 ]; then
echo "普通"
elif [ $A -gt 200 ]; then
echo "贵"
fi
done
在这个例子中,我们使用了read命令来输入水的价格,存储在变量A
中。然后使用了while
循环来重复执行条件判断和输出。 在循环体中,使用了if-elif语句来判断水的价格,如果A
小于等于0就break跳出循环,如果A等于150就输出"正常",如果A
小于200就输出"普通",如果A
大于`200就输出"贵"
也就是说,这个例子使用了while循环和if-elif语句来实现输入水的价格,并判断价格的不同情况。
7.for循环
在bash中,for循环和while循环一样是一种常用的循环结构,用来重复执行一组命令。
语法格式如下:
for variable in list; do
commands
done
在这个语法中,variable是循环变量,list是循环的数据列表,commands是循环体,do和done是循环的开始和结束符。
在循环体中的命令会被重复执行,循环变量每次会获得列表中的下一个值。
例如:
#!/bin/bash
for i in 1 2 3 4 5; do
echo "Welcome $i times"
done
在这个例子中, for循环重复执行了5次,循环变量i每次会获得列表中的下一个值,循环体中的命令会输出"Welcome $i times"
for循环还可以在遍历文件,目录,数组等。
练习
来看看我们练习的bash
#!/bin/bash
for i in {1..10}
do
echo $(expr $i \* 3 + 1);
done
我们使用for循环重复执行了10次。
首先,它使用了#!/bin/bash
来指定脚本使用bash来运行。
然后是for循环,它使用了for i in {1..10}
来创建一个循环变量i,并将它的值从1到10遍历一遍。
在循环体中,它使用了echo $(expr $i \* 3 + 1)
来输出表达式的值,这个表达式计算了i乘3加1的值, 也就是 i*3+1。
然后,每次循环结束后,循环变量i的值会自动更新为下一个数,循环体中的命令会再次执行,直到循环完所有的数。
所以,这段程序使用了for循环来输出1~10中每个数乘3+1的值。
练习2
n=(1 2 3 4 5 6 7 8 9)
sum=0
for i in ${n[@]}; do
sum=expr $sum + $i
done
echo $sum
8.while和for的区别
while循环和for循环都是在bash中常用的循环结构,两者都用于重复执行一组命令。
while循环和for循环的主要区别在于它们的循环条件和循环变量的不同。
while循环是一种条件循环结构,它的循环条件是在循环开始之前就已经确定的,循环体中的命令会一直重复执行,直到条件不成立为止。
for循环是一种遍历循环结构,它的循环条件是在循环开始之前就已经确定的,循环体中的命令会一直重复执行,直到列表中的所有元素都被遍历完为止。
还有就是,对于循环变量的控制来说, while循环中的循环变量需要在循环体之外进行初始化和更新,而for循环中的循环变量是在循环中进行更新的。
总结就是
while循环是一种条件循环结构,用来重复执行一组命令,直到条件不成立。而for循环是一种遍历循环结构,用来重复执行一组命令,直到列表中的所有元素都被遍历完。
写一个case判断
while true; do
read -p "请输入你喜欢的游戏名字(输入q退出):" game
if [ $game == "q" ]; then
break
fi
case $game in
"World of Warcraft"|wow)
echo "《World of Warcraft》是一款大型多人在线角色扮演游戏,拥有超高人气"
;;
"League of Legends"|lol)
echo "《League of Legends》是一款团队对战的多人在线游戏,深受玩家喜爱"
;;
"Overwatch"|ow)
echo "《Overwatch》是一款团队射击游戏,拥有丰富的角色设定和技能系统"
;;
"Apex Legends"|apex)
echo "《Apex Legends》是一款多人吃鸡游戏,深受玩家喜爱"
;;
*)
echo "抱歉,我不知道 $game 是啥"
esac
done
这是一个使用 while 循环和 case 语句的示例。它会不断循环读取用户输入的游戏名字,并使用 case 语句进行判断。如果用户输入 "World of Warcraft" 或 "wow",则输出 "《World of Warcraft》是一款大型多人在线角色扮演游戏,拥有超高人气",如果用户输入 "League of Legends" 或 "lol",则输出 "《League of Legends》是一款团队对战的多人在线游戏,深受玩家喜爱",如果用户输入 "Overwatch" 或 "ow",则输出 "《Overwatch》是一款团队射击游戏。
使用case语句时需要注意以下几点:
- 每个case分支后面需要以双分号(;;)结尾。
- 每个case分支中比较的值需要以单引号(‘)或双引号(")括起来。
- 如果没有匹配到任何case分支,将会执行默认分支,即esac前面的default部分。
- case语句中使用通配符时,只能使用一个星号(*)。
- case语句中可以使用正则表达式来匹配字符串,只需在比较的值前面加一个点号(.)。
- 使用case语句时需要注意值的大小写,默认是区分大小写的。