资讯动态

【Shell脚本学习】

发布时间:2026/10/27 1:18:02 来源:尧图企业网站定制
目录1、运行shell脚本三种方式2、变量赋值3、字符串4、数组5、变量的值6、多行注释7、算术运算符8、关系运算符9、布尔运算符10、逻辑运算符11、字符串运算符12、文件测试运算符13、echo14、输入/输出重定向15、printf16、test17、流程控制18、let19、函数20、操作键盘输入21、select与case22、多命令逻辑执行顺序23、包含外部脚本24、获取进程ID25、杀进程26、xargs27、chattr28、自动输入sudo的密码shell脚本格式 第一行#后面跟的是解释器的路径shell本身是一种解释型语言1、运行shell脚本三种方式./脚本文件调用解释器使得脚本执行bash、csh、ash、bsh、ksh等如bash 脚本文件source 脚本文件分别用三种方式运行一个有cd命令的脚本第一和第二种不会切换目录第三种会切换。因为第一第二种执行脚本时系统会创建一个子进程或者说子shell来执行脚本原进程或父shell在整个过程中会等待子进程执行完毕然后子进程退出父进程也退出。cd命令确实被执行了但是仅仅是在子进程中改变了工作目录所以脚本执行完后使用pwd显示工作目录并没有改变。而第三种执行的shell脚本并不创建子进程就是在原来的进程中执行所以最后的目录改变了。一个脚本调用另一个脚本时三种方式都不cd成功因为cd是在被调用的脚本source FileName作用:在当前 bash 环境下读取并执行 FileName 中的命令。该 filename 文件可以无 “执行权限”。sh FileName 或 bash FileName作用:打开一个子 shell 来读取并执行 FileName 中命令。该 filename 文件可以无 “执行权限”。./FileName作用: 打开一个子 shell 来读取并执行 FileName 中命令该 filename 文件需要 “执行权限”。注运行一个 shell 脚本时会启动另一个命令解释器。2、变量赋值等号前后不可以有空格还可以语句赋值for file in ls /etc 或 for file in $(ls /etc)使用一个定义过的变量在变量名前面加美元符号使用时才加$重新赋值时不用加变量名外面的花括号是可选的加不加都行加花括号是为了帮助解释器识别变量的边界推荐给所有变量加上花括号欲想给变量赋一个命令的执行结果例varpidof processname使用 readonly 命令可以将变量定义为只读变量只读变量的值不能被改变。给只读变量赋值会报错但会继续往下执行命令行可以这样使用ll pwd/ipconfig3、字符串字符串可以用单引号也可以用双引号也可以不用引号。单引号字符串的限制 单引号里的任何字符都会原样输出单引号字符串中的变量是无效的单引号字串中不能出现单独一个的单引号对单引号使用转义符后也不行但可成对出现作为字符串拼接使用。双引号的优点 双引号里可以有变量双引号里可以出现转义字符your_namerunoob# 使用双引号拼接greetinghello, $your_name !greeting_1hello,${your_name}!echo$greeting$greeting_1# 使用单引号拼接greeting_2hello, $your_name !greeting_3hello, ${your_name} !echo$greeting_2$greeting_3输出hello, runoob ! hello, runoob ! hello, runoob ! hello, ${your_name} !获取字符串长度stringabcd echo ${#string} #输出 4提取子字符串stringrunoob is a great site echo ${string:1:4} # 从字符串第 2 个字符开始截取 4 个字符输出 unoo注意第一个字符的索引值为 0。更详细的字符串提取、截取菜鸟教程下面笔记查找子字符串查找字符 i 或 o 的位置(哪个字母先出现就计算哪个)stringrunoob is a great site echo expr index $string io # 输出 4git组合命令git log --since2021-10-01 --until2021-10-31 --authorname --prettytformat: --numstat | awk { add $1; subs $2; loc $1 - $2; total $1 $2 } END { printf 新增代码行: %s\n 移除代码行: %s\n 总增加代码行: %s\n 总修改代码行: %s\n, add, subs, loc, total }4、数组用括号来表示数组数组元素用空格符号分割开。定义数组的一般形式为 数组名(值1 值2 … 值n)读取数组元素值的一般格式是${数组名[下标]}使用 符号可以获取数组中的所有元素echo ${array_name[]}获取数组元素的个数length${#array_name[]} 或者 length${#array_name[*]}取得数组单个元素的长度lengthn${#array_name[n]}5、变量的值引用变量的值例$变量名$0表示程序名$1表示第1个参数$2表示第2个参数, $n…$* 这个程式的所有参数$ 跟$*类似但是可以当作数组用$# 这个程式的参数个数$$ 这个程式的PID(脚本运行的当前进程ID号)$! 执行上一个背景指令的PID(后台运行的最后一个进程的进程ID号)$? 执行上一个指令的返回值 (显示最后命令的退出状态。0表示没有错误其他任何值表明有错误)$- 显示shell使用的当前选项与set命令功能相同$0获取的文件名包括./以及路径等前缀信息如果想仅得到文件名而不包含./可以使用basename命令namebasename $0 echo The command entered is: $name想获取所有的参数当然可以利用$#和循环逐个遍历。也可以利用如下两个特殊变量$*将所有的命令行参数看作一个整体存储而$将命令行中以空格间隔的参数单独存储可测试打印forparamin$*forparamin$echoThe last parameter is:${$#}# 按道理输出最后一个参数实则不然。因为在花括号内不能使用$符号而是以!来代替$工作需要这样echoThe last parameter is:${!#}6、多行注释:EOF注释内容…注释内容…EOF(EOF 也可以使用其他符号如’、!)7、算术运算符 加法 expr $a $b - 减法 expr $a - $b * 乘法 expr $a \* $b / 除法 expr $b / $a % 取余 expr $b % $a 赋值 a$b 将把变量 b 的值赋给 a 相等。用于比较两个数字相同则返回 true。 [ $a $b ] ! 不相等。用于比较两个数字不相同则返回 true。 [ $a ! $b ] 注意条件表达式要放在方括号之间并且要有空格例如: [$a$b] 是错误的必须写成 [ $a $b ]。8、关系运算符关系运算符只支持数字不支持字符串除非字符串的值是数字。-eq 检测两个数是否相等相等返回 true。-ne 检测两个数是否不相等不相等返回 true。-gt 检测左边的数是否大于右边的如果是则返回 true。-lt 检测左边的数是否小于右边的如果是则返回 true。-ge 检测左边的数是否大于等于右边的如果是则返回 true。-le 检测左边的数是否小于等于右边的如果是则返回 true。9、布尔运算符! 非运算 -o 或运算 -a 与运算10、逻辑运算符 逻辑的 AND || 逻辑的 OR11、字符串运算符检测两个字符串是否相等相等返回 true。[$a$b]!检测两个字符串是否不相等不相等返回 true。[$a!$b]-z检测字符串长度是否为0为0返回 true。[-z$a]-n检测字符串长度是否不为0不为0返回 true。[-n$a]#这里应该加上双引号否则 -n $a 的结果永远是 true$ 检测字符串是否为空不为空返回 true。[$a]12、文件测试运算符-b file 检测文件是否是块设备文件如果是则返回 true。-c file 检测文件是否是字符设备文件如果是则返回 true。-d file 检测文件是否是目录如果是则返回 true。-f file 检测文件是否是普通文件既不是目录也不是设备文件如果是则返回 true。-g file 检测文件是否设置了 SGID 位如果是则返回 true。-k file 检测文件是否设置了粘着位(Sticky Bit)如果是则返回 true。-p file 检测文件是否是有名管道如果是则返回 true。-u file 检测文件是否设置了 SUID 位如果是则返回 true。-r file 检测文件是否可读如果是则返回 true。-w file 检测文件是否可写如果是则返回 true。-x file 检测文件是否可执行如果是则返回 true。-s file 检测文件是否为空文件大小是否大于0不为空返回 true。-e file 检测文件包括目录是否存在如果是则返回 true。-S: 判断某文件是否 socket。-L: 检测文件是否存在并且是一个符号链接。13、echoecho“”文件路径#清空文件echo“test”文件路径#清空文件写入字符echo“test”文件路径#追加重定向输入某个位置文件2重定向错误输出2重定向错误追加输出到文件末尾混合输出错误的和正确的都输出14、输入/输出重定向commandfile将输出重定向到 file。commandfile将输入重定向到 file。commandfile将输出以追加的方式重定向到 file。 nfile将文件描述符为 n 的文件重定向到 file本来需要从键盘获取输入的命令会转移到文件读取内容 nfile将文件描述符为 n 的文件以追加的方式重定向到 file。 nm 将输出文件 m 和 n 合并。 nm 将输入文件 m 和 n 合并。tag 将开始标记 tag 和结束标记 tag 之间的内容作为输入。需要注意的是文件描述符 0 通常是标准输入通常是键盘1 是标准输出通常是屏幕2 是标准错误输出。重定向深入讲解。一般情况下每个 Unix/Linux 命令运行时都会打开三个文件标准输入文件(stdin)stdin的文件描述符为0Unix程序默认从stdin读取数据。标准输出文件(stdout)stdout 的文件描述符为1Unix程序默认向stdout输出数据。标准错误文件(stderr)stderr的文件描述符为2Unix程序会向stderr流中写入错误信息。默认情况下command file 将 stdout 重定向到 filecommand file 将stdin 重定向到 file。如果希望 stderr 重定向到 file可以这样写$ command 2file如果希望执行某个命令但又不希望在屏幕上显示输出结果那么可以将输出重定向到 /dev/null$ command /dev/null/dev/null 是一个特殊的文件写入到它的内容都会被丢弃如果尝试从该文件读取内容那么什么也读不到。但是 /dev/null 文件非常有用将命令的输出重定向到它会起到禁止输出的效果。如果希望屏蔽 stdout 和 stderr可以这样写$ command /dev/null 2115、printfprintf 中可格式化字符串还可以制定字符串的宽度、左右对齐方式等。默认printf不会像echo自动添加换行符我们可以手动添加 \n16、testtest 命令用于检查某个条件是否成立它可以进行数值、字符和文件三个方面的测试。17、流程控制ifconditionthencommandfiforvarinitem1 item2... itemNdocommanddonewhileconditiondocommanddoneuntilconditiondocommanddonecase值in模式1)command1;;模式2 command2;;esacbreak命令允许跳出所有循环终止执行后面的所有循环continue命令与break命令类似只有一点差别它不会跳出所有循环仅仅跳出当前循环。18、letlet 命令是 BASH 中用于计算的工具用于执行一个或多个表达式变量计算中不需要加上 $ 来表示变量。如果表达式中包含了空格或其他特殊字符则必须引起来。如自加操作let no19、函数[function]funname[()]{action;[return int;]}可以带function fun() 定义也可以直接fun() 定义,不带任何参数。参数返回可以显示加return 返回如果不加将以最后一条命令运行结果作为返回值。20、操作键盘输入read-p请输入一段文字:-n6-t5-spasswordecho-e\npassword is$password提示-p 输入提示文字-n 输入字符长度限制(达到6位自动结束)-t 输入限时-s 隐藏输入内容将输入文本颜色设置为与背景色一样read命令中可根据需要将输入的数据保存在多个变量中如指定的变量比较少那么最后一个变量将包含余下的所有输入。如使用read命令时不指定变量那么read将其接收的任何数据都放到环境变量REPLY中。使用read命令时脚本会一直等待用户输入数据如果想设置等待时间使用-t选项即可指定一个计时器当计时器超时后read命令会返回一个非零状态码。ifread-t5-pPlease enter your name: namethenechoHello$name.elseechoSorry, too slowfiread每次从文件中读取一行数据当文件中没有数据时read命令返回非零状态码。最常见的方法是将cat命令运行后的结果通过管道传给含有read的while语句。count1cat25.sh|whilereadlinedoechoLine$count:$linecount$[$count1]done21、select与case#!/bin/bash# sh解释器不支持select, bash支持;# 1、将解释器定为bash 2、运行时使用bash或者source命令运行脚本fruits(applepearorange)selectvarin${fruits[]};doechoYou have selected$varcase$varinapple*)echoapple;;pear*)echopear;;orange*)echoorange;;*)echoFile$1can not be uncompressed with smartzip;;esacif[$varpear];thenechosorry! you like pear.break# 没有遇到break不会退出选择循环fidone22、多命令逻辑执行顺序A.分号 ;command1 ; command2命令之间没有逻辑关系。分号连接的命令会按照顺序从前向后依次执行但分号两端的命令之间没有任何逻辑关系所有写出来的命令最终都会被执行即使分号前面的命令出错也不影响后面的命令。B.command1 command2逻辑与。连接的命令会按照顺序从前向后执行但只有当command1正确执行才执行command2如果command1不正确执行则不执行command2。在bash中通过预定义变量“? ”来判断命令是否正确执行如果 ?”来判断命令是否正确执行如果?”来判断命令是否正确执行如果?的值为0则表示前一条命令正确执行其他任意值都表示不正确执行。C.||command1 || command2逻辑或。||连接的命令会按照顺序从前向后执行但只有当command1不正确执行才执行command2command1正确执行则不会执行command2。||和都是短路符号符号左右的命令之间具有逻辑关系。D.command1 command1 command2表示将其前面的命令放入后台执行放入后台后会立即返回到bash环境让用户可以继续和bash交互。如果符号连接了两个命令则其前面的命令被放入后台立即执行后面的命令所以可以简单地认为这两个命令是并行执行的两端的命令之间也没有任何逻辑关系。需要注意的一点是在终端的bash环境下子shell中的后台的进程不受终端控制在终端被关闭时它会挂靠在init/systemd进程下因此退出终端或脚本shell环境无法中断这些后台进程。23、包含外部脚本包含外部脚本。这样可以很方便的封装一些公用的代码作为一个独立的文件。#!/bin/bash#使用 . 号来引用test1.sh 文件../test1.sh# 注意点号.和文件名中间有一空格# 或者使用以下包含文件代码# source ./test1.sh# 被包含的文件 test1.sh 不需要可执行权限。24、获取进程IDshell获取进程ID的方法a、ps -A |grep “cmdname”| awk ‘{print $1}’b、pidof “cmdname”c、pgrep “cmdname”这三种在bash和busybox ash里面的运行结果稍有不同第一种完全相同但是因为调用命令次数较多性能上是不行的。第二种pidof只能获取程序的文件名匹配到的进程号在ash中比如 pidof “usr/bin/telnetd” 和 pidof telnetd中结果不一样前一种结果为空但是在bash中执行两者一样。第三种pgrep跟1的效果相同因为是单一命令比第一种性能要好得多。25、杀进程kill [options] pid pkill processname26、xargsxargs是给命令传递参数的一个过滤器也是组合多个命令的一个工具。xargs 可以将管道或标准输入stdin数据转换成命令行参数也能够从文件的输出中读取数据。xargs 也可以将单行或多行文本输入转换为其他格式例如多行变单行单行变多行。xargs 默认的命令是 echo这意味着通过管道传递给 xargs 的输入将会包含换行和空白不过通过 xargs 的处理换行和空白将被空格取代。xargs 是一个强有力的命令它能够捕获一个命令的输出然后传递给另外一个命令。由于很多命令不支持|管道来传递参数而日常工作中有有这个必要所以就有了 xargs 命令https://www.runoob.com/linux/linux-comm-xargs.html27、chattrchattr命令用于改变文件属性。改变存放在ext2文件系统上的文件或目录属性共有以下8种模式a让文件或目录仅供附加用途。b不更新文件或目录的最后存取时间。c将文件或目录压缩后存放。d将文件或目录排除在倾倒操作之外。i不得任意更动文件或目录。s保密性删除文件或目录。S即时更新文件或目录。u预防意外删除。参数-R 递归处理将指定目录下的所有文件及子目录一并处理。-V 显示指令执行过程。属性 开启文件或目录的该项属性。-属性 关闭文件或目录的该项属性。例用chattr命令防止系统中某个关键文件被修改chattr i /etc/resolv.conf查看lsattr /etc/resolv.conf28、自动输入sudo的密码echo “admin” | sudo -S service tomcat7 stop参考linkexpect待学习本文内容参考公开技术文档如有侵权请联系删除。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑