往期推荐
脚本解释器与变量
脚本文件类似
❝
知道windows下有
.bat
脚本用来批量执行命令的,那Liunx下呢则是使用.sh
脚本来批量执行命令,称为shell脚本
-
创建脚本的方式很多,只需要保证文件类型为 .sh
即可
touch 1.sh
变量的概念
❝
什么是变量?可以理解为一个盒子(a)里面存放的东西为盒子(变量)的值,在Liunx中的变量通常用美元($)搞提醒操作系统他是个变量
-
如果设置全局变量只需要在设置变量的基础上前面加 export
#尝试设置一个临时变量
box=v50
#然后用命令输出他,记得加上美元符号告诉系统他是一个变量
echo$box
引号的概念
单引号
-
使用单引号包裹着变量则不会对变量进行解释(告诉他里面是什么)和赋值(将里面的东西输出)
#尝试设置一个变量
box=v50
#将变量用单引号括起来
echo'$box'
双引号
-
双引号会对其中包含的变量进行解释或替换。默认不带符合则为双引号
#尝试设置一个变量
box=v50
#将变量用双引号括起来
echo"$box"
花括号
-
花括号在变量主要中用于明确边界、条件检索、字符串替换和截取
#尝试设置一个变量
box=v50
#正常我们如果要和变量输出的内容进行贴合(字符wo)话需要空格,而可以使用花括号来明确边界
echo${box}wo
-
条件检索( -
为空使用默认值、+
为空使用赋为默认值、+
返回指定变量的值)
#尝试设置一个变量
box=
#输出一个值为空或者未定义的变量时,默认是无输出的,但是可以使用花括号来进行设置默认值
echo${box:-v50}
脚本解释器
❝
都知道Windows下的bat脚本的解释器是CMD,那么Liunx下的脚本解释器都有什么呢?默认情况下为/bin目录下的
bash
、sh
、dash
-
具体选择那个都可以,也可以注意到 sh
的就解释器是软链接到dash
的
-
在脚本执行的开头指定解释器
#!/bin/bash
#尝试设置一个变量
box=v50
#输出
echo $box
系统变量和字符串
系统变量path
❝
Liunx和windows系统中都有个全局系统变量名为
path
,里面存放了可执行文件的搜索路径,多个路径用:
分隔。
-
如果你想将脚本文件可以在系统的各个位置都可以执行话则需要将脚本的路径添加到 path
中
-
临时添加
#还记得:$PATH表示保留原有的格式
export PATH="/root:$PATH"
2. 永久添加(在原本的基础上添加,或者将脚本移动到他变量的路经(不建议))
#这里的$PATH指引用他原本的变量,使用单引号是不解释他变量
echo'export PATH="$PATH:/root"' >> ~/.bashrc
字符串的概念
❝
字符组成的有序序列的一种变量数据类型,用于表示文本数据。字符串可以包含字母、数字、空格、符号以及其他字符,例如标点符号、特殊符号等。
字符串的定义
-
字符串可以受用单双引号或者无引号包裹,建议使用引号来避免歧义
#其实就是一种类型,只不过使用引号包裹,不仅限于设置变量为字符串,输出的内容也可以为字符串
str="v50"
#但是字符串和变量不是一个道理,输出的变量内容为字符串,但不能为理解为输出字符串
echo$str
字符串的操作
-
输出多个字符串拼接
str="v50"
rts="kfc"
#为什么这里使用了花括号————避免引用变量产生歧义
echo${rts}到了$str
2. 获取字符串长度
str="Linux"
# 输出:长度是:5
echo"长度是:${#str}"
3. 截取子字符串
str="Shell scripting is fun"
# 输出:scripting,从0开始数第六个截取到第九个
echo"${str:6:9}"
4. 查找和替换
str="I love Linux"
#在变量str里面找Liunx替换为Unix
echo"${str/Linux/Unix}"
传参和数值运算
传参的基本概念
❝
可以让脚本更加灵活地处理外部输入。通过位置参数来接收传递给脚本的参数。
位置参数
|
|
---|---|
$0 |
|
$1 |
|
$2 |
|
$3 |
|
... |
|
$# |
|
$@ |
|
$* |
$@ 类似,稍有区别) |
"$@" |
|
"$*" |
|
$? |
|
$$ |
|
传参测试
#!/bin/bash
echo"脚本名称: $0"
echo"第一个参数: $1"
echo"第二个参数: $2"
echo"所有参数($@): $@"
echo"所有参数($*): $*"
echo"参数总数: $#"
echo"命令的退出状态:$?"
echo"命令的退出进程:$$"
数值运算
变量的算数运算
-
使用 $(( ))
进行一个简单的运算,例子使用变量进行,实际上能直接套数值
#!/bin/bash
a=8
b=9
# 加法
sum=$((a + b))
echo"加法:$a + $b = $sum"
# 减法
diff=$((a - b))
echo"减法:$a - $b = $diff"
# 乘法
product=$((a * b))
echo"乘法:$a * $b = $product"
# 除法
quotient=$((a / b))
echo"除法:$a / $b = $quotient"
# 取余
remainder=$((a % b))
echo"取余:$a % $b = $remainder"
-
使用 expr
进行算术运算,例子使用变量进行,实际上能直接套数值 -
运算需要使用空格,且需要对运算符进行转义。
#!/bin/bash
a=5
b=3
# 加法
sum=$(expr $a + $b)
echo"加法:$a + $b = $sum"
# 减法
diff=$(expr $a - $b)
echo"减法:$a - $b = $diff"
# 乘法(*为通配符,需要使用反斜杠转义)
product=$(expr $a * $b)
echo"乘法:$a * $b = $product"
# 除法
quotient=$(expr $a / $b)
echo"除法:$a / $b = $quotient"
# 取余
remainder=$(expr $a % $b)
echo"取余:$a % $b = $remainder"
扩展运算
-
shell计算中默认只能整数,可配合 bc
来进行浮点运算语法:echo "表达式" | bc
#!/bin/bash
# 浮动点数除法,scale为设置小数点后几位
result=$(echo"scale=2; 5 / 2" | bc)
echo"浮动点数除法:5 / 5 = $result"
-
配合 bc
的-l
数学库参数来进行得出算数平方根sqrt
、正弦s
、余弦c
、反正弦a
、对数l
、次方e
、正切j
、反余弦f
、反正切p
、x^y次方x^y
、圆周率PI
#!/bin/bash
# 浮动点数除法,scale为设置小数点后几位,sqrt为计算平方根
result=$(echo"scale=2;sqrt(64)"| bc -l)
echo"64的算数平方根为$result"
-
配合 bc
的-q
参数运算后不显示提示符,即运算后不弹窗
echo"scale=2; 5/7" | bc -q
用户交互与关系运算符
用户交互
❝
意味可以过脚本与用户进行输入和输出的交互。通过提示用户输入信息,并根据用户输入执行相应的操作。
基本交互
-
通过 read
命令来获取用户输入的参数,如读取多个变量则需要使用空格来分隔
#!/bin/bash
echo"请输入你的名字和年龄:"
#依次将输入的内容赋值给变量
read name age
echo"你的名字是:$name,年龄是:$age"
提示交互
-
通过 read
命令来获取用户输入的参数-p
来提供输入前的提示信息
#!/bin/bash
read -p "请输入你的名字:" name
read -p "请输入你的年龄:" age
echo"你的名字是:$name,年龄是:$age"
read全部参数
❝
不同参数之间可以配合使用,例如设置隐藏输入内容和提示信息可以使用
-ps
|
|
---|---|
-p |
|
-s |
|
-t |
|
-i |
|
-r |
|
-a |
|
-n |
|
菜单交互
-
基本语法
select variable in option1 option2 option3 ...; do
# 对应的操作
done
-
简单的操作,无退出操作只能通过ctrl+c退出
#!/bin/bash
# 显示菜单
echo"你要吃什么"
select option in"白米饭""红米饭""叉烧饭";
do
echo"你选择了$option"
done
关系逻辑运算
关系运算符
用于比较两个整数值的大小和相等关系。
|
|
|
---|---|---|
-eq |
|
a -eq b
|
-ne |
|
a -ne b
|
-gt |
|
a -gt b
|
-lt |
|
a -lt b
|
-ge |
|
a -ge b
|
-le |
|
a -le b
|
if条件控制语句
-
还可配合逻辑与关系运算 -
在 [ condition ]
之间一定要有空格,条件和操作符两边都需要空格。
if [ condition ]; then
# 条件成立时执行的命令
elif [ another_condition ]; then
# 如果第一个条件不成立,且第二个条件成立时执行的命令
else
# 如果上述所有条件都不成立时执行的命令
fi
实例
-
[]
可以删掉,在if
前面空格间隔使用test
也一样可以输出,但不推荐使用
#!/bin/bash
a=10
b=20
#判断a是否小于b,为真则输出,假则跳出输出
if [ $a -lt $b ]; then
echo"a 小于 b"
fi
-
配合菜单使用
#!/bin/bash
echo"你要吃什么"
select option in"白米饭""红米饭""叉烧饭"; do
if [ "$option" = "白米饭" ]; then
echo"白白的$option好吃吗?"
elif [ "$option" = "红米饭" ]; then
echo"红红的$option好吃吗?"
elif [ "$option" = "叉烧饭" ]; then
echo"$option我最爱吃!"
else
echo"请你吃大嘴巴子"
break# 退出 select 循环
fi
done
字符运算符与逻辑运算符
字符运算符:
|
|
|
---|---|---|
= |
|
if [ "$str1" = "$str2" ]; then |
!= |
|
if [ "$str1" != "$str2" ]; then |
-z |
|
if [ -z "$str" ]; then |
-n |
|
if [ -n "$str" ]; then |
< |
|
if [[ "$str1" < "$str2" ]]; then |
> |
|
if [[ "$str1" > "$str2" ]]; then |
|
[[ ]] 中) |
if [[ "$str1" == "$str2" ]]; then |
实例
-
判断相等
#!/bin/bash
str1="hallo"
str2="Hallo"
if [ $str1 = $str2 ]; then
echo"相等"
else
echo"不相等"
fi
-
为空判断
#!/bin/bash
str1="hallo"
if [ -n $str1 ]; then
echo"不为空"
else
echo"空"
fi
逻辑运算符
|
|
|
|
|
---|---|---|---|---|
|
|
-a |
&& |
[ condition1 -a condition2 ]
[ condition1 ] && [ condition2 ] |
|
|
-o |
|| |
[ condition1 -o condition2 ]
[ condition1 ] || [ condition2 ] |
|
|
! |
! |
[ ! condition ] |
实例
-
逻辑与运算
#!/bin/bash
x=5
y=8
# 旧语法 - 使用 -a
if [ "$x" -gt 3 -a "$y" -lt 10 ]; then
echo"x 大于 3 且 y 小于 10"
else
echo"条件不成立"
fi
# 现代语法 - 使用 &&
if [ "$x" -gt 3 ] && [ "$y" -lt 10 ]; then
echo"x 大于 3 且 y 小于 10"
else
echo"条件不成立"
fi
for循环与while循环
for循环
基本语法
-
variable
:表示当前循环中的变量,它将依次取list
中的每个值。 -
list
:可以是一个列表,或者是通过命令生成的输出结果。
for variable in list
do#开始
# 执行的命令
done#结束
遍历固定元素列表
-
方法一(不设变量)
#!/bin/bash
for tian in"一""二""三""四""五""六""日"
do
echo"今天星期$tian"
done
-
方法二(设置变量)
#!/bin/bash
# 定义一个数组
fruits=("一""二""三""四""五""六""日")
# ${fruits[@]}使用 for 循环遍历数组
for fruit in"${fruits[@]}"
do
echo"今天星期$fruit"
done
遍历数字范围
-
方法一(不设置变量)
#!/bin/bash
# 遍历数字范围 1 到 10 间隔为2(可以不要)
for i in {1..10..2}
do
echo"数字是 $i"
done
-
方法二(通过 seq生成
):seq [起始值] [间隔] [结束值]
#!/bin/bash
# 使用 seq 生成数字 1 到 10,间隔为 2
for i in $(seq 1 2 10)
do
echo"数字是 $i"
done
遍历命令
-
for循环和Liunx下的命令配合操作,使用命令的输出的当作字符串返回—— $()
#!/bin/bash
data=$(date)
echo"日期:$data"
-
配合for循环使用获取
#!/bin/bash
# 使用 find 查找所有 .txt 文件,并通过 for 循环处理
for txt_file in $(find /etc -name "*.txt")
do
# 输出当前正在处理的文件
echo"正在查看文件:$txt_file"
# 打开文件内容并输出
cat "$txt_file"
echo"===================="# 分隔符
done
(())
配合类似C风格
-
(())
里面可以进行简单的算数运算和条件运算,另外的let命令也可以进行算数运算
简单语法
for ((初始值; 条件; 自变量)) #自变量的值可为: i++ i-- i+=2(每次加2)
do
# 代码块
done
实例
-
从1到100
#!/bin/bash
#i初始值为1,当i小于或等于100时就do一次,然后i自增
for ((i=1;i<=100;i++))
do
echo"$i"
done
while循环
基础语法
#直到条件不成立(假)时停止运行,或者使用循环终止
while [ 条件 ]
do
# 需要重复执行的命令
done
循环输出数字
#!/bin/bash
i=1
while [ $i -el 5 ]
do
echo"i = $i"
((i++)) # 自增 i
done
终止语句配合使用
-
break
终止当前循环
#!/bin/bash
i=0
whiletrue#设置永为真
do
echo"当前值:$i"
if [ $i -eq 12 ]; then#内嵌条件判断
echo"i 等于 5,终止循环"
break# 当 i 等于 5 时终止循环
fi
let i+=2 #上方条件不符合进行运算
done
echo"跳出while循环"
-
continue
跳出本次循环,并回到循环。
#!/bin/bash
i=1
while [ $i -le 50 ] #小于50则循环
do
if [ $((i % 5)) -eq 0 ]; then#i除5的余等于0时执行一次
echo"$i为5的倍数"
((i++))
continue# 跳出本次循环(while后面语句都的都不执行了,重新再执行一次while)
fi
echo"当前值为:$i"
((i++))
done
配合|
管道符使用
#!/bin/bash
cat /etc/apt/sources.list | whileread line #read逐行读取cat输出的内容
do
let i++
echo"第$i行:$line"
done
until循环与case判断
until循环
基本语法
until [ condition ]
do
# commands当条件不成立才退出
done
数值累加
#!/bin/bash
sum=0 i=1
until [ $i -gt 10 ] #知道满足条件退出循环
do
sum=$((sum + i))
let 1++
done
echo"1 到 10 的和是:$sum"
case判断
基本语法
case$variablein
pattern1)
# 处理匹配到 pattern1 的情况
;;
pattern2)
# 处理匹配到 pattern2 的情况
;;
*)
# 默认情况下执行的代码
;;
esac
根据输入执行相应操作
#!/bin/bash
# 显示菜单
echo"需要执行的操作"
select option in"安装""修复""卸载";
do
case$optionin
安装)
echo"正在安装中..."
sleep 2 #等待两秒
break
;;
修复)
echo"正在修复中..."
sleep 2 #等待两秒
break
;;
卸载)
echo"正在卸载中..."
sleep 10 #等待10秒
break
;;
*)
echo"已退出操作"
exit#关闭脚本
;;
esac
done
封装函数与脚本调用与重定向
封装函数
❝
函数封装就是指将一段可重用的代码放入一个函数中,并通过函数的参数和返回值来与外部的代码进行交互。
基本语法
-
封装方法一
function_name() { #封装函数
# commands
}
function_name(传递的参数) #调用
-
封装方法二
function function_name { #封装函数
# commands
}
function_name(传递的参数) #调用
实例
-
日志打印
#!/bin/bash
# 定义日志打印函数
log_message() {
#local定义局部变量
local log_level=$1#参1
local message=$2#参二
echo"[$log_level] $(date): $message"
}
# 调用日志函数
log_message "INFO""脚本开始执行"
log_message "ERROR""文件未找到"
log_message "DEBUG""正在调试模式"
2. 备份文件脚本
#!/bin/bash
# 定义备份函数
backup_file() {
local source_file=$1
local backup_file=$2
if [ ! -f "$source_file" ]; then
echo"错误:源文件 $source_file 不存在"
return 1
fi
# 执行备份
cp "$source_file""$backup_file"
echo"文件已成功备份:$source_file 到 $backup_file"
}
read -p "要备份的文件:" file
read -p "备份的路径:" dir
# 调用备份函数
backup_file "$file""$dir"
脚本调用
-
用一个脚本调用另一个脚本的输出结果
#!/bin/bash
# 显示菜单
echo"需要执行的操作"
select option in"安装""卸载";
do
case$optionin
安装)
./2.sh #.会新的子 Shell 中执行目标脚本,变量会与当前脚本不冲突
break
;;
卸载)
source 3.sh #source会加载另一个脚本文件的内容并在当前 Shell 中执行,变量可复用
break
;;
*)
echo"已退出操作"
exit#关闭脚本
;;
esac
done
2. 从另一个脚本中定义变量执行当前脚本
#!/bin/bash
# 显示菜单
echo"需要执行的操作"
select option in"安装""卸载";
do
case$optionin
安装)
./2.sh #.会新的子 Shell 中执行目标脚本,变量会与当前脚本不冲突
echo$test
break
;;
卸载)
source 3.sh #source会加载另一个脚本文件的内容并在当前 Shell 中执行,变量可复用
echo$test
break
;;
*)
echo"已退出操作"
exit#关闭脚本
;;
esac
done
重定向操作
重定向操作符
|
|
|
|
---|---|---|---|
|
0 |
|
cat < input.txt |
|
1 |
|
echo "Hello, World!" > output.txt |
|
2 |
|
ls nonexistent_file 2> error.log |
-
标准输入(将文本的内容当作命令的执行变量)
ls -l < 3.txt
-
标准输出(将命令执行的输出重定向到文件里面)
ls > z.txt
3. 标准错误(命令执行失败将报错重定向到文件内)
nmap 2> 1.txt
4. 组合使用
ls > 2.txt 2>1.txt
nmap > 2.txt 2>1.txt
文件运算符(扩展)
1. 文件存在性和类型测试运算符
|
|
|
---|---|---|
-e FILE |
|
[ -e /path/to/file ]
|
-f FILE |
|
[ -f /path/to/file ]
|
-d FILE |
|
[ -d /path/to/dir ]
|
-s FILE |
|
[ -s /path/to/file ]
|
-L FILE |
|
[ -L /path/to/file ]
|
-h FILE |
-L 与 -h 功能相同)。 |
[ -h /path/to/file ]
|
-p FILE |
|
[ -p /path/to/file ]
|
-c FILE |
|
[ -c /path/to/file ]
|
-b FILE |
|
[ -b /path/to/file ]
|
-w FILE |
|
[ -w /path/to/file ]
|
-r FILE |
|
[ -r /path/to/file ]
|
-x FILE |
|
[ -x /path/to/file ]
|
-u FILE |
|
[ -u /path/to/file ]
|
-g FILE |
|
[ -g /path/to/file ]
|
-k FILE |
|
[ -k /path/to/file ]
|
-O FILE |
|
[ -O /path/to/file ]
|
-G FILE |
|
[ -G /path/to/file ]
|
-N FILE |
|
[ -N /path/to/file ]
|
2. 文件比较运算符
除了用于文件属性的测试外,还有一些文件比较运算符,用于比较两个文件的内容或属性。
|
|
|
---|---|---|
FILE1 -nt FILE2 |
|
[ /path/to/file1 -nt /path/to/file2 ]
|
FILE1 -ot FILE2 |
|
[ /path/to/file1 -ot /path/to/file2 ]
|
FILE1 -ef FILE2 |
|
[ /path/to/file1 -ef /path/to/file2 ]
|
附录
OSCP培训
学习没思路?安全不知道怎么学习的朋友可以了解一下OSCP证书课程一次报名后续相关的课程都免费哦,咨询也不吃亏。实在不放心还可以关注公众看一下我们零开始到红队的公益课程不含任何费用公众号
帮会
也可以了解一下我们帮会,是真正的红队大佬创建的,里面会定时丢些网上没有的工具。以及文章中包含的所有工具
聊天群聊
加入群聊一起交流学习,有什么疑问可以一起交流。
原文始发于微信公众号(泷羽Sec-小篮子):shell脚本基础用法
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论