当前位置: 首页 > news >正文

网站首页引导页 模版网站开发缓存

网站首页引导页 模版,网站开发缓存,包图网图片素材,计算机网站建设书前言 shell编程学习总结#xff0c;1万3千多字带你学习shell编程 往期推荐 14wpoc#xff0c;nuclei全家桶#xff1a;nuclei模版管理工具Nuclei 哥斯拉二开#xff0c;免杀绕过规避流量检测设备 fscan全家桶#xff1a;FscanPlus#xff0c;fs#xff0c;fscan适用…前言 shell编程学习总结1万3千多字带你学习shell编程 往期推荐 14wpocnuclei全家桶nuclei模版管理工具Nuclei 哥斯拉二开免杀绕过规避流量检测设备 fscan全家桶FscanPlusfsfscan适用低版本系统FscanParser 自动爬取url地址检测sql注入漏洞sqlmc安装使用 一键转换订阅为代理池工具白嫖思路 TestNet安装使用可以代替灯塔 shell1脚本的创建和执行变量的使用 脚本的创建和执行 以kail为例进入终端创建一个sh脚本 vim 1.sh # 按i进入插入模式输入 echo hello world # 按esc退出插入模式然后:wq 保存文件并且退出直接执行1.sh发现权限不够需要赋予权限 chmod 777 1.sh # 777是最高权限我这里图方便直接赋予的实际是不推荐的有安全风险除了赋予权限我们还可以让脚本解释器帮我们执行脚本由于解释器本身就赋予权限所有不需要在为脚本赋予权限我们在创建一个2.sh内容为echo 111 #!/bin/sh、#!/bin/bash 、#!/bin/dash三个都是脚本解释器 可以发现2.sh是没有x:执行权限的不过我们可以通过解释器进行执行这里用的都是绝对路径也可以直接sh,bash,dash这样执行 #!/bin/sh、#!/bin/bash 、#!/bin/dash三者的区别 在kali中使用 ll /bin/sh可以发现sh指向的是dash当然/bin/sh 指向 /bin/dash但这并不意味着所有的脚本都会被Dash解释器执行别的可能就不是了不过大部分linux系统都是这样的 使用stat命令可以更加细致的对比三者的关系通过对比发现bash解释器的大小差不多是dash的十倍事实上 鉴于 bash 过于复杂有人把 bash 从 NetBSD 移植到 Linux 并更名为 dashDebian Almquist Shell并以获得更快的脚本执行速度。Debian Almquist shell缩写为dash一种 Unix shell。它比 Bash 小只需要较少的磁盘空间但是它的对话性功能也较少。它由 NetBSD版本的Almquist shell (ash)发展而来于1997年由赫伯特·许Herbert Xu移植到Linux上于2002年改名为 dash。 所以dash其实是bash的简化版 总结 一般情况下sh其实调用的就是dash而dash其实是bash的简化版 除了上面的三个脚本解释器还有一个source他是内置的命令没有固定的路径而是由Shell直接解析和执行。可以使用 type 命令来检查命令的类型 type source可以发现他没有固定的路径是内置命令 source和其他三个脚本解释器的区别 首先他是内置的命令是由shell直接解析和执行的 这里主要对比一下和sh的区别 source当前Shell执行命令在当前Shell会话中执行不会启动新的子Shell。变量作用域文件中定义的变量、函数和别名会直接在当前Shell会话中生效。环境变化文件中对环境变量的修改会立即反映在当前Shell会话中。权限要求文件不需要具有可执行权限只需要有读权限即可。 sh子Shell执行命令在一个新的子Shell中执行与当前Shell会话隔离。变量作用域文件中定义的变量、函数和别名仅在子Shell中生效不会影响当前Shell会话。环境变化文件中对环境变量的修改仅在子Shell中生效不会影响当前Shell会话。权限要求文件需要具有读权限但不需要可执行权限。 对我们来说最大的影响有两个source执行的脚本变量会影响到当前会话sh不会source执行之后输出结果有颜色变化 创建一个3.sh内容为name1通过我的演示可以很直观的感受到source影响了当前会话 创建4.sh内容为 echo aaa ls可以发现有颜色变化 变量的使用 变量声明和定义 举例定义一个name变量name“xiaoyu” 再利用echo $name打印出来这就是简单的变量声明 再定义一个age变量 age20 echo $age可以写复杂点比如说 echo my name is $name,and my age is $age years old然后就直接打印出了姓名和年纪 单引号和双引号的区别 单引号 () 字面量引用单引号内的所有字符都被视为普通字符不进行变量替换或转义字符处理。特殊字符无效单引号内的 $、\、、 等特殊字符都会被视为普通字符不会被解释。 双引号 () 部分解释双引号内的大多数字符会被视为普通字符但某些特殊字符如 $、、\会被解释。变量替换双引号内的变量会被替换为其值。命令替换双引号内的命令替换command 或 $(command)会被执行。转义字符双引号内的某些转义字符如 \n、\t会被解释。 总之单引号里面的字符视为普通字符双引号不会 可以发现使用单引号不会打印变量的值原因是$符没有被解释 echo $name $age echo $name $age变量拼接 当我们想要将变量和字符连接起来 echo my name is $name,and my age is $ageyears old echo my name is $name,and my age is$age years old可以发现$ageyears被当作新的变量并且没有被声明所以打印了空值 为了解决这个问题问题我们可以使用 双引号 或者 花括号{}拼接起来 echo my name is $name,and my age is $ageyears old echo my name is $name,and my age is {$age}years old变量命名规则 上面讲的全部是临时的一个变量变量是由数字字符串下划线组成但是不能以数字开头例如1aa这种是不行的变量中间最好不要有空格比如说a a如果非要用这种可以加个下划线a_aaaa这种 查找和删除定义的变量 利用set命令查找 set set | grep name # 可以使用grep进行筛选使用unset删除变量 unset name set | grep name可以发现name变量没有了 shell2临时变量和永久变量字符串相关的操作 临时变量和永久变量 临时变量与永久变量是相对应得 常见永久变量 echo $HOME # (家目录root用户)echo $PATH # 环境变量对于 P A T H 变量 w i n d o w s 也有类似的 P a t h ! [ i m a g e . p n g ] ( h t t p s : / / i − b l o g . c s d n i m g . c n / i m g c o n v e r t / e f 6 e 91 e e d c b 04472 c b 8 b 4 a 3 b 29516811. p n g ) 他们的效果都是类似的为了简化用户输入命令的过程不需要指定目录再进行命令使用了比如 PATH变量windows也有类似的Path ![image.png](https://i-blog.csdnimg.cn/img_convert/ef6e91eedcb04472cb8b4a3b29516811.png) 他们的效果都是类似的为了简化用户输入命令的过程不需要指定目录再进行命令使用了 比如 PATH变量windows也有类似的Path![image.png](https://i−blog.csdnimg.cn/imgc​onvert/ef6e91eedcb04472cb8b4a3b29516811.png)他们的效果都是类似的为了简化用户输入命令的过程不需要指定目录再进行命令使用了比如PATH下面有/bin目录而我们的sh、bash、dash三个解释器就在这个目录下面所有就不需要指定路径就能直接使用当然指定路径也可以 创建1.sh里面写入echo hello world sh 1.sh /bin/sh 1.sh查看命令绝对路径which 可以使用which命令查看 which sh which -a ls # 显示所有命令的绝对路径这里我们可以发现直接使用which ls不行原因是ls命令有两个绝对路径只会输出优先级高的那个命令的全称加上-a参数就行了 添加可直接使用的命令 添加到/bin/之类的已经被系统定义的路径中 比如将1.sh添加到/bin/目录下面 mv 1.sh /bin/1.sh直接将命令的绝对路径写入到$PATH环境变量中 我们先删除/bin/1.sh rm /bin/1.sh将目录写入会导致目录其他命令也会直接被写入 # 首先先复制一下原来的$PATH内容以做备用 echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games临时添加 export PATH$PATH:/home/kali/桌面/dir/test # 有中文最好使用括起来记得给脚本赋予权限不然不能使用 chmod 777 2.shexport 命令在 Unix 和 Linux 系统中用于将变量导出到环境变量中使得这些变量在当前 Shell 会话及其子进程中可见。环境变量在多个方面都有重要作用例如配置系统行为、设置路径、传递参数等不过直接这样只是在当前命令窗口改变不会影响别的窗口 永久添加 为了使变量在每次登录时都有效可以将 export 命令添加到 Shell 配置文件中。常见的配置文件包括 Bash: ~/.bashrc 或 ~/.bash_profileZsh: ~/.zshrcFish: ~/.config/fish/config.fish 示例在 ~/.bashrc 中添加 export 命令 首先还原一下 export PATH/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games echo export PATH$PATH:/home/kali/桌面/dir/test ~/.bashrc source ~/.bashrc如果直接使用发现不行 找不到命令 “shopt”您的意思是“shout” 命令来自 Debian 软件包 libshout-tools 尝试 apt install deb name 找不到命令 “shopt”您的意思是“shout” 命令来自 Debian 软件包 libshout-tools 尝试 apt install deb name 找不到命令 “shopt”您的意思是“shout” 命令来自 Debian 软件包 libshout-tools 尝试 apt install deb name 找不到命令 “shopt”您的意思是“shout” 命令来自 Debian 软件包 libshout-tools 尝试 apt install deb name 原因是~/.bashrc是bash解释器的需要使用bash解释器而默认的是使用sh解释器。这里也可以看出bash解释器是三个当中最全的解释器 字符串相关的操作 假设我们想知道一个字符串的长度比如我们想解析一个字符串的长度我们如何进行实现 比如 namecybc age20 然后我们通过 echo my name is $name,and I am $age years old 打印完整字符串使用 ${#variable} 来获取字符串的长度 strhello world echo ${#str}使用 ${variable:num:num} 来获取字符串的切片 输出前6个字符hello echo ${str:0:6}shell3参数传递算术运算 参数传递 脚本程序传递参数如何实现 创建一个a.sh内容如下如下 echo 执行的文件名是$0 echo 第一个参数是$1 echo 传递的参数作为一个字符串显示$* echo 传递的参数独立作为每个字符串显示$ echo 传递到脚本的参数个数是$# echo 最后命令的退出状态$? echo 脚本运行的当前进程ID是$$$0这个变量包含了当前执行脚本的名称。如果脚本是通过完整路径调用的它将包含整个路径。$1, $2, ...分别表示传递给脚本的第一个、第二个等参数。可以一直递增到脚本接收到的最后一个参数。$*当未被双引号包围时$*与$的行为相同都是将所有位置参数视为一个字符串。但当它们被双引号包围时$*会将所有参数视为单个以首个字符为分隔符通常是空格连接起来的字符串而$则会保持每个参数独立。$与$*类似但在被双引号包围时它将每个参数都作为独立的字符串处理。$#表示传递给脚本或函数的参数数量。$?存储最近一次执行的前台管道的退出状态。通常0 表示成功非零值表示错误。$$表示当前shell进程的PID进程ID。 更多的Shell特殊变量 除了上述变量之外还有其他一些有用的特殊变量 $_这是上一个命令执行的最后一个参数。这在交互式shell中特别有用。$!最近一个后台进程中运行的作业的PID。$-显示当前shell选项设置的状态。$IFSInternal Field Separator定义了用于分割单词的字符默认为空格、制表符和换行符。这对于控制如何解析输入非常关键。$BASH_VERSION如果你使用的是Bash shell这个变量保存了当前Bash版本的信息。$HOME用户的家目录。$PWD当前工作目录。$SECONDS自脚本开始执行以来经过的秒数。$RANDOM生成一个随机整数。每次引用该变量时都会产生一个新的随机数。$LINENO当前正在执行的代码行号。$BASH_SOURCE对于函数或脚本提供了一个数组其中包含了调用栈中每个元素的文件名。$FUNCNAME如果在一个函数内该变量包含了函数的名字。 $*与$ 当未被双引号包围时$*与$的行为相同都是将所有位置参数视为一个字符串。但当它们被双引号包围时$*会将所有参数视为单个以首个字符为分隔符通常是空格连接起来的字符串而$则会保持每个参数独立。 新建一个b.sh #!/bin/bash echo Using \$*: $* echo Using \\$*\: \$*\ echo Using \$: $ echo Using \\$\: \$\当你运行这个脚本并传入参数./script.sh hello world goodbye时输出将会是这样的 Using $*: hello world goodbye # 参数被当作单个字符串处理Using $*: hello world goodbye # 所有参数作为一个字符串中间用空格分割Using $: hello world goodbye # 参数被视为独立的字符串Using $: hello world goodbye # 每个参数都被独立地引用 算术运算 常见的命令 1. 使用 expr 命令 expr 是一个非常基础但功能有限的工具用于执行简单的算术运算。 result$(expr 5 3) echo $result # 输出 8注意使用 expr 时操作符和数字之间需要有空格。 2. 使用 $((...)) 语法 这是一种更现代且更简洁的方法可以直接在变量赋值或命令替换中使用。 result$((5 3)) echo $result # 输出 8# 或者直接输出 echo $((5 * 3)) # 输出 153.使用 let 命令 let 可以用来执行整数算术表达式并将结果存储到变量中。 let result53 echo $result # 输出 84. 使用 bc 命令 bc 是一个强大的计算器支持浮点运算和复杂的数学函数。 result$(echo scale2; 5 / 3 | bc) echo $result # 输出 1.67 (保留两位小数)# 执行更复杂的计算 result$(echo sqrt(9) | bc -l) echo $result # 输出 3.00000000000000000000其中-l 选项加载了标准数学库允许进行更高级的数学运算。 5. 使用 awk awk 不仅是一个文本处理工具也提供了丰富的数学运算能力。 result$(awk BEGIN{print 53}) echo $result # 输出 8# 浮点运算 result$(awk BEGIN{printf %.2f\n, 5/3}) echo $result # 输出 1.676. 使用 declare -i 来定义整数变量 这可以让你对变量进行直接的算术运算而不需要额外的命令。 declare -i num5 num3 echo $num # 输出 8以expr为例演示加减乘除取模 注意符前后都需要空格隔开 - \* 转义一下linux的*代表任意 / %\( \) 括号需要转义如 expr 6 \* 6(乘法是用\*,python.直接*就行了 要用\进行转义)复杂一些的运算 注意括号需要转义并且前后需要空格 shell4shell脚本于用户交互关系运算符 shell脚本于用户交互read命令 read [选项] [变量名...]常用参数 -p 提示信息: 在读取之前显示一条提示信息记得手动打印一个换行符因为该选项会阻止自动换行-t 秒数: 设置等待用户输入的时间限制秒。如果超时则返回一个非零退出状态。-s: 安静模式输入的内容不会回显到终端上适用于密码输入等敏感信息。-n 字符数: 限制输入的最大字符数。-d 分隔符: 指定结束输入的分隔符默认为换行符。 可以利用read命令进行shell脚本于用户的交互 例如 read nameecho $echo但是当我们使用-p参数的时候会报错 原因很简单kali中默认使用sh脚本解释器运行脚本sh本质是指向dash解释器而dash解释器其实是bash解释器的简化版大小只有bash的十分之一左右所以有很多命令参数解释并不支持 需要使用bash脚本 bashread -p 请输入姓名: name 可以多个参数输入 read -p 请输入姓名和年龄: name ageecho $name $age我们在看个例子使用参数-t(指定时间) read -t 10 -p 请输入您的姓名 name# 如果我们在10秒内输入了就会执行成功10秒内没有输入就会自动退出可以使用-n参数限制用户输入的字符个数 read -n 3 -t 10 -p 请输入您的姓名 name输入三个字符自动执行如果输入了三个以下的字符需要自己敲回车执行 关系运算符 在脚本环境中如何简单的做条件判断 运算符 -eq检查两个数是否相等。-lt检查左边的数是否小于右边的数。-gt检查左边的数是否大于右边的数。-ne检查两个数是否不相等。 使用 vim o.sh首先定义两个变量然后通过if条件判断来进行两个简单的条件判断再接入关系运算符 内容为 num111 num222if [ $num1 -eq $num2 ]; thenecho 数字相等 else echo 数字不相等 fi更加复杂一些的 #!/bin/bash# 定义两个变量 num110 num220# 使用 if-then-else 语句进行条件判断 if [ $num1 -eq $num2 ]; thenecho num1 等于 num2 elif [ $num1 -lt $num2 ]; thenecho num1 小于 num2 elif [ $num1 -gt $num2 ]; thenecho num1 大于 num2 elseecho num1 不等于 num2虽然这个条件总是为真但这里是为了展示 else 的用法 fi# 另一个例子使用更复杂的条件 if [ $num1 -ne $num2 ] [ $num1 -lt 15 ]; thenecho num1 不等于 num2 并且 num1 小于 15 elseecho num1 不满足上述条件 fi注意事项 在 [ ] 中使用空格是很重要的。例如[ $num1 -eq $num2 ] 必须在每个元素之间加上空格。如果你想要对字符串进行比较可以使用  或者 !。但是请注意这些操作符需要在 [[ ]] 中使用而不是 [ ]。例如 if [[ hello hello ]]; thenecho 字符串相等 fitest和[] [ ] 和 test 命令在 Bash 脚本中实际上是等价的。[ ] 是 test 命令的一种更直观的写法。你可以用 test 来替换 [ ]但需要注意的是使用 test 时不需要方括号参数直接传递给 test 命令。 简单的用法 复杂一些的 #!/bin/bash# 定义两个变量 num110 num220# 使用 test 命令进行条件判断 if test $num1 -eq $num2; thenecho num1 等于 num2 elif test $num1 -lt $num2; thenecho num1 小于 num2 elif test $num1 -gt $num2; thenecho num1 大于 num2 elseecho num1 不等于 num2虽然这个条件总是为真但这里是为了展示 else 的用法 fi# 另一个例子使用更复杂的条件 if test $num1 -ne $num2 test $num1 -lt 15; thenecho num1 不等于 num2 并且 num1 小于 15 elseecho num1 不满足上述条件 fishell5字符串运算符逻辑运算符 字符串运算符 [[ ... ]]和[...] 首先我们在终端利用vim打开u.sh 内容为 str1hello str2helloif [[ $str1 $str2 ]]; thenecho True elseecho false fi使用来比较两个字符串是否相等。使用双方括号[[ ... ]]来进行字符串比较它支持模式匹配和更复杂的表达式。变量应当用双引号包围以确保即使变量值为空或包含空格时也能正确处理。 提示[[: not found。这通常是因为shell环境不支持[[ ... ]]条件表达式这可能是由于您使用的是一个较旧的或非常基础的shell版本比如shBourne shell它不支持这种语法。 kail默认使用sh解释器我们可以使用bash解释器因为在kali中sh解释器的其实最终用的dash解释器而dash解释器是bash解释器的简化版 当然了我们如果要使用sh解释器也可以使用旧的语法 str1hello str2helloif [ $str1 $str2 ]; thenecho True elseecho false fi注意以下几点 使用单个等号确保在[和]两边都有空格。变量仍然需要用双引号包围以确保安全处理。 上面的两个例子中双引号都是可以省略的加上可以确保即使变量值为空或包含空格时也能正确处理 大小写是否敏感 我们可以更改str1为Hello来看看效果 str1Hello str2helloif [ $str1 $str2 ]; thenecho True elseecho false fi我们使用!在来看看他们是否不想等 str1Hello str2helloif [ $str1 ! $str2 ]; thenecho True elseecho false fi可以发现对大小写敏感 检查字符串的长度是否为0、不为0 str1hello str2helllo# 检查str1的长度是否为0 if [ -z $str1 ]; thenecho True # 如果str1长度为0则输出True elseecho False # 否则输出False fi使用-z来检测字符串长度是否为零。变量名$str1应该被双引号包围以防止空值或包含空格的值导致的问题。if和[之间以及[和条件表达式之间需要有空格。then关键字之前也需要有一个空格。 使用-n测试来检查字符串是否不为空。如果字符串不为空则返回True如果字符串为空则返回False。我们将把str1改为str11并检查其长度。 # 定义变量 str11 # 这里设置为一个空字符串# 检查str11的长度是否不为0 if [ -n $str11 ]; thenecho True # 如果str11不为空则输出True elseecho False # 如果str11为空则输出False fi逻辑运算符之布尔运算符 # 定义变量 num19# 检查num1是否不等于9 if [ $num1 ! 9 ]; thenecho num1不等于9 elseecho num1等于9 fi使用单方括号[ ... ]来进行条件测试。使用!来检查num1是否不等于9。变量num1被双引号包围以确保安全处理。if语句的格式已经正确调整。 -a和-o 参数 -a来连接两个条件相当于 -o来连接两个条件相当于|| num19 num219# 检查num1是否不等于9并且num2是否小于20 if [ $num1 ! 9 -a $num2 -lt 20 ]; thenecho True elseecho False fi使用单方括号[ ... ]来进行条件测试。使用!来检查num1是否不等于9。使用-lt来检查num2是否小于20。使用逻辑与运算符-a来连接两个条件。变量num1和num2被双引号包围以确保安全处理。 更改为-o num19 num219# 检查num1是否不等于9并且num2是否小于20 if [ $num1 ! 9 -o $num2 -lt 20 ]; thenecho True elseecho False fi我们也可以利用多个[...]这样调理更加清楚 比如刚才的例子我们可以这样 注意这里要使用管道符链接比如、||因为-a和-o都是需要在[]才能被识别的 #!/bin/sh# 定义变量 num19 num219# 检查num1是否不等于9或者num2是否小于20 if [ $num1 ! 9 ] || [ $num2 -lt 20 ]; thenecho True elseecho False fishell6if条件判断语句for循环结构 if条件判断语句 有一点编程基础的应该都知道if语句这里就不解释了看一下实例就都会了 参数使用 在if语句中使用测试表达式时需要特别注意格式。[ ]是test命令的一种符号链接形式用于进行条件测试。 参数 文件测试-e存在-d目录-f普通文件等。字符串测试-z空字符串-n非空字符串相等!不等。数字比较-eq等于-ne不等于-lt小于-le小于等于-gt大于-ge大于等于。 注意 在[ ]内确保有适当的空格如 [ -f file ]。使用双引号包围变量以防止变量为空或包含空格时出现错误。当条件复杂时考虑使用[[ ]]它提供了更多的特性比如支持模式匹配和更宽松的空格规则。利用和||组合命令可以在一条命令行上完成复杂的逻辑判断。 实例 # 定义变量 a10 b20# 进行条件判断 if [ $a -eq $b ]; thenecho ab elif [ $a -gt $b ]; thenecho ab elseecho 没有符合上述条件 fi语句很好看懂不过需要注意 使用[ ]来创建测试表达式这是test命令的一个符号链接。在-eq, -gt等运算符两边都需要有空格。每个[后面应该有一个对应的]并且[和]之间至少要有一个空白字符通常是一个空格与之分隔。elif和else块同样需要以fi结束。 这里我们可以再增加一条elif语句 elif [ $a -lt $b ]; thenecho ab注意这里变量最好加上双引号不然如果脚本复杂的话容易出事 for循环结构 在Shell脚本中for循环是一种非常有用的控制结构它允许你重复执行一系列命令直到满足特定条件。for循环可以处理数字、字符串列表、文件名以及命令的输出等。下面将详细介绍几种常见的for循环用法及其示例。 基本格式 列表迭代 这是最简单的for循环形式它遍历一个预定义的值列表。 for variable in list do# 执行的命令 done例如打印从1到5的数字 for i in 1 2 3 4 5 doecho $i done使用范围 Bash支持使用花括号{}来指定一个数值范围。 for i in {start..end} do# 执行的命令 done例如打印从1到10的数字 for i in {1..10} doecho Number: $i done您还可以通过增加第三个参数来指定步长 for i in {1..10..2} # 步长为2 doecho Odd number: $i done遍历文件 for循环也可以用于遍历目录中的文件。 for file in /path/to/directory/* do# 对每个文件执行操作echo Filename: $file done处理命令输出 您可以使用$(command)来获取命令输出并将其作为for循环的输入。 for line in $(cat filename.txt) do# 处理每一行echo Line: $line done类C语言风格的for循环 Bash还支持一种类似于C语言的for循环语法这在需要更复杂的初始化、条件测试和更新逻辑时非常有用。 for (( EXP1; EXP2; EXP3 )) do# 执行的命令 doneEXP1 是初始化表达式。EXP2 是条件表达式。EXP3 是每次循环后执行的更新表达式。 例如打印1到10的数字 for (( i1; i10; i )) doecho Count: $i done特殊用途 无限循环 如果您想创建一个无限循环可以省略for语句中的所有元素。 for (( ; ; )) do# 无限执行的命令read -p Press [Enter] key to continue or [CtrlC] to exit... key done跳出循环 使用break语句可以在满足特定条件时提前退出循环。 for i in {1..10} doif [ $i -eq 5 ]; thenbreakfiecho Number: $i done继续下一次迭代 使用continue语句可以让循环跳过当前迭代的剩余部分直接进入下一次迭代。 for i in {1..10} doif [ $((i % 2)) -eq 0 ]; thencontinuefiecho Odd number: $i done实际应用案例 批量添加用户 假设我们有一个包含用户名的文本文件我们可以使用for循环来批量添加这些用户。 #!/bin/bash while IFS read -r user douseradd $userecho User added: $user done users.txt检查网络连通性 我们可以使用for循环结合ping命令来检查一组IP地址的连通性。 #!/bin/bash for ip in 192.168.1.{1..254} doping -c 1 $ip /dev/nullif [ $? -eq 0 ]; thenecho $ip is upelseecho $ip is downfi done通过以上介绍您应该能够理解如何在Shell脚本中使用for循环来处理各种任务。for循环是编写自动化脚本时非常强大的工具掌握其用法可以使您的脚本更加高效和灵活。 实例 for num in 1 2 3 4 5 6 doecho num is $num done我们可以使用{..}来简化数值列表的定义不过需要使用bash脚本 for str in Hello world doecho str is $str done 这是因为 for 循环在这里只迭代了一次且迭代的值就是整个字符串 Hello world。 如果想要遍历 Hello world 中的每个单词即 Hello 和 world需要使用空格来分隔这些单词 for str in Hello world doecho str is $str done这样for 循环会把 Hello 和 world 扩展遍历字符串中的每个字符 如果你的目标是遍历 Hello world 中的每一个字符那么你需要稍微修改一下脚本。一种方法是使用 while 循环结合 read 命令来逐个读取字符或者使用 fold 命令来拆分字符串。以下是两种方法的示例 方法一使用 while 循环和 read 命令 需要使用bash脚本 stringHello world while IFS read -r -n1 char doecho char is $char done $string这里IFS 确保了内部字段分隔符为空使得 read 不会跳过空白字符。-n1 参数告诉 read 每次只读取一个字符。 是 here string 的语法用于将字符串作为输入提供给循环。 方法二使用 fold 命令 sh和bash脚本解释器都可以 stringHello world for char in $(echo -n $string | fold -w1) doecho char is $char done这里fold -w1 将字符串按照每1个字符宽度进行分割然后 for 循环遍历这些字符。 shell7bash解释器的 for循环while循环 for 前面已经讲过for循环了不过是sh解释器的for循环前面已经说过了在kali中sh解释器的其实是指向dash解释器而dash解释器是bash解释器的简化版只有bash解释器的1/10左右的大小所以bash解释器可以支持更多更复杂的语法 for循环有三种写法反引号$(...)((...)) 第一种 for i in seq 1 100 doecho $i doneseq 1 100: 这个命令生成一个数字序列从1开始直到100包括100。seq是一个在Linux/Unix系统中用来产生一系列数字的工具。在这个例子中它将生成一系列连续的整数1, 2, 3, …, 98, 99, 100。for i in ...: 这是for循环的开始它会遍历由seq 1 100生成的所有数字。每次迭代时变量i都会被设置为当前迭代中的数字。do…done: 这两个关键字定义了循环体即在每次迭代时要执行的代码块。在这个例子中循环体只包含了一条语句——echo $i这条语句用于输出当前迭代中的数字i。echo $i: 在每次循环中echo命令会被调用并且当前值$i会被打印到标准输出。 第二种$(...) for i in $(seq 1 100) doecho $i done第三种((...)) 或者使用C语言风格的for循环语法这可能对熟悉C语言的程序员来说更加直观 注意这里的语法不像sh解释器那么严苛符号前后不需要强制空格 这样标准的也行 for (( i1; i100; i )) doecho $i donefor ((ii;i100;i )) doecho $i done这里(( i1; i100; i ))直接指定了循环的初始化、条件测试和增量操作使得整个循环结构看起来更加紧凑。 while while循环有编程基础的应该都知道就不细讲语法了大家看一下实例就都知道怎么写了。还是和for循环一样将一下sh和bash注sh可以的bash都可以 sh解释器 首先sh解释器只能使用[]或者test来规定循环的结束条件其次对于循环变量的变化sh解释器可以使用的语法有$((...))和$(expr $i 1) $((...)) i1 while [ $i -lt 10 ] doecho $ii$((i1)) done$(expr $i 1) i1 while [ $i -lt 10 ] doecho $ii$(expr $i 1) done sh解释器不支持:(())和let 如果将i$((i1))替换成((i)) i1 while [ $i -lt 10 ] doecho $i((i)) done不支持 程序报错但是不会停止运行会直接死循环 替换成let i1 while [ $i -lt 10 ] doecho $ilet ii1 done 还是一样程序报错但是不会停止运行会直接死循环 bash解释器 sh可以的bash一定可以 bash可以使用更加简单的语法循环结束条件可以使用(())循环变量的变化可以使用$((...))、$(expr $i 1)、(())和let i1 while(($i10)) doecho $i((i)) donelet的使用上面已经讲了这里就不演示了 shell8 until循环 until循环与while循环的区别 while循环是在条件为真时执行循环体而until循环则是在条件为假时执行循环体。通常情况下while循环更常用因为它直观地反映了“只要条件成立就继续做某事”的逻辑。until循环更适合于那些默认行为是重复执行直到发生某种变化的情况。 所以until循环和while循环除了循环条件是相反的while为真时循环until为假时循环几乎一样 还是和while一样分为sh解释器和bash解释器在kali中sh解释器的其实是指向dash解释器而dash解释器是bash解释器的简化版只有bash解释器的1/10左右的大小所以bash解释器可以支持更多更复杂的语法 while讲的文章shell编程7bash解释器的 for循环while循环 这里简单演示一下详细的去看while的文章 sh解释器 首先sh解释器只能使用[]或者test来规定循环的结束条件其次对于循环变量的变化sh解释器可以使用的语法有$((...))和$(expr $i 1) i1 until [ $i -gt 10 ] doecho $ii$((i1)) done 初始化首先变量i被初始化为1。条件判断until [ $i -gt 10 ]部分定义了循环的终止条件。这里的条件是当$i大于10时循环停止。-gt是一个比较运算符表示“大于”。循环体 echo $i命令输出当前i的值。i$((i1))这条语句将i的值增加1。这里使用了算术扩展$((...))来进行数学运算。 bash解释器 sh可以的bash一定可以 bash可以使用更加简单的语法循环结束条件可以使用(())循环变量的变化可以使用$((...))、$(expr $i 1)、(())和let i1 until ((i10)) doecho $i;((i)) done初始化变量i被初始化为1。条件判断until ((i 10))部分定义了循环的终止条件。这里的条件是当i大于或等于10时循环停止。((...))是用于执行算术运算的结构它允许在表达式中直接使用比较操作符如。循环体 echo $i;命令输出当前i的值。((i))这条语句将i的值增加1。这里使用了算术扩展((...))来进行数学运算i表示将i递增1。 case语句 基本语法 有编程基础的应该都知道case多分支结构我这里就不细讲了 case语句的基本格式如下 case 变量 in模式1)# 当变量匹配模式1时执行的命令;;模式2|模式3)# 当变量匹配模式2或模式3时执行的命令;;*)# 当变量不匹配任何模式时执行的命令默认情况;; esaccase 变量 in开始一个case语句其中变量是要检查的值。模式)定义一个模式如果变量与这个模式匹配则执行紧接着的命令序列。;;表示一个模式结束。*)通配符代表所有情况通常作为默认分支使用。esac结束case语句。 特殊模式精确匹配如1)、abc)等仅当变量值完全等于指定字符串时匹配。通配符如*word*可以用来匹配包含特定子串的任意字符串。范围如[0-9]可以匹配一个数字字符。多个模式通过|分隔例如a|b|c)可以匹配’a’、‘b’或’c’。 实例 read -p 请输入一个数字 num case $num in1) # 如果输入的是1echo 您输入的数字是1;;2) # 如果输入的是2echo 您输入的数字是2;;*) # 如果输入的是其他任何值echo 您输入的是其他数字;; esacread -p 请您输入一个数值: num这条命令提示用户输入一个数值并将输入存储到变量num中。case $num in ... esac这是case语句的基本结构。它会检查$num的值并根据匹配的情况执行相应的代码块。1)、2) 和 *)这些是模式匹配项。1)匹配输入为1的情况2)匹配输入为2的情况而*)则匹配所有其他情况即除了1和2之外的所有输入。;;每个case分支以;;结束表示该分支的结束。 基本函数 在Shell脚本中函数是一种组织代码的方式可以将一段代码封装起来以便于重复使用。通过定义和调用函数可以使脚本更加模块化、易于维护并且提高代码的复用性。下面是一些关于如何在Shell脚本中使用函数的基本指导和示例。 定义函数 在Bash中可以通过以下方式定义一个函数 function_name() {# 函数体 }其中function_name是你给函数起的名字应该具有描述性以方便理解其功能。 调用函数 一旦定义了函数就可以通过简单地写函数名来调用它 function_name如果函数需要参数可以在调用时传递这些参数 function_name arg1 arg2实例 基本函数 这是一个简单的函数用于打印一条消息 greet() {echo Hello, $1 }# 调用函数 greet World # 输出: Hello, World在这个例子中$1是第一个参数的位置变量代表传入的第一个参数。 带返回值的函数 函数可以返回一个状态码0表示成功非0表示错误也可以通过全局变量或输出来返回结果 add_numbers() {local sum$(( $1 $2 ))echo $sum # 输出求和的结果 }result$(add_numbers 5 3) # 将函数的输出捕获到变量result中 echo The result is: $result # 输出: The result is: 8这里使用local关键字声明了一个局部变量sum它只在函数内部可见。echo $sum用来输出计算结果这个输出被外部命令$(...)捕获并赋值给result变量。 使用return语句 虽然return通常用于返回状态码但也可以用来控制流程 check_number() {if [ $1 -gt 10 ]; thenreturn 0 # 成功elsereturn 1 # 失败fi }if check_number 15; thenecho Number is greater than 10. elseecho Number is not greater than 10. fi在这个例子中check_number函数检查传入的数字是否大于10并通过return语句返回相应的状态码。 注意事项 作用域在函数内部定义的变量默认是局部的除非使用global关键字。参数处理函数可以接受任意数量的参数它们分别对应位置参数$1, $2, … 等。返回值函数的返回值通常是通过return语句设置的状态码范围从0到255。对于复杂的数据结构通常使用输出或全局变量来返回数据。命名规则函数名遵循与变量相同的命名规则即不能以数字开头且不能包含特殊字符。 shell9不同脚本的互相调用重定向的使用 重定向操作和不同脚本的互相调用 不同脚本的互相调用 1. 直接调用 直接从一个脚本中使用bash或sh等其他shell解释器命令来执行另一个脚本文件 1.sh #!/bin/bashlet num53 echo $num2.sh #!/bin/shbash ./1.sh 看这个例子可以发现哪怕2.sh用的解释器是sh也不会影响必须要使用解释器的1.sh除非1.sh没有指定bash解释器那么就会按照默认的解释器kali中刚好是sh所以报错 echo $SHEll # 查看默认解释器2. 使用点号.或者source命令来包含脚本 可以使用.操作符也称为source命令。使得被包含的脚本在当前shell环境中执行而不是创建一个新的子shell。 相当于c语言中的include 1.sh #!/bin/bashlet num53 echo $num2.sh #!/bin/sh. 1.sh 点号.和source的区别 虽然他们都可以进行包含并且都可以进行命令执行甚至使用which命令指向的内置shell都一样但是还是有区别的 通上面图片和下面的图片可以发现使用source命令必须指定bash解释器而.不需要所有优先使用.代码的鲁棒性更好 其他的两个就没有这么常用了就自己看看就行了 3. 传递参数 当调用另一个脚本时可以传递参数给它。这些参数可以通过位置参数$1, $2, … 来接收。 #!/bin/bash # script1.shecho This is script1 ./script2.sh arg1 arg2 echo Back to script1在script2.sh中你可以这样获取参数 #!/bin/bash # script2.shecho Received arguments: $1 and $24. 设置环境变量 如果你想让被调用的脚本能够访问到某些环境变量可以在调用之前设置它们。 #!/bin/bash # script1.shexport MY_VARHello, World! ./script2.sh然后在script2.sh里就可以读取这个环境变量了 #!/bin/bash # script2.shecho Value of MY_VAR: $MY_VAR重定向 分为输出重定向和输入重定向 输出重定向 使用 和来实现 使用符号  将标准输出重定向到一个文件。如果文件已经存在则会被覆盖。使用符号  将标准输出追加到一个文件的末尾不会覆盖现有内容。 ls 1.txtls 1.txt输入重定向 使用、、实现 使用 符号将文件内容作为命令的标准输入使用 符号可以从标准输入中读取多行文本直到遇到指定的终止字符串使用 符号将一个字符串作为命令的标准输入。 2.txt内容为 . # 表示当前目录 test# 空的也表示当前目录xargs 命令进行转换的使用 使用 符号将文件内容作为命令的标准输入使用命令行参数的命令不能直接这样输入需要使用 xargs 命令进行转换 比如这是因为 ls 命令不从标准输入读取文件名而是从命令行参数中读取。 创建2.txt写入 /home/kali/桌面/dir/test .. 表示当前目录 ls 2.txt xargs ls 2.txt可以发现直接使用ls是不行的运行 ls 2.txt 时ls 命令并没有从 2.txt 文件中读取文件名而是直接列出了当前目录下的文件和文件夹 使用 符号可以从标准输入中读取多行文本直到遇到指定的终止字符串。 cat EOF Hello, World! This is a test. EOFcat 命令会读取从 EOF 开始到下一个 EOF 之间的所有文本并将其作为输入。 使用 符号将一个字符串作为命令的标准输入。 wc -c Hello Worldwc -c 命令会计算字符串 Hello World 中的字符数 文件描述符/dev/null 标准输入0: 默认情况下标准输入是从键盘读取数据。标准输出1: 默认情况下标准输出是显示在终端上的文本。标准错误2: 默认情况下标准错误也是显示在终端上的文本但通常用于输出错误信息。 ls 1.txts 1.txt 22.txts 1 1.txt 22.txt这里我们可以发现使用s 1.txt 22.txt命令使1.txt的内容为空了其实这里相当于执行了 1.txt所以内容被覆盖了刚好覆盖的内容是空所以1.txt为空 使用s 1 1.txt 22.txt发现是一样的 /dev/null指向的是kali的回收站所以如果我们直接指向回收站 ls /dev/nullls 2 /dev/nullls 1 /dev/null /dev/null 21详细解释 是在这里是重定向符可以重定向流这里就是将2报错流重定向到1标准流而标准流到了回收站所以这里不显示任何输出和报错 21: 2 表示标准错误流文件描述符 2。1 表示标准输出流文件描述符 1这里的  是必要的因为它表示这是一个文件描述符而不是一个文件名21 的意思是将标准错误流2重定向到标准输出流1的位置。 执行顺序 /dev/null: 首先标准输出1被重定向到 /dev/null。这意味着任何原本会输出到标准输出的内容都会被丢弃。 21: 接着标准错误2被重定向到标准输出1的位置。由于标准输出已经被重定向到 /dev/null因此标准错误也会被重定向到 /dev/null。 shell编程作业 ⼀、⽤Shell写⼀个计算器 通过 read 命令获取用户输入的表达式表达式的格式设定为 操作数1 运算符 操作数2 例如 5 3 然后利用设计的脚本输出运算结果。 要求实现 加、减、乘、除运算 简单的可以使用bc命令 #!/bin/bashwhile true doread -p 请输入一个表达式(格式是:操作数1 运算符 操作数2): expressionresult$(echo $expression | bc)echo $result done 复杂的可以是case语句或者if-else语句 read -p 请输入一个表达式(格式是:操作数1 运算符 操作数2): expressionIFS read -r num1 operator num2 $expression case $operator in)result$((num1 num2));;-)result$((num1 - num2));;\*)result$((num1 * num2));;/)if (($num2 0)); thenecho 错误: 除数不能为零exit 1firesult$((num1 / num2));;*)echo 不支持请重新输入exit 1;; esacecho 结果为:$result⼆、⽤Shell定义⼀个求n的阶乘函数 定义一个计算n的阶乘的函数含参函数、if判断、for循环 写一个脚本去调用求阶乘的函数并定义一个变量 n 可用read交互输入最终输出 n的阶乘 结果 在kali中sh解释器的其实是指向dash解释器而dash解释器是bash解释器的简化版只有bash解释器的1/10左右的大小所以bash解释器可以支持更多更复杂的语法 sh解释器 jiechen() {local n$1local result1if [ $n -lt 0 ]; thenecho 错误: 阶乘只适用于非负整数return 1fifor i in $(seq 1 $n); doresult$((result * i))doneecho $result }read -p 请输入一个非负整数 n: nnn$(jiechen $n) echo n 的阶乘是: $nnbash解释器 jiechen() {local n$1local result1if (($n 0)); thenecho 请输入一个0的数字return 1fifor (( i1; in; i )); doresult$((result * i))doneecho $result }read -p 请输入一个非负整数 n: nnn$(jiechen $n) echo n 的阶乘是: $nn扩展 获取ipv4的地址 写⼀个Shell脚本去筛选出eth0⽹卡的ipv4地址并赋值⼀个变量输出 可以去了解grep、awk文本处理工具 ip_address$(ip a show eth0 | grep inet | awk $1inet {print $2} | cut -d / -f1 )if [ -z $ip_address ]; thenecho 没有找到eth0的ipv4的地址 elseecho eth0的ipv4的地址是: $ip_address ficrontab 将上⾯的脚本编辑到计划任务中并将echo输出内容重定向到⼀个固定⽂件中计划时间随意⼀天⼀次也可以 使用crontab -e命令进行写入选择nano 0 0 * * * /home/kali/桌面/dir/test/ipv4.sh ipv4.txt无限重启Linux 做⼀个像Windows中的⼀样⽆限重启脚本了解LINUX中的自启动 #!/bin/bashwhile true; doecho 5秒后重启sleep 5sudo reboot done使用nano进行写入 sudo nano /etc/systemd/system/cq.service写入内容 [Unit] DescriptionInfinite Reboot Service Afternetwork.target[Service] ExecStart/home/kali/桌面/dir/test/cq.sh Restartalways Userkali[Install] WantedBymulti-user.target启用并启动服务 sudo systemctl daemon-reload sudo systemctl enable cq.service sudo systemctl start cq.service失败了应该是sudo reboot哪里没有权限 使用root [Unit] DescriptionInfinite Reboot Service Afternetwork.target[Service] ExecStart/home/kali/桌面/dir/test/cq.sh Restartalways Userroot[Install] WantedBymulti-user.target可以了现在只需要写成一个脚本就行了
http://www.w-s-a.com/news/312651/

相关文章:

  • 网站改版被降权赣州景文网络科技有限公司
  • 吉林省网站建设推广图片模版
  • 如何做网站热力图佛山 网站关键词优化
  • 个人网站建设论文中期报告申报网站建设理由 模板
  • 岫岩做网站软件开发和app开发的区别
  • 邯郸质量一站式服务平台上线如何做国外销售网站
  • 内蒙古工程建设协会网站sem优化策略
  • Linux网站建设总结建设电子商务平台
  • 公司网站背景图片课程网站如何建设
  • 用js做简单的网站页面互联网技术对人力资源管理的影响有哪些
  • 银川做网站贵德县wap网站建设公司
  • 深圳网站建设zvge山西省煤炭基本建设局网站
  • 佛山网页网站设计线上怎么做推广和宣传
  • 多个域名绑定同一个网站案例
  • 建设网站都需要准备什么代理加盟微信网站建设
  • 网站备案没有了wordpress 添加按钮
  • 湖南建设银行宣传部网站福田蒙派克空调滤芯安装位置图
  • wap网站搜索wordpress工作室模板
  • 青岛金融网站建设如何提交网站地图
  • 制作简单门户网站步骤网站建设论文的摘要
  • 可以直接进入网站的正能量照片学做静态网站
  • 织梦做社交网站合适吗网站的市场如何制作
  • 阳曲网站建设价格多少四川佳和建设工程网站
  • 免费注册店铺位置sem seo什么意思
  • 建筑网站搜图电子商务网站建设渠道
  • 学校网站内容四川手机网站开发
  • 网站制作公司违法商业网站运营成本
  • 显示佣金的网站是怎么做的广告设计主要做哪些
  • 做阿里网站的分录济南seo网站排名关键词优化
  • 北京建设银行纪念钞预定官方网站wordpress中文优化版