【网络安全】Shell 脚本学习
声明:学习视频来自 b 站 up 主 泷羽 sec,如涉及侵权马上删除文章
声明:本文主要用作技术分享,所有内容仅供参考。任何使用或依赖于本文信息所造成的法律后果均与本人无关。请读者自行判断风险,并遵循相关法律法规。
脚本创建执行与变量使用
首先进入Linux终端【Windows系统可以使用MobaXterm中的zsh/bash终端】,可以使用 vim 创建一个 .sh 结尾的文件。
在文件的第一行写入下列三种中的其中一种,这些是脚本解释器
#!/bin/bash
等是一个特殊的行,称为 shebang(也称为 hashbang)。它出现在脚本文件的第一行。这一行的作用是告诉操作系统应该使用哪个解释器来执行这个脚本。
#!/bin/bash
#!/bin/dash
#!/bin/sh
- 在许多 Linux 系统中,
/bin/sh
(传统的 Bourne shell)实际上是指向/bin/dash
的符号链接。dash
(Debian Almquist Shell)是一个轻量级的 shell,它被设计用来提供基本的脚本执行功能,并且在启动速度和资源占用方面有一定的优势。 - 当一个脚本没有指定解释器(即没有
#!/bin/bash
或其他明确的解释器路径的 shebang 行),系统会默认使用/bin/sh
来解释执行这个脚本。由于/bin/sh
常常是/bin/dash
的链接,所以在这种情况下,脚本实际上是由dash
来执行的。
如果终端安装了 zsh 等其他脚本解释器,可以使用 #!/bin/zsh
来进行解释,或者 依然也可以使用 #!/bin/bash
等,此时执行时,依然会使用 bash 进行脚本解释,zsh 只会充当一个调用的角色。
在执行 .sh 结尾的shell 脚本时,有两种方式:
chmod +x xxx.sh
添加执行权限后,使用./xxx.sh
执行- 使用脚本解释器直接执行
sh xxx.sh
/bash xxx.sh
/zsh xxx.sh
source xxx.sh
,该命令与使用 脚本解释器直接执行效果一致,唯一不同的地方在于该命令会将输出内容进行不同颜色标注。
变量
声明变量 name="d1"
使用变量 echo $name
/ echo "my name is $name"
如果使用双引号和不使用双引号的效果是一样的,都会将变量进行替换为变量值;
但如果是单引号,就不会对变量进行解析。
变量拼接
echo "my name is $name,and my age is $ageyears old"
上述例子中,变量age和字符串years之间没有空格,因为会导致解析为空,因为没有定义变量,解决办法是 使用 双引号 或 大括号 将变量引起来
echo "my name is $name,and my age is "$age"years old"
echo "my name is $name,and my age is {$age}years old"
但是使用花括号引起来的方式,在输出时,变量内容会被显示在花括号中
以上所述变量均为临时变量,变量由数字、字母和下划线组成,但不能以数字开头,也不能中间存在空格,可以使用下划线代替。
查看定义的变量
如果在终端直接定义变量,那么需要查看定义的变量时,可以使用
set | grep name
删除变量
unset name
永久环境变量和字符串显位
Windows中的环境变量在 path 下添加
which ls
在Linux下查看ls命令所在位置
echo $PATH
Linux输出环境变量
查看输出结果存在/usr/bin目录什么意思呢就是当我们执行ls它会帮我们找到对应得目录做一个执行,也就是ls的完整路径应该是/usr/bin/ls脚本
根据上述描述,我们可以直接将我们的脚本添加至环境变量使其可以直接执行:
- 将写好的脚本 1.sh 移动到环境变量
/usr/bin
等任意一个目录下,就可以在终端直接执行 1.sh - 将整个目录都添加到环境变量中,这样整个目录下的文件都可以直接执行。例如:将
/root/
目录添加到环境变量中,/usr/bin:/bin:/usr/bin:/drives/c/windows:/root/
;- 使用命令
export PATH=/root:$PATH
export
命令是一个用于设置环境变量的关键字,使得设置的变量可以在当前shell以及由该shell启动的子进程中生效。- PATH:这是一个非常重要的环境变量,它定义了系统在哪些目录下去寻找可执行程序。当你在命令行输入一个命令(如Is、cat等)时,系统会根据PATH环境变量所指定的目录顺序去查找对应的可执行文件,找到后就执行它。
- /root:$PATH:这里是在重新定义PATH的值。它将/root目录添加到了原有的PATH变量值的最前面(假设原有的PATH值存储在变量PATH中,这里通过:PATH的形式保留了原来的值并添加了新的部分)。这样做的结果是,当系统去查找可执行程序时,会先在/root目录下查找,然后再按照原来PATH所指定的其他目录顺序查找。
- 使用命令
永久变量
修改用户配置文件(~/.bashrc
或 ~/.bash_profile
):
- 对于 bash
用户,通常可以在用户主目录下的 ~/.bashrc
或 ~/.bash_profile
文件中添加目录到环境变量。如果使用的是 zsh
,则是 ~/.zshrc
。以 bash
为例,使用文本编辑器(如 vi
或 nano
)打开 ~/.bashrc
文件。
vi ~/.bashrc
- 在文件末尾添加以下行(假设要添加
/home/user/permanent_bin
目录):
export PATH=$PATH:/home/user/permanent_bin
- 保存并退出文件后,要使修改生效,可以在终端中运行
source ~/.bashrc
。这样,以后每次打开新的终端会话,/home/user/permanent_bin
目录都会自动添加到PATH
中。
修改系统配置文件(全局设置,谨慎操作):- 在某些情况下,可能需要为系统的所有用户添加目录到环境变量。这可以通过修改系统级别的配置文件来实现,如
/etc/profile
或/etc/environment
。 - 例如,在
/etc/profile
文件中添加目录路径。使用文本编辑器打开/etc/profile
:
- 在某些情况下,可能需要为系统的所有用户添加目录到环境变量。这可以通过修改系统级别的配置文件来实现,如
vi /etc/profile
- 找到合适的位置,添加类似以下的内容(假设要添加
/systemwide/bin
目录):
export PATH=$PATH:/systemwide/bin
- 保存并退出后,这个目录就会被添加到所有用户的环境变量
PATH
中。不过,修改系统配置文件可能会影响整个系统的运行,需要谨慎操作。
字符串相关操作
假设我们想知道一个字符串的长度,比如我们想解析一个字符串的长度我们如何进行实现?
比如 name="D1" age=27
然后我们通过 echo "my name is $name,and i am $age years old"
打印完整字符串
str="hello world"
echo ${#str}
输出字符串 str 的长度
echo ${str:0:3}
输出前三个字符
脚本参数传递与数学运算
向脚本程序传递参数如何实现?
echo 执行的文件名是:$0
echo 第一个参数是:$1
echo 传递的参数作为一个字符串显示:$*
echo 传递的参数独立作为每个字符串显示:$@
echo 传递到脚本的参数个数是:$#
echo 最后命令的退出状态:$?
echo 脚本运行的当前进程ID是:$$
将上述内容添加到 2.sh 脚本中
执行脚本时, ./2.sh 1 2
这样,2.sh是第一个参数,但不是传入的第一个参数,因此 $0 就是 2.sh ,1 是传入的第一个参数,因此 $1 就是 1。
由此得出 参数传递一般为 $n(n表示数字 可递增)
,$*
就是将参数当作统一的字符串显示出来,而 $@
是将每个字符串当作独立的字符串显示这也是 $*
和 $@
的区别,$#
代表参数的个数,$?
是查看命令执行状态的,如果显示为0那么命令就是正常执行的,其他数字就是出错了,$$
就是查看脚本当前进程id的。
在shell中进行数学运算
在shell编程中,利用expr进行运算
expr 5+10
回显 5+10
而 expr 5 + 10
这样写就行了5(空格)+(空格)10
以上方法适用于加法减法,如果用乘法就会报错。
expr 6\*6
(乘法是用\*
python直接使用 *
就行了,而shell要用\进行转义)
除法:
expr 6 / 3
/ 是取整数
expr 6 % 3
% 是取余
混合运算
expr ( 5 + 7 ) \* 2
这样会报错,括号依然需要转义 expr \( 5 + 7 \) \* 2
通过变量进行运算
需要将变量内容赋值为运算表达式,使用反引号,这样在调用时,就可以直接得到运算结果。
脚本与用户交互以及 if 条件判断
使用shell脚本进行交互
利用read name age指定变量信息xiaoyu 26 ,然后利用echo $name
和 echo $age
来接收用户输入。
利用read -p "请输入您的姓名" name age
输入:xiaoyu 80 【这种方式输入时,需要用空格将两个变量分开,且一次性输入】
echo $name(接收用户的输入)
-p 用于输出后面的内容
-t 用于指定用户输入的事件,超时自动退出
-n 用于限制用户输入内容的长度
关系运算符
首先定义两个变量,然后通过if条件判断来进行两个变量直接的判断,只能对数值进行判断,无法对字符进行判断。
-eq 相等
-lt 小于
-gt 大于
-ne 不等于
else 反转
num1 = 28
num2 = 36
if [ "$num1" -eq "$num2" ] ;then
echo 相等
else
echo 不相等
fi
字符串运算和逻辑运算符
字符串运算
注意方括号后的空格,以及分号后面的空格,还有变量的引号
str1="hello"
str2="hello"
if [ "$str1" = "$str2" ]; then
echo True
else
echo False
fi
注意:Linux大小写敏感
str1="hello"
str2="hello"
if [ -z "$str1" ]; then
echo True
else
echo False
fi
-z 参数,用于检查变量长度是否为零
-n 参数,检查变量长度是否不为零,与-t相反
str1="hello"
str2="hello"
if [ "$str1" ]; then
echo True
else
echo False
fi
不设置任何参数,如果 str1为空,则返回 False,不为空,返回True。
逻辑运算
布尔运算
num1=9
if [ "$str1" != "9" ]; then
echo num1不等于9
else
echo num1等于9
fi
余运算
num1=9
num2=19
if [ "$str1" != "9" -a $num2 -lt "20" ]; then
echo True
else
echo False
fi
同时满足 $num1 != 9 -a $num2 -it 20
输出true,不满足返回false
与之相反的参数是-o参数,只需要满足其中一个就可以返回true两个都不满足就返回flase
if 条件判断与 for 循环结构
if 条件判断
#!/bin/bash
# 定义变量
a=10
b=20
# 进行条件判断
if [ "$a" -eq "$b" ]; then
echo "a=b"
elif [ "$a" -gt "$b" ]; then
echo "a>b"
else
echo "没有符合上述条件"
fi
bash 脚本中,通过 “变量名=值” 的方式就可以完成变量的定义和赋值。
for 循环
for num in 1 2 3 4 5
do
echo "The number is $num"
done
这是一段使用for循环的代码片段,常见于Shell脚本(如bash脚本)中,用于对一系列的值进行迭代操作。
循环语句 for num in 1 2 3 4 5
:
for:是循环的关键字,用于开启一个for循环结构。
num:定义了一个循环变量,在每次循环迭代过程中,这个变量会被赋予不同的值。
in 1 2 3 4 5 :指定了个值的列表,循环变量。num将会依次取这个列表中的每一个值,num会先被赋值为1,然后进行第一次循环;接着num会被赋值为2,进行第二次循环,以此类推,
直到num取完列表中的最后一个值5。
循环体
do:是与for循环起始语句配合使用的关键字,它标志着循环体的开始。在do和后面的done之间的语句就是每次循环时需要执行的操作。
输出语句 echo "The number is Snum"
:
echo:是一个用于在终端输出信息的命令。
循环结束
done:是for循环的结束关键字,它标志着整个for循环过程结束。
for str in "hello world"
do
echo $str
done
上述循环中,str 只会被赋值一次,其赋值为字符串,因为值列表中只有一个字符串。
for循环与while循环
for i in `seq 1 100`
do
echo $i
done
for i in $(seq 1 100)
do
echo $i
done
上述两种写法的作用都是一样的,使 i 从1取值到100,并输出。
for ((i=1; i<100; i++))
do
echo $i
done
在for循环的双括号语法(())中:
初始化部分i=1是给循环变量i赋初值为1。
条件判断部分i<100表示只要i的值小于100,循环就会继续执行。
选代部分i++是每次循环结束后让i的值自增1,这样就能实现从1开始,每次增加1,直到1达到99(因为当1等于100时就不满足<100这个条件了),并在每次循环中通过echo输出i的当前值。
while 循环
i=1
while (( $i<=10 ))
do
echo $i
((i++))
done
i=1
while (( $i<=10 ))
do
echo $i
let "i++"
done
代码(1)
变量初始化:
首先通过i=1这一行,将变量i初始化为1,为后续的循环操作确定起始值。
循环条件判断:
while(( $i<=10 ))是循环的条件判断部分。这里使用了双括号(())语法,它用于进行算术表达式的计算和判断。在每次循环开始前,都会检查的值是否小于等于10。只要这个条件满足,循环体内部的代码就会被执行。
循环体执行内容:
在循环体内部,首先通过 echo $i 这一行,将当前i的值输出到控制台,这样就可以看到循环过程中 i 的变化情况。
接着,通过((i++))这一语句对变量i进行自增操作。这里的(())语法同样用于算术运算,i++表示将i的值增加1。每次循环结束后,i的值就会比上一次循环时增加1,以便在下次循
环开始时进行新的条件判断。
let 命令用于 执行算术运算符,可以接收一个或多个算术表达式作为参数,并对相关变量执行算术操作。
until 循环以及函数基本创建调用
until 循环
until 直到xxx为止
i=0 # 初始化变量
until [ ! $i -lt 10 ]
do
echo $i
((i++))
done
这段代码使用 until 循环结构,用于在满足特定条件之前重复执行循环体中的操作。
上述代码中,会不断输出 i 的值,并对 i 的值进行自增,直到 i 的条件不满足循环条件。
上述循环条件为 i 不小于 10 时,进行不断循环。
[] 的作用与 test 语句一致
[ ! $i -lt 10 ]
与
test! $i -lt 10
Case 语句
read -p "请您输入一个数值:" num
case $num in
1)echo 您输入的数字是1
;;
2)echo 您输入的数字是2
;;
*)echo 您输入的是其他数字
;;
esac
上述这段代码的功能是,从用户那里获取一个数值,根据输入的数值进行不同的处理。
如果输入是1,就输出第一个字符串。
获取用户输入:
read -p "请您输入一个数值:" num:这里使用read命令来读取用户从键盘输入的内容。p选项用于在等待输入之前向用户显示提示信息,在这个例子中,提示信息是“请您输入一个数值:,用户输入的内容会被存储到变量num中。
case $num in:这是bash,中的case语句的起始标识,用于根据变量num的不同取值来执行不同的代码块。
1)、2)和*)部分:
1):当变量num的值等于1时,会执行这部分代码。即echo您输入的数字是1,然后通过;;结束这个分支的执行。
2):同理,当num的值等于2时,执行echo您输入的数字是2,并以;;结束。
*)
:这是一个通配符分支,当num的值既不等于1也不等于2时,就会执行这部分代码,即echo您输入的是其他数字,最后也以;;结束整个case语句。
基本函数学习
DemoFunc(){
echo "hello world"
}
DemoFunc // 单独一行
上述代码是一个基本函数的创建和引用
DemoFunc(){
echo "Hello world"
echo "my name is $1"
}
DemoFunc xiaoyu
代码功能
这段代码定义了一个函数DemoFunc,然后调用了该函数并传递了参数xiaoyu。函数DemoFunc的功能是在被调用时,先输出固定的字符串“hello world”,接着输出一个包含参数值的字符串“My name is $1:”,这里的$1表示函数接收到的第一个参数。
代码执行过程
函数定义:
DemoFunc():这部分声明了函数名为DemoFunc(),大括号内是函数体内容。
echo “hello world":当函数被调用时,这是函数体中首先执行的语句,会将字符串“helloworld”输出到控制台。
echo “My name is $1:”:在输出“hello world”之后,会执行这条语句。由于在调用函数DemoFunc()时传递了参数xiaoyu,此时S1的值就被设置为xiaoyu,所以这条语句会输出“My
name is xiaoyu:"。
函数调用:
DemoFunc xiaoyu:这行调用了已经定义好的DemoFunc函数,并将参数xiaoyu传递给它。
多函数调用
DemoFunc(){
echo "hello world"
echo "My name is $1 , and my age is $2 years old"
}
DemoFunc xiaoyu 27
不同脚本的互相调用
2.sh
#!/bin/bash
echo "hello 2.sh"
3.sh
#!/bin/bash
. 2.sh
或
source 2.sh
注意:是 .空格2.sh
此时执行3.sh就会执行 2.sh的内容
变量的调用
1.sh
name="d1"
age=22
2.sh
source 1.sh
echo "my name is $1 , and my age is $2 years old"
重定向
重定向分为 输入重定向和输出重定向
ls > 1.txt
cat 1.txt
who > 1.txt
cat 1.txt
追加内容
ls >> 1.txt
cat 1.txt
如果将 ls 重定向到垃圾回收站
ls > /dev/null
不会有任何回显
输入重定向
dist.txt
/home/user/Document
/home/user/Pictures
/home/user/Music
使用 ls 命令加输入重定向,查看目录下的文件
ls -al < dist.txt
文件描述符
0:标准输入
1:标准输出
2:错误输出
例子:
ls > 3.txt 2>5.txt
如果输出正确,就会将结果输出到3.txt,如果错误,就将结果输出到5.txt
【网络安全】Shell 脚本学习的更多相关文章
- 笔记——shell脚本学习指南
<shell脚本学习指南>机械工业出版 ISBN 987-7-111-25504-8 第2章 2.4 初级陷阱 1.当今的系统,对#!这一行的长度限制从63到1024个字符都有,尽量不要超 ...
- Shell 脚本学习资料搜集
Shell文档 ChinaUnix上大神“網中人”总结的Shell十三问,强烈推荐,这本书讲得比较精炼,而且都是一些Shell学习中容易把握不住的一些细节难点.每一问都写得非常精彩.ChinaUnix ...
- 学习笔记之Shell脚本学习指南 & sed与awk & 正则表达式
正则表达式_百度百科 http://baike.baidu.com/link?url=ybgDrN2WQQKN64_gu-diCqdeDqL8LQ-jiQ-ftzzPaNUa9CmgBRDNnyx50 ...
- 转 shell脚本学习指南
shell脚本学习指南 以下八点不敢说就能成为你shell脚本学习指南de全部,至少可以让你编写出可靠的shell脚本. 1. 指定bashshell 脚本的第一行,#!之后应该是什么?如果拿这个问题 ...
- Shell脚本学习 - 运算符
继续shell脚本学习.上一篇是基本数据类型和语法的总结,这一篇是运算相关的操作. 运算符 bash不支持简单的数学计算,需要依赖其他命令实现. expr可以代为实现. # 表达式一般这么写 ` + ...
- shell脚本学习总结02--数组
bash同时支持普通数组个关联数组,普通数组只能使用整数作为数组的索引,关联数组可以使用字符串作为数组的索引. 数组的定义方法: 在单行中使用一列值定义一个数组 [root@new ~]# array ...
- Shell脚本学习指南笔记
Shell脚本学习指南 作者:Danbo 2015-8-3 脚本编程语言与编译型语言的差异 许多中型.大型的程序都是用编译型语言写的,例如:C.C+.Java等.这类程序只要从源代码(Source C ...
- shell脚本学习之6小时搞定(1)
shell脚本学习之6小时搞定(1) 简介 Shell是一种脚本语言,那么,就必须有解释器来执行这些脚本. Unix/Linux上常见的Shell脚本解释器有bash.sh.csh.ksh等,习惯上把 ...
- shell脚本学习心得
近来主要捣鼓ubuntu,大多数项目中都用到了sh脚本作为启动脚本等,以前只是大概明白如何使用,今天需要自己修改并运行脚本就碰到了很多问题,所以决定静下心来学习一下shell脚本,学习了几个小时,现将 ...
- shell脚本学习(一)
Shell脚本最常用于系统管理工作,或者用于结合现有的程序以完成小型.特定的工作. Shell的特点有: 1. 简单性 2. 可移植性 3. 开发容易 [什么是shell] 简单点理解,就是系统跟计算 ...
随机推荐
- spring上 -基于注解配置bean,动态代理,AOP笔记
用的是jdk8,spring框架里jar包的下载可以自己搜到 注解用到的jar包. 60,注解配置Bean快速入门 基本介绍 代码结构: UserDao.java package com.hspedu ...
- KubeSphere 社区双周报 | Fluent Operator 2.6.0 发布 | 2023.11.10-11.23
KubeSphere 社区双周报主要整理展示新增的贡献者名单和证书.新增的讲师证书以及两周内提交过 commit 的贡献者,并对近期重要的 PR 进行解析,同时还包含了线上/线下活动和布道推广等一系列 ...
- 云原生动态周刊:你订阅 GitHub README 播客了吗?
云原生一周动态要闻: Apache Kafka 3.0.0 发布 Deis Labs 推出 WebAssembly PaaS 平台 Hippo Mirantis Flow 将数据中心重塑为云原生系统 ...
- 两个时间段比较的六种情况,以及交集、并集、补集简要sql语句示例
〇.两时间段比较的全部情况 总共有如下图中的六种情况: 下文将根据这六种情况进一步操作. 注意,图中说的动态和固定两时间段,就是两个普通时间段,不区分主次,仅用作帮助理解. 一.判断两个时间段是否有交 ...
- 在centos7系统上安装docker环境
基于 CentOS 7 安装 官网安装参考手册:https://docs.docker.com/install/linux/docker-ce/centos/ 确定你是CentOS7及以上版本 [ro ...
- 版本库控制系统的切磋之路[Git & SVN]
集中式和分布式 集中式版本库控制系统 :SVN ; 分布式版本库控制系统 :Git . 集中式 版本库是存在中央服务器的.干活使用的是自己的电脑,每次干活前都是从服务器上拉下最新的代码版本,然后才 ...
- 92. 反转链表 II Golang实现
题目描述: 给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right .请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 ...
- Codeforces 1847 A-F
题面 A B C D E F 难度:红 橙 黄 蓝 紫 紫 题解 B 题目大意:找到一组分割方法,使得 \(\sum _{i=1} ^ k (\text{&} _{j=l_i} ^ {r_i} ...
- C# 请求 form-data格式的 接口 POSTMAN form-data
HttpClient _httpClient = new HttpClient(); var postContent = new MultipartFormDataContent(); string ...
- Tensorflow/Keras、Pytorch 杂记
Tensorflow/Keras 直接从文件生成图片数据 ImageDataGenerator,循环生成图片,在重复生成图片之前,会把所有图片都遍历一遍.而且如果图片总量不是生成批量的倍数的话,在生成 ...