bash脚本编程基础

发布时间:2026/9/4 21:10:29
bash脚本编程基础 1.1.1 为什么学ShellShell脚本语言, 是实现Linux/UNIX系统管理所用的, 那是必备的一种相当重要的工具, Linux/UNIX系统底层的核心之处, 还有基础应用软件的核要部分, 大多都和Shell脚本的相关内容有所关联。每一位称得上合格的, Linux系统管理员或者运维工程师, 都得要能够熟练地去编写Shell脚本语言才行, 并且还得能够读懂, 系统和各类软件附带的Shell脚本内容。唯有如此方可使得运维人员的工作效率得以提高, 去适应日益繁杂的工作环境, 将没必要的重复性工作予以减少, 进而为个人的职场发展奠定较为良好的基础。1.1.2 什么是shellShell是个命令解释器, 它处于操作系统最外层, 负责径直跟用户对话, 将用户输入诠释给操作系统, 还处理各类操作系统输出结果, 把屏幕返回结果输出给用户。这种对话方式可以是交互的形式是, 自键盘键入命令, 借由/bin/bash 的剖析, 能够即刻获取 Shell 的回应。[rootclsn ~]# ls anaconda-ks.cfg [rootclsn ~]# echo ls |bash anaconda-ks.cfg非交互的方式: 脚本1.1.3 什么是Shell脚本命令、变量和流程控制语句等有机的结合起来擅长处理纯文本类型数据的是shell脚本, 在linux里, 几乎所有的配置文件, 都是纯文本类型文件, 日志也是纯文本类型文件。1.1.4 脚本语言的种类一、编译型语言表述为: 专用的编译器, 针对特定操作平台操作系统, 把某种高级语言源代码, 一次性翻译成能被硬件平台直接运行的二进制机器码含操作数、指令及相应格式之类, 此过程称作编译./ make编译好的可执行性文件.exe, 能在相对应平台运行移植性差, 不过运行效率高。典型的编译型语言有 C语言、C等。此外, Java语言属于一门极为特殊的语言, Java程序必须经历编译步骤, 然而却并不产生特定平台的二进制机器码, 它编译之后生成的是一种和平台毫无关联的字节码文件*.class此乃移植性良好的缘由, 这种字节码理所当然无法被平台直接予以执行, 运行之际需要借助解释器诠释为相应平台的二进制机器码文件绝大多数人认定Java是一种编译型语言, 但是我们讲Java可谓是编译型语言, 同时也是解释型语言亦并无差错。二、解释型语言这样一种语言, 它的定义是, 使用专门的解释器, 要对源程序一行一行地去解释, 解释成特定平台的机器码, 然后马上就执行, 它就如同是把编译型语言的编译以及链接这两个过程混合在一起, 同时进行并完成的。执行上, 解释型语言效率相比于常规的较低, 并且它没办法脱离解释器单独运行, 不过呢它在不同平台之间的交互性是比较容易实现满足成功的, 只要提供特定的解释器就可以达成实现了。常见的解释型语言有 同时是脚本语言与Ruby等。三、脚本语言有一种计算机编程语言, 它是被定义出来的, 其目的在于, 以此来缩短传统的那种编写、编译、链接、运行, 也就是edit--link--run这个过程并且使之得以出现并且存在。特点是, 程序代码就是最终的执行文件, 只是, 实现这个情况需要解释器参与其中, 所以, 脚本语言跟解释型语言存在很大的联系, 脚本语言一般是被解释执行的, 并且, 程序属于文本文件。典型的脚本语言有shell等。其他常用的脚本语句种类PHP属于网页程序范畴, 同时也是一种脚本语言, 它是一款在web页面开发前端展示领域更为专注定向的脚本语言, 像PHP程序能够用于处理系统日志、配置文件等, 并且此语言中的php还具备调用系统命令之能力。Perl脚本语言, 它比shell脚本强大许多, 其语法具备灵活性且复杂, 有着诸多实现方式, 不易读懂, 会使团队协作变得困难, 但它仍旧算是很好的一种脚本语言哦, 这世间留存着大量用该语言编写的程序软件, 比如说MHA高可用这一软件就是用Perl写的。不仅能够开展脚本程序方面的有关开发, 还能够达成 web 程序以及软件的有关开发, 近两年之中越来越多许多的公司都都会提出拥有掌握具备会的要求。Shell脚本与php/perl/语言的区别和优势处理操作系统底层各类业务, 这是shell脚本所具备的优势, 在linux系统之中, 其内部应用借助shell脚本来达成缘何能达成呢, 大量linux系统命令给予了它支撑, 2000多个命令, 都是对shell脚本编程有力的支持特别是像grep、awk、sed等这些命令, 在一键软件安装、优化、监控报警脚本以及常规的业务应用里体现得尤为明显, 运用shell进行开发, 更为简单且快速, 遵循了运维方面简单、易用、高效的原则。PHP, 其优势体现在开发运维工具方面, 还在于web界面的管理工具方面, 以及web业务的开发当中。于处理一键软件安装方面, 在优化方面, 对报警脚本而言, 亦或是常规业务的应用等方面, php/同样是有能力达成的。然而, 其开发效率同复杂程度相比较, 要是与shell相比的话, 那可就差了许多了。系统环境说明[rootclsn scripts]# cat /etc/redhat-release #查看当前版本 CentOS Linux release 7.4.1708 (Core) [rootclsn scripts]# uname -r #查看当前内核版本 3.10.0-693.el7.x86_64 [rootclsn scripts]# getenforce #使用getenforce命令可以显示当前SELinux的应用模式是强制、执行还是停用。98 Disabled [rootclsn scripts]# systemctl status firewalld.service #查看当前防火墙状态 firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled) Active: inactive (dead) Docs: man:firewalld(1)补充uname命令操作系统信息的显示利用uname命令, 其主要作用在于针对操作系统, 让显现版本、平台等方面信息得以达成标点符号。它的参数主要有以下-a 显示全部信息-s 显示内核名称-n 显示主机名-r 显示当前系统的内核版本-m 显示主机的硬件名称-p 显示处理器的类型-i 显示主机的硬件平台-o 显示所使用的操作系统的名称扩展root ~# //查看当前系统为32位root ~发出指令, 通过该指令, 对特定文件进行操作, 此操作目的在于, 查看当前系统的类型, 该文件为特定路径的文件。1.1.5 系统中的shell查看系统中的命解释器[rootclsn ~]# cat /etc/shells #显示系统拥有的shell /bin/sh /bin/bash /sbin/nologin /usr/bin/sh /usr/bin/bash /usr/sbin/nologin常用操作系统的默认shell1.Linux是 Again shellbash2.和缺省的是 shellsh3.AIX下是Korn Shellksh4.HP-UX缺省的是POSIX shellsh[rootclsn ~]# echo $SHELL #显示当前默认sell /bin/bashbash版本[rootclsn scripts]# bash -version #显示当前shell版本 GNU bash 版本 4.2.46(2)-release (x86_64-redhat-linux-gnu) Copyright (C) 2011 Free Software Foundation, Inc. 许可证 GPLv3: GNU GPL 许可证版本3或者更高 这是自由软件您可以自由地更改和重新发布。 在法律允许的范围内没有担保.1.2 脚本书写规范1.2.1 脚本统一存放目录[rootclsn ~]# mkdir -p /server/scripts/ [rootclsn ~]# cd /server/scripts/1.2.2 选择解释器注意格式 ↓其中, 开头的“#!”字符, 又被称作幻数, 在执行bash脚本之际, 内核会依据“#!”后面的解释器, 来明确该使用哪个程序, 去解释这个脚本里的内容。[rootclsn scripts]# head -1 /etc/init.d/* /etc/init.d/functions # -*-Shell-script-*- /etc/init.d/netconsole #!/bin/bash /etc/init.d/network #! /bin/bash1.2.3 编辑脚本使用vim使用 .vimrc 文件能够快速的生成开头的注释信息[rootclsn scripts]# cat ~/.vimrc autocmd BufNewFile *.py,*.cc,*.sh,*.java exec :call SetTitle() func SetTitle() if expand(%:e) sh call setline(1,#!/bin/bash) call setline(2, ##############################################################) call setline(3, # File Name: .expand(%)) call setline(4, # Version: V1.0) call setline(5, # Author: clsn) call setline(6, # Organization: call setline(7, # Created Time : .strftime(%F %T)) call setline(8, # Description:) call setline(9, ##############################################################) call setline(10, ) endif endfunc使用后的效果[rootclsn scripts]# cat scripts_test.sh #!/bin/bash ############################################################## # File Name: scripts_test.sh # Version: V1.0 # Author: clsn # Organization: # Created Time : 2017-12-04 11:39:57 # Description: First scripts file ##############################################################于Shell脚本里, 跟在#后边的内容意为注释, 注释部分并不会执行, 仅仅是给人看的, 注释能够自成一行, 也能够跟在命令后头, 与命令为同行, 要养成书写注释的习惯, 以便利于自己以及他人。最理想的情况是不采用中文注释, 鉴于在不同字符集的系统当中会出现乱码的状况。此时字符集是zh_CN.UTF-8, 属于中文。1.2.4 文件名规范名字要有意义并且结尾以 .sh 结束1.2.5 开发的规范和习惯小结1) 放在统一的目录2) 脚本以.sh为扩展名3) 开头指定脚本解释器。4) 加在之前版本版权等信息, 是可以进行配置的, 能够通过~/.vimrc文件自动实现添加。5) 脚本不要用中文注释尽量用英文注释。6) 代码书写优秀习惯a、依次将成对出现的项目, 在同一时间全部予以写出, 从而避免出现遗漏的情况, 诸如、 、等等。b、两端要有空格先输入,退格输入2个空格再退格写。c、流程控制语句, 要先一次书写完毕, 之后再向其中添加内容, (if 条件 ; then 内容;fi)ddd。d、通过缩进让代码易读。f、脚本里头的引号, 全都是处于英文状态之下的引号, 别的字符同样是英文状态。1.3 shell脚本的执行1.3.1 执行脚本的办法sh/bash scripts.sh chown x ./scripts.sh ./scripts.sh source scripts.sh . (空格) scripts.sh cat oldboyedu.sh |bash # 效率较低与 . 点 的作用命令[rootclsn ~]# help source |head -2 source: source 文件名 [参数] 在当前 shell 中执行一个文件中的命令。. (点)[rootclsn scripts]# help . |head -2 .: . 文件名 [参数] 在当前 shell 中执行一个文件中的命令。1.3.2 sh 于 的区别[rootclsn scripts]# sh clsn_test.sh Hello World! [rootclsn scripts]# echo $clsn # sh 新建一个Shell窗口新建一个进程执行一个文件中的命令。 [rootclsn scripts]# source clsn_test.sh Hello World! [rootclsn scripts]# echo $clsn Hello World!补充Linux中执行 .sh 的方法复制代码linux下执行.sh文件的方法以文本形式存在的.sh文件, 若要使其能够被执行, 那就得运用chmod ax xxx.sh这种方式来赋予其可执行的权限。是bash脚本么可以用touch test.sh #创建test.sh文件vi test.sh #编辑test.sh文件加入内容#/bin/bashmkdir test保存退出。给名为test.sh的文件, 赋予所有用户可执行的权限, 操作是执行chmod ax test.sh。如test,sh文件在 /home/work文件下执行方法一 本身目录下运行进入 cd /home/文件下执行 ./test.sh命令会在当前目录下创建一个“test”目录。方法二 绝对路劲运行执行 /home/work/test.sh方法三 本身目录下运行sh test.sh最后建议:使用C代码1.man shman sh 来看看sh 的介绍Linux.sh语法介绍1 开头程序必须以下面的行开始必须方在文件的第一行#!/bin/sh符号#!, 其作用是向系统表明, 它后面跟着的参数, 乃是用于执行该文件的程序。在这个例子当中, 我们借助/bin/sh来达成程序的执行。当编写脚本完成时如果要执行该脚本还必须使其可执行。要使编写脚本可执行编译 chmod x 这样才能用./ 来运行2 注释对于shell编程而言, 若有以#开头的相关语句之处, 那部分便是处于被标明为注释, 此状况会一直持续行进到这一行的最终末端位置。我们是以无比真诚的态度向您提出建议, 希望您能够在整个程序里面使用这类注释。要是您运用了注释, 即便好长的某段时间之内都没有运用该脚本, 您也能够在极短的片刻时间里弄清楚该脚本的作用以及其工作原理。3 变量在别的编程语言里头, 您是必须得使用变量的。于shell编程当中, 所有的变量都是由字符串给构成的, 而且您是不需要去对变量做声明的。要是想要给一个变量赋值, 您能够像下面这样来写:#!/bin/sh#对变量赋值a”hello world”# 现在打印变量a的内容echo “A is:”echo $a有时候变量名很容易与其他文字混淆比如num2echo “this is the $numnd”这不会打印出”this is the 2nd”, 只会打印”this is the “原因在于, shell会去搜索变量numnd的值, 可这个变量没有值。能够使用花括号告知shell, 我们要打印的是num变量:num2echo “this is the ${num}nd”这将打印 this is the 2nd4 环境变量经过关键字处理的变量被称作环境变量, 我们不就环境变量展开讨论, 因为一般情形下, 环境变量仅仅在登录脚本里予以使用。5 Shell命令和流程控制在shell脚本中可以使用三类命令1)Unix 命令:即便于shell脚本里能够运用任意的unix命令, 然而依旧存在一些相对更为常用的命令, 这些命令通常是用以开展文件和文字操作的。常用命令语法及功能echo “some text”: 将文字内容打印在屏幕上ls: 文件列表wc, 通过启用 –l 选项, 来着手计算文件行数, 借助 –w 选项, 用以计算文件中的单词数, 利用 –c 选项, 针对 file 计算文件中的字符数。cp : 文件拷贝mv : 重命名文件或移动文件rm file: 删除文件使用grep对某个文件进行操作, 也就是在该文件内搜索特定的字符串, 例如执行grep ’’ file.txt这样的指令。切割 -b 文件: 明确要展示的文件内容范畴, 并且把它们输出至标准输出设备, 比如说: 输出每一行从第5个到第9个字符, 切割 -b5 - 9 文件.txt, 千万不能跟 cat 命令弄混。这是两个完全不同的命令使用cat命令, 将file.txt这个文件的内容, 输出到标准输出设备, 也就是屏幕上。file : 得到文件类型read var: 提示用户输入并将输入赋值给变量将file.txt文件之中的行, 予以排序操作 , 使它们呈现出特定的顺序。uniq: 将文本文件里所出现的行列予以删除, 比如: sort file.txt之后再紧跟uniq。依照数学运算的要求, 操作是两个因素相加, 具体是把二与三予以相加, 其表达式为二加上符号“”再加上三。查找: 搜寻文件, 比如说: 依据文件名来查找, find. -name -print。tee, 它能够把数据输出到标准输出设备, 也就是屏幕, 并且它还可以输出到文件, 就像这样| tee。提取: 返回不含有路径的文件名, 举例来说, 像: /bin/tux这样的情况, 将会返回为tux。/file、返回、文件所在路径, 比如、/bin/tux将返回、/bin。head file: 打印文本文件开头几行tail file : 打印文本文件末尾几行Sed, 它属于那种基本的查找替换程序, 能够从标准输入, 就像命令管道那样, 去读入文本, 然后还会将。结果被输出至标准输出, 也就是屏幕。该命令借由正则表达式, 此正则表达式可见参考内容来展开搜索。切莫和shell当中的通配符产生混淆。举例来说, 将其替换成为: 以cat text.file | sed ’s///’ .这条指令为例 , awk起到从文本文件里提取字段的作用。默认状态下 , 字段分割符是空格 , 能够运用 -F去指定别的分割符。这里我们运用, 将其当作字段分割符, 使用.txt通过awk -F, ‘{print $1 “,” $3}’, 来打印第一个和第三个字段。要是该文件内容有着这样的情况: Adam Bor, 34, , 22, USA, 那么命令输出结果就是: Adam Bor, , USA。2) 概念: 管道, 重定向和这些不是系统命令但是他们真的很重要。管道 (|) 将一个命令的输出作为另外一个命令的输入。grep “hello” file.txt | wc -l于file.txt里, 寻觅含有”hello”的行, 然后对其行数予以计算。这里, grep命令的输出是被当作了wc命令的输入的那种情况哦当然您是能够使用多个命令的呀。重定向将命令的结果输出到文件而不是标准输出屏幕。 写入文件并覆盖旧文件 加到文件的尾部保留旧文件内容。反短斜线想要把一个命令的输出当作另外一个命令的一个命令行参数, 是可以借助反短斜线来达成的。命令查找, 当前目录及其子目录下, 最近1日内有修改的, 文件类型为普通文件的, 那些项, 并打印显示全部。要找寻过去二十四小时之内注意, -mtime –2所代表的乃是过去四十八小时被修改过的文件。要是您打算把所有查找出来的文件打成一个包, 那么能够采用下面这个linux脚本:#!/bin/sh执行tar命令, 以压缩的方式, 将通过查找当前路径下, 修改时间在一天之内, 类型为文件的那些文件, 进行打包并生成.tar.gz格式的压缩包。3) 流程控制1.if“if” 表达式 如果条件为真则执行then后面的部分if ….; then….elif ….; then….else….fi绝大多数情形之下, 能够运用测试指令去针对条件予以测试。举例而言, 能够开展字符串的比较, 并且实施文件是否存在以及是否具备可读属性等的判定, 等等……一般而言, 会运用” “去展现条件测试。留意, 此处的空格是格外重要的。务必要保证方括号里的空格。-f 判断是否是一个文件-x /bin/ls判断/bin/ls是否存在并有可执行权限判断$var变量是否有值$a $b判断$a和$b是否相等将 man test 进行执行, 能够去查看, 所有测试表达式能够作比较以及进行判断的类型。直接执行以下脚本#!/bin/shif$SHELL /bin/bash; then反斜杠, 双引号, 你的登录外壳是那个, 再会外壳, 的, 巴什, 反斜杠, 双引号。else输出 “你的登录 shell 不是 bash 而是那个 $SHELL”, 这里的 echo, 是用来进行输出显示操作的, 让这样一句话得以呈现出来。fi变量得名$SHELL, 其涵盖登录shell的名称, 我们针对此, 与/bin/bash展开了比较。快捷操作符