Linux Shell脚本
一、Shell简介
Shell 是计算机操作系统中用于用户与内核交互的接口,既是命令行解释器(Command Interpreter),也是一种脚本编程语言。它的核心功能是解析用户输入的命令,将其转化为系统调用或程序执行,并返回结果。
Shell脚本编程入门
1.查看Linux系统已提供的shell解释器
cat /etc/shells
2.查看当前系统使用的默认shell解释器
echo $SHELL
1、脚本格式
#!/bin/bash开头(指定解析器)
2、第一个Shell脚本
(1)创建脚本
vim hello.sh
添加:
#!/bin/bash
echo "Hello World"
(2)执行hello.sh脚本(使用解释器执行)
sh hello.sh或bash hello.sh
使用绝对路径执行脚本
sh /root/hello.sh或bash /root/hello.sh
(3)赋予执行权限后执行
chmod +x hello.sh
./hello.sh
(4)使用 source 或 . 执行
source hello.sh
. hello.sh
使用sh或bash时,本质是bash解析器帮你执行脚本,所以脚本本身不需要执行权限;
使用./执行shell时,本质是脚本需要自己执行,所有需要执行权限。
3、第二个Shell脚本(多命令处理)
(1)创建脚本
vim test.sh
添加:
#!/bin/bash
cd /root/
touch test.txt
echo "I love shell" >> test.txt
(2)执行脚本
bash test.sh
cat test.txt
4、Shell中的变量
(1)常用系统变量
echo $HOME
echo $PWD
echo $SHELL
echo $USER
(2)自定义变量
语法:
1.定义变量:变量名=值【注意:= 两边不能有空格】
定义一个变量A,赋值为1
A=1
取变量A的值
echo $A
2.撤销变量:unset 变量名
unset A
3. 声明一个静态变量:readonly 变量名,注意:不能unset,重启系统后失效
定义一个变量B,赋值为2
readonly B=2
取变量B的值
echo $B
定义变量的规则:
- 变量名可以由字母、数字和下划线组成,但不能以数字开头,环境变量名建议大写。
- 赋值符号(=)两边不能有空格。
- 在bash,中变量默认类型都是字符串类型,无法直接进行数字运算。
- 变量的值如果有空格,需要使用双引号或单引号括起来。
- 可把变量提升为全局环境变量,可供其他Shell程序使用。语法:export 变量名
(3)特殊字符($n)
语法:
$n:n为数字,$0代表该脚本名称,$1-9 代表第一个至第九个参数,十以上的参数需要用大括号括起来,如{10}。
案例:
创建脚本
vim inputoutput.sh
添加:
#!/bin/bash
echo "$0 $1 $2"
执行脚本
sh inputoutput.sh a b
(4)特殊变量($#)
$#功能描述:获取所有输入参数的个数;如果定义了参数但未输入,则为0;常用于循环。
案例:
vim inputoutput.sh
添加(在原有基础上添加加粗部分):
#!/bin/bash
echo "$0 $1 $2"
echo $#
执行脚本
sh inputoutput.sh
sh inputoutput.sh a b
(5)特殊变量($*和$@)
$*:将所有参数视为一个整体(单字符串)
$@:将每个参数视为独立的字符串
案例:
vim inputoutput.sh
添加(在原有基础上添加加粗部分):
#!/bin/bash
echo "$0 $1 $2"
echo $#
echo $*
echo $@
执行脚本
sh inputoutput.sh p1 p2 p3
(6)特殊变量($?)
$?:最后一次执行的命令的返回状态。如果这个变量的值为0,证明上一个命令正确执行;如果这个变量的值为非0(具体是哪个参数,由命令自己来决定),则证明上一个命令执行不正确。
案例:
5、运算符
(1)基本语法
“( ( 运算式 ) ) ”或“ ((运算式))”
expr + , - , *, / , % [expr 加,减,乘,除,取余]
注意:expr 与运算的数值及运算符之间要有空格
(2)案例
使用 “( ( 运算式 ) ) ”或“ ((运算式))”进行计算
#加法
#加、除、减
#混合运算
使用expr计算
#加
#减
#乘
#除
#%
# 计算 (2 + 4) * 5 的值
# 先使用``包住括号内的运算,然后在*5
6、Linux bc命令
bc 是一个 高精度计算器语言和工具,通常作为 Unix/Linux 系统的内置命令行计算器。它支持任意精度算术,能够处理大数运算、浮点数计算以及复杂的数学表达式,适用于科学计算、财务分析、脚本编程等场景。
查看帮助
bc --help
-h --help 打印此使用信息并退出
-i --interactive 强制进入交互模式
-l --mathlib 使用预定义的数学例程
-q --quiet 不显示初始标语
-s --standard 非标准 bc 构造是错误的
-w --warn 警告非标准 bc 构造
-v --version 打印版本信息并退出
(1)bc命令的基本用法
启动bc环境
bc 可以在命令行中直接启动。默认情况下,它不会输出计算过程中的每一步结果,直到收到一个表达式并求值后才显示结果。启动 bc 的最简单方式是在命令行中输入 bc,然后按 Enter 键。
进行基本计算
基础运算:+、-、*、/、%(取模)、^(幂运算)
退出bc
要退出 bc,可以使用 quit 命令或者组合键 Ctrl+D
交互式 & 非交互式模式
直接输入 bc 进入交互式计算
通过管道或文件输入(如 echo "5+3" | bc)
#简单计算
#浮点数计算(设置小数位数)
bc中的数学功能
#执行高级数学计算
bc 支持多种数学函数,包括但不限于平方根、指数、对数等。为了使用这些功能,需要在启动 bc 时加入 -l 选项,这将载入数学库
#平方根和指数函数
计算数字的平方根可以使用 sqrt() 函数,计算指数可以使用 ^ 运算符
#处理精度问题
通过设置 scale 变量来调整精度(小数位数)
(2)bc命令的高级用法
在脚本中使用 bc
可以通过将表达式传递给 bc 来从 bash 脚本中调用 bc
创建脚本计算两个变量的乘积
vim bc.sh
添加:
#!/bin/bash
a=5
b=6
result=$(echo "$a * $b" | bc)
echo "The result is $result"
执行脚本计算
7、条件判断
(1)基本语法
[condition] (注意condition前后要有空格)
注意:条件非空即为true,[yuan]返回true,[]返回false
(2)常用判断条件
#两个整数之间比较
#按照文件权限进行判断
#按照文件类型进行判断
(3)案例
#数字比较运算
1 > 2 ?
1 < 2 ?
3 – 1 = 3 ?
#文件权限判断练习
hello.sh文件是否有可写权限?
hello.sh文件是否有可读权限?
hello.sh文件是否有可执行权限?
#文件类型练习
查看 test.txt 文件存在且是一个常规文件?
查看 aaa.txt 文件是否存在
查看/home 是否为一个目录
#多条判断
&&:表示前一条命令执行成功时,才执行后一条命令
||:表示上一条命令执行失败后,才执行下一条命令
8、流程控制
(1)if判断
#基本语法
if [ 条件判断式 ];then# 程序代码
elif [ 条件判断式 ];then# 程序代码
fi
或者
if [ 条件判断式 ]then# 程序代码
elif [ 条件判断式 ]then # ...
fi
注意:
[ 条件判断式 ],中括号和条件判断式之间必须有空格
if 后要有空格
#案例练习
输入一个数字,如果输入的是1、2、3,则输出具体的数字,否则什么也输出
新建一个shell文件,名称为:control_if.sh
vim control_if.sh
添加:
#!/bin/bash
if [ $1 -eq "1" ];thenecho "You entered the number 1"
elif [ $1 -eq "2" ];thenecho "You entered the number 2"
elif [ $1 -eq "3" ];thenecho "You entered the number 3"
elseecho "You entered the other number"
fi
执行control_if.sh脚本
#不加参数执行control_if.sh脚本
#加参数 “1” 执行control_if.sh脚本
(2)case语句
#基本语法
case $变量名 in"值1")如果变了的值等于1,则执行程序1;;"值2")如果变量的值等于2,则执行程序2;;........
esac
#案例
新建control_case.sh脚本
vim control_case.sh
添加:
#!/bin/bash
case $1 in
"1")echo "You entered the number 1";;
"2")echo "You entered the number 2";;
esac
执行control_case.sh脚本
(3)for循环
#基本语法1
for ((初始值;循环控制条件;变量变化))
docommand1command2...commandN
done
#案例
新建control_for.sh脚本
vim control_for.sh
添加:
#!/bin/bash
result=0
for((i=1;i<=100;i++))
doresult=$[$result+$i]
done
echo $result
执行control_for.sh脚本
#基本语法2
for var in item1 item2 ... itemN
docommand1command2...commandN
done
#案例
新建control_for_one.sh脚本
vim control_for_one.sh
添加:
#!/bin/bash
# $* 任意参数(是个整体)
for i in $*
doecho "I love $i"
done
echo "———————————————"
# $@ 任意参数(逐个区分)
for j in $@
doecho "I love $j"
done
执行control_for_one.sh脚本
新建control_for_two.sh脚本(区分$*和$@)
vim control_for_two.sh
添加:
# $*与$@ 不加双引号时看不出来区别
for i in $*
doecho "I love $i"
done
echo "———————————————"
# $@ 任意参数(逐个区分)
for j in $@
doecho "I love $j"
done
echo "———————————————"# $*与$@ 加双引号时区别明显
for a in "$*"
doecho "I love $a"
done
echo "———————————————"
for b in "$@"
doecho "I love $b"
done
执行control_for_two.sh脚本
(4)while循环
#基本语法
while [条件表达式]
do#code
done
#案例(算出1加到100的和)
新建control_while.sh脚本
vim control_while.sh
添加:
#!/bin/bash
i=1
s=0
while [ $i -le 100 ]
dos=$(($s+$i))i=$(($i+1))
done
echo $s
执行control_while.sh脚本
(5)read读取控制台输入
#基本语法
read [选项] [参数]
选项:
-p "提示符":在读取输入之前显示提示信息
-t 超时时间:设置等待输入的秒数,超时后命令退出
参数:
变量名:存储输入内容的变量。如果不指定变量名,默认存入 REPLY 变量
#案例
新建read.sh脚本
vim read.sh
添加:
#!/bin/bash
read -t 10 -p "Please enter your name in ten second: " NAME
if [ -z "$NAME" ];thenechoecho "You didn't enter a name in time"
elseecho "You entered: $NAME"
fi
命令解析:
read -t 10:设置 10 秒超时
-z "$NAME" 检查 NAME 是否为空
执行read.sh脚本
在 10 秒内输入名字(如 aa)
在 10 秒内没有输入
9、Shell函数
Shell 函数是由若干条Shell命令组成的语句块,它实现了代码重用和模块化编程,使得脚本编写更加简洁、高效和可维护。
语法格式:
格式一(简化写法):
函数名() {
函数体(即命令序列)
[return 返回值]
}
格式二(标准写法):
function 函数名() {
函数体(即命令序列)
[return 返回值]
}
在这两种格式中,function 是 Shell 中的关键字,专门用来定义函数;函数名 是你为函数定义的名称,用于在脚本中调用该函数;函数体 是由一系列Shell命令组成的,用于实现函数的具体功能;return 返回值 是可选的,用于从函数中返回一个值。
使用 Shell 函数时,只需在脚本中调用函数名,并传递相应的参数(如果需要的话),函数就会执行其内部的命令序列,并返回结果(如果有返回值的话)。这使得代码更加模块化,提高了代码的可读性和可维护性。
(1)定义函数并调用
vim function_one.sh
添加:
#!/bin/bash
# 定义函数
function f1 {echo "Hello world"
}
# 调用函数打印消息
f1
执行function_one.sh脚本
(2)定义参数传递函数
Shell 函数在定义时不能指定参数,但在调用时可以传递参数。传递参数给函数时,需要在函数名后面以空白分隔给定参数列表。在函数体内部,可以使用特殊变量来接收这些参数。
具体来说,Shell 函数使用 $n 的形式来接收参数,其中 $1 表示第一个参数,$2 表示第二个参数,以此类推。这样,在函数内部就可以通过 $1、$2 等来引用传递进来的参数。
$#:表示传递给函数的参数的个数。
$@ 或 $*:表示传递给函数的所有参数。当它们被双引号 " " 包含时,"$*" 会将所有的参数作为一个整体输出,而 "$@" 会将各个参数分开输出。
创建function_two.sh函数脚本
vim function_two.sh
添加:
#!/bin/bash
my_func() {echo "第一个参数是: $1"echo "第二个参数是: $2"echo "总共有 $# 个参数"echo "所有参数是: $@"
}
my_func arg1 arg2
执行function_two.sh脚本
sh function_two.sh
#!/bin/bash
# 定义函数打印欢迎消息
welcome_message() {echo "Welcome to the script"
}
# 定义一个函数来检查文件是否存在
check_file_exists() {local file_path=$1if [ -f "$file_path" ];thenecho "File $file_path exists"elseecho "File $file_path does not exists"fi
}
(3)案例函数脚本
vim function.sh
添加:
#!/bin/bash
# 定义函数打印欢迎消息
welcome_message() {echo "Welcome to the script"
}
# 定义一个函数来检查文件是否存在
check_file_exists() {local file_path=$1if [ -f "$file_path" ];thenecho "File $file_path exists"elseecho "File $file_path does not exists"fi
}
# 调用函数打印欢迎消息
welcome_message
# 调用函数检查文件是否存在
check_file_exists "/root/file.txt"
执行function.sh脚本
10、echo的输出颜色
(1)基本语法
echo -e “\e[显示方式;前景色;背景色m文本\e[0m”
命令解析:
-e:启用转义字符解析
\e[ 或 \033[:开始 ANSI 颜色代码
显示方式:控制文本样式(如加粗、下划线等),见下方表格
前景色:文本颜色代码(30-37 或 90-97)
背景色:背景颜色代码(40-47 或 100-107)
m:结束颜色代码
文本:你想显示的彩色文本
\e[0m:重置所有样式(避免影响后续输出)
显示方式:
前景色(文字颜色):
背景色:
(2)使用案例
显示方式的使用
前景色的使用
背景色的使用