
【Shell 】基础知识
Shell 脚本
1. Shell 概述
Shell 是用户与操作系统内核之间的接口,它接收用户输入的命令并将其传递给操作系统执行。而 Shell 脚本就是一系列命令的集合,将这些命令按照一定的逻辑顺序编写在一个文本文件中,就形成了一个 Shell 脚本。通过执行这个脚本文件,系统会依次执行其中的命令,从而完成特定的任务。
- 自动化任务:可以编写脚本自动完成一些重复性的工作,如文件备份、系统更新、日志清理等。例如,每天定时备份重要文件到指定的存储位置。
- 系统管理:用于管理系统资源,如监控系统性能、创建和管理用户账户、配置网络等。
- 软件安装与部署:可以编写脚本来自动化软件的安装过程,确保在不同的环境中都能一致地安装和配置软件。
2. 用户和硬件之间的关系

3. 脚本区别和环境确定
针对于环境变量, 在 Linux 中有两个相关的脚本文件
- 系统配置脚本文件
/etc/profile
- 针对于整个 Linux 系统的相关配置文件,如果修改之后,可以利用重启当前 Linux 系统操作完成相关配置生效。针对与普通用户基本无需操作
- 当前用户的配置脚本文件
~/.bashrc
- 针对于每一个用户,在各自的家目录下都有一个
.bashrc
脚本环境配置文件,当前配置文件有且只针对于当前用户有效,其他用户无效,同时当前脚本的作用不会影响整个操作系统。

确认当前系统采用的脚步解析方式/脚本执行方式
echo $SHELL
执行效果
当前 Linux 解析执行脚本默认的方式为 bash 方式。
4. 和脚本见一面
脚本案例
#!/bin/bash
# 脚本注释
echo "Hello World!"
echo "你好,世界"
num=100
echo "num is $num"
read str
echo "str is $str"
# 脚本中文支持一般,通常情况下,不会在脚本中出现中文字符。
5. 脚本执行方式
脚本执行方式常用有三种
脚本文件直接执行,需要当前脚本具备可执行权限。
chmod 775 XXX.sh chmod +x xxx.sh # 以上两种方式都可以加入可执行权限
利用
bash
,sh
执行当前文件bash xxx.sh
. xxx.sh
利用 . + 空格执行目标脚本文件. xxx.sh
6. shell 自定义变量
直接自定义变量操作
#!/bin/bash
num=100
# 定义了一个变量 num 同时完成赋值操作 100
# 【注意】 = 两端不得有空格,否则 shell 语法报错
# 如果需要展示打印对应的变量存储数据,需要利用 $variable
echo "num is $num"
echo num is $num
num=200
echo "num is $num"
echo num is $num
read 定义变量,且从终端直接获取用户输入的数据内容
echo "Please input string : "
read str # 从键盘上获取用户输入的数据内容,存储到 str 变量中
echo "str value : $str"
export 变量,是将目标变量【临时】作为当前终端的环境变量,当前终端其他的程序可以使用。如果当前终端关闭,或者在其他终端中无法使用 export 临时生效的环境变量
04-export_var.sh
#!/bin/bash
export_var=2000
export export_var
05-var_test.sh
#!/bin/bash
echo "export_var is $export_var"
生效方式
- 执行 04-export_var.sh,
. 04-export_var.sh
或者直接source 04-export_var.sh
- 执行 05-var_test.sh 可以看到临时环境变量 export_var
7. 系统预设环境变量
以下为常用的系统预设环境变量
#!/bin/bash
echo "当前用户的家目录为 : $HOME"
echo "当前工作目录为 : $PWD"
echo "当前登录的用户名为 : $LOGNAME"
echo "当前 Linux 默认脚本解析工具 : $SHELL"
echo "当前主机名 : $HOSTNAME"
8. $预设变量
$n
:n 是一个整数,获取终端执行脚本的
$*
: 获取当前执行脚本所有的参数内容
$$
: 当前脚本对应的系统 PID 进程号
$?
: 获取上一条指令执行是否成功,成功返回 0 ,失败返回 1
#!/bin/bash
# 授予当前脚本文件权限之后执行。
# ./07-$var.sh aaa bbb ccc ddd
# 整个脚本执行对应的参数个数为 5 个
# 对应的下标范围是 0 ~ 4
# 下标 0 ==> ./07-$var.sh 下标 2 ==> bbb
echo "当前脚本文件名称为 : $0"
echo "当前脚本执行第一个参数: $1"
echo "当前脚本执行第二个参数: $2"
echo "当前脚本执行第三个参数: $3"
echo "当前脚本执行第四个参数: $4"
echo "当前脚本执行所有参数: $*" # 会获取所有的参数,但是不包括 $0
echo "当前脚本执行对应的程序 PID(Process ID)/进程号 $$"
echo "-----------------------------------------------"
ls -l
echo "之前的命令是否执行成功 成功(0) 失败/错误(1): $?"
cd /root
echo "之前的命令是否执行成功 成功(0) 失败/错误(1): $?"
9. 脚本变量的特殊用法
""
字符串内部变量会被解释
''
整个内容当做字符串处理,不会解释其中的变量内容
转义字符
转义字符如果需要生效,必须有对应的 shell 脚本参数 -e
()
内部修改外部定义的变量,对于外部无影响
{}
内部修改外部定义的变量,对于外部有影响
#!/bin/bash
num=100
echo "num is $num" # 当前使用的是双引号,内部的变量数据会被 shell 解释
echo 'num is $num' # 整个文本都是当做字符串数据进行处理
echo "date : `date`" # 解释当前 Shell 预设的变量 date
# 转义字符 \n \t \\ \" \' \a
# 如果需要转义字符串生效,必须使用 -e shell 脚本操作
echo -e "Text \n Text"
echo -e "\a"
# () {} 的区别
ret=200
# 小括号中修改的外部变量内容,有且只在小括号内部有效,对于外部数据无效
(
ret=300
echo "ret : $ret"
ymc=150
)
echo "ret : $ret"
# 大括号修饰的变量内容,内外都有效
yqc=200
{
yqc=300
echo "yqc : $yqc"
yqm=100
}
echo "yqc : $yqc"
echo $ymc + $yqm # ?
命令作为参数时需要加``而不是单引号
10. 条件判断
两种方式
test 标记 内容
[ 标记 内容 ]
要求中括号内部到判断语句必须有空格
注:test -n命令是字符串的长度不为零则为真
test -n没有参数时,默认返回 0(真)
10.1 文件
在文件操作中使用的判断标记
-e 是否存在 -d 是目录 -f 是文件 -r 可读 -w 可写 -x 可执行 -L 符号连接 -c 是否字符设备 -b 是否块设备 -s 文件非空,如果文件为空,$? 为 1 ,如果文件不为空,$? 为 0
#!/bin/bash
test -e /home # 判断指定路径文件或者文件夹是否存在
echo $? # 获取上一条指令执行是否成功,成功返回 0 ,失败返回 1
test -e /home/qq # 判断指定路径文件或者文件夹是否存在
echo $?
test -d ~
echo $?
test -f ~
echo $?
test -f ~/.bashrc
echo $?
[ -r ./01-test.sh ]
echo $?
[ -w ./01-test.sh ]
echo $?
[ -x ./01-test.sh ]
echo $?
[ -s ../02/1.txt ]
echo $?
10.2 字符串
字符串判断使用的判断标记
= 两个字符串相等 != 两个字符串不相等 -z 空串 -n 非空串
#!/bin/bash
str1="ABC"
str2="ABC"
test $str1=$str2
echo $?
[ "123" != "234" ]
echo $?
[ "123" != "123" ]
echo $?
echo "----------------------------------------------"
# [ -z $str1 ] #
[ -z $str10 ]
echo $?
str3="123"
[ -z $str3 ]
echo $?
str5=""
[ -n "$str5" ]
echo $?
10.3 数据
数据判断使用的判断标记
-eq # equal 数值相等 -ne # not equal 数值不相等 -gt # greater than 数 1 大于数 2 -ge # greater equal 数 1 大于等于数 2 -le # less equal 数 1 小于等于数 2 -lt # less than 数 1 小于数 2
#!/bin/bash
num=10
[ $num -eq 10 ]
echo $?
[ $num -ne 10 ]
echo $?
[ $num -gt 8 ]
echo $?
[ $num -lt 8 ]
echo $?
[ $num -le 10 ]
echo $?
[ $num -ge 10 ]
echo $?
10.4 组合判断/复合判断
组合判断
&&:
command1 && command2
&&左边命令(command1)执行成功(即返回 0)shell才执行&&右边的命令(command2)||
||左边的命令(command1)未执行成功(即返回非 0)shell才执行||右边的命令(command2)
逻辑判断
条件 | 作用 |
---|---|
-a | 类似于逻辑与操作 |
-o | 类似于逻辑或操作 |
! | 类似于取反操作 |
#!/bin/bash
num1=10
num2=20
# && 第一个条件如果成立,&& 符号之后的内容执行
[ $num2 -gt $num1 ] && echo "&& 测试"
# || 第一个条件不成立,|| 符号之后的内容执行
[ $num2 -lt $num1 ] || echo "|| 测试"
echo "----------------------------------------------------"
num3=100
num5=200
test $num1 -lt $num2 -a $num3 -lt $num5
echo $?
[ $num1 -lt $num2 -a $num3 -lt $num5 ]
echo $?
[ 10 -gt 15 -o 10 -gt 15 ]
echo $?
[ ! 10 -gt 5 ]
echo $?
declare -i num
read num
11. 控制语句
11.1 if 分支结构
格式有三种
if [ 条件判断 ]; then
# 处理方式
fi # finish if
if [ 条件判断 ]; then
# if 处理方式
else
# else 处理方式
fi # finish if
if [ 条件判断 1 ]; then
# if 处理方式
elif [ 条件判断 2 ]; then
# elif 处理方式
else
# else 处理方式
fi # finish if
案例代码
#!/bin/bash
echo "请输入一个整数 : "
read num
if [ $num -gt 10 ]; then
echo "用户输入数据大于 10"
fi
echo "---------------------------------------------"
echo "请输入一个整数 : "
read num1
if [ $num1 -gt 20 ]; then
echo "用户输入数据大于 20"
else
echo "用户输入数据不大于 20"
fi
echo "---------------------------------------------"
echo "请输入一个整数 : "
read num3
if [ $num3 -ge 100 ]; then
echo "送闫某昌一位"
elif [ $num3 -ge 90 ]; then
echo "送某齐昌一位"
else
echo "送闫齐某一位"
fi
11.2 case 控制语句
格式
case $变量 in
"第一个选项")
处理方式
;;
"第二个选项")
处理方式
;;
*)
最终处理方式
;;
esac
#!/bin/bash
# 需要授予权限执行当前脚本程序
echo "脚本执行第一个参数内容 : "
# $1 是获取第一个参数
case $1 in
"闫")
echo "喜提研究僧"
;;
"齐")
echo "刚果金社区幼儿园"
;;
"昌")
echo "育儿班"
;;
*)
echo "长江大学"
;;
esac
11.3 for 循环
格式
for (( 初始化; 限制值; 步进关系 ))
do
执行语句
done
案例代码
#!/bin/bash
declare -i sum
for (( i=1; i<=100; i=i+1 ))
do
sum=sum+i
done
echo "Sum : $sum"
echo "-------------------------------------"
# 当前循环 i 在 in 之后的数据范围以内,并且逐一遍历
for i in 1 2 3 4 5 6 7 8 9
do
echo $i
done
echo "-------------------------------------"
# `ls` 是执行目标 Linux 命令,获取当前文件列表
# 循环是将文件列表中的每一个文件或者文件夹名称获取
# if 分支完成对应的分类处理操作
for file_name in `ls`
do
if [ -f $file_name ]; then
echo "$file_name is File"
elif [ -d $file_name ]; then
echo "$file_name is Dir"
fi
done
11.4 while 循环 和 until 循环
格式
while [ condition ]
do
执行语句
done
格式
until [ condition ]
do
执行语句
done
- while 循环控制是条件满足时,代码执行语句可以运行
- until 循环控制是条件不满足是,执行对应的语句,【直到】条件满足终止
#!/bin/bash
declare -i begin
declare -i end
begin=1
end=10
while [ $begin -lt $end ] # 执行
do
begin=begin+1
echo "while 循环结构执行中..."
done
echo "-------------------------------------------------------"
begin=1
end=10
until [ $begin -lt $end ] # 不执行
do
begin=begin+1
echo "until 循环结构执行中..."
done
echo "-------------------------------------------------------"
begin=1
end=10
while [ $begin -lt $end ] # 执行
do
begin=begin+1
echo "while 循环结构执行中..."
done
echo "-------------------------------------------------------"
begin=1
end=10
until [ $begin -gt $end ] # 执行
do
begin=begin+1
echo "until 循环结构执行中..."
done
11.5 break 和 continue
有且只允许操作和 C/C++ 一致
12. 函数
格式
- 函数和 C/C++ 一样,都要求有对应的返回值类型,函数名和参数类型,但是 shell 中对于返回和参数类型非常的【自由】
- 函数参数取决于用户提供的参数情况,且按照和执行脚本一样的参数获取方式进行提取操作。脚本执行的参数是 0 1 2.... 1 对应函数中第一个参数
- 返回值取决于用户在函数内部进行的数据反馈
函数名 ()
{
}
function 函数名()
{
}
案例代码
#!/bin/bash
# 函数声明 + 实现
is_dir()
{
# 判断当前用户提供的参数个数小于 1,直接返回 1,错误状态
if [ $# -lt 1 ]; then
return 1
fi
# 如果当前第一个参数路径对应的是一个文件夹,返回 2
if [ -d $1 ]; then
return 2
else
return 3 # 普通文件返回 3
fi
}
echo "请输入路径 : "
read filepath
# 函数调用,需要提供函数名和对应的参数,不需要小括号
# is_dir 函数名 $filepath 是函数参数,对应 $1
is_dir $filepath
echo "函数运行结果 : $?"
- 感谢你赐予我前进的力量