当前位置: 首页 > 科技观察

BashShell脚本初学者指南(第2部分)

时间:2023-03-16 18:02:31 科技观察

欢迎阅读BashShell脚本初学者的第二部分。本文将深入探讨Bash脚本的一些更独特的方面。我们将使用上一篇文章中我们已经熟悉的一些命令(如果遇到新命令,我们会给出解释),然后涵盖标准输出、标准输入、标准错误、“管道”和数据重定向的一些相关知识.使用#添加注释随着脚本变得越来越复杂和有用,我们需要添加注释以便我们记住程序在做什么。如果您与他人分享您的脚本,评论也将帮助他们理解思考过程并更好地理解您的脚本的作用。回想上一篇文章中的数学方程式,我们在新版本的脚本中添加了一些注释。请注意,在learnToScript.sh文件(如下所示)中,注释是以#符号开头的行。脚本运行时不会出现这些注释行。#!/bin/bash#让我们从上一篇文章开始。我们#learnedhowtousemathematicalequations#inbashscripting.echo$((5+3))echo$((5-3))echo$((5*3))echo$((5/3))[zexcon~]$./learnToScript.sh82151管道|我们将使用另一个名为grep的工具来介绍管道运算符。grep可以在输入文件中搜索与指定模式匹配的行。默认情况下,grep将输出相应的匹配行。https://www.gnu.org/software/grep/PaulW.Frields在《Fedora 杂志》上的文章很好地介绍了grep。命令行快捷提示:使用grep搜索管道键位于键盘回车键上方,英文按Shift+\即可输入。现在您对grep已经有些熟悉了,让我们看一个使用pipe命令的示例。输入ls-l|grep在命令行学习。[zexcon~]$ls-l|grep学习-rwxrw-rw-。1zexconzexcon70Sep1710:10learnToScript.sh通常ls-l命令会在屏幕上显示文件列表。这里ls-l命令的完整结果通过管道传输到grep命令以搜索字符串learn。您可以将管道命令视为过滤器。首先运行一个命令(在这种情况下是ls-l,结果将给出目录中的文件),这些结果通过管道传递给grep命令,它将在其中搜索learn,并且只显示符合条件的目标行。再看一个例子,巩固一下相关知识。less命令允许用户查看超过一个屏幕大小的命令结果。以下是命令手册页中less的简要说明。less是一个类似于more的程序,但它允许页面在文件中前后移动。此外,less不必在启动前读取整个输入文件,因此对于大型输入文件,它的启动速度比文本编辑器(如vi)快。此命令较少使用termcap(或某些系统上的terminfo),因此它适用于各种终端。甚至还支持硬拷贝终端的端口。(在硬拷贝终端上,显示在屏幕顶部的行将以插入符号为前缀。)下面的Fedora34手册页让我们看看pipe命令与less命令结合使用时的样子。[zexcon~]$ls-l/etc|总计1504drwxr-xr-x。1rootroot126Jul717:46abrt-rw-r--r--。1rootroot18Jul716:04adjtime-rw-r--r--。1rootroot1529Jun232020别名drwxr-xr-x。1rootroot70Jul717:47alsadrwxr-xr-x。1rootroot23年4月14日05:58cron.ddrwxr-xr-x。1根根02021年1月25日cron.daily::为便于阅读,此处对结果进行了修整。用户可以使用键盘上的箭头键向上或向下滚动来控制显示。如果使用命令行,如果结果超出屏幕,用户可能看不到结果的第一行。要退出less屏幕,只需按q键。标准输出(stdout)重定向>,>>,1>,1>>>or>>>符号前的命令输出将写入紧跟在in后面的相应文件名文件。>与1>效果相同,因为1代表标准输出。如果您未明确指定1,则默认为标准输出。>>和1>>将数据追加到文件末尾。使用>或>>时,如果文件不存在,则会创建相应的文件。例如,如果您想查看ping命令的输出,看看它是否丢弃了数据包。不要专注于控制台,而是将输出重定向到一个文件,以便您稍后可以回来查看是否丢弃了数据包。下面是使用>的重定向测试。[zexcon~]$ls-l~>learnToScriptOutput这个命令会得到应该输出到终端的结果(~代表主目录),并重定向到learnToScriptOutput文件。请注意,我们没有手动创建learnToScriptOutput,该文件是自动创建的。总共128drwxr-xr-x。1zexconzexcon26810月1日16:02Desktopdrwxr-xr-x。1zexconzexcon80Sep1608:53文档drwxr-xr-x。1zexconzexcon010月1日15:59下载-rw-rw-r--。1zexconzexcon68510月4日16:00learnToScriptAllOutput-rw-rw-r--。1zexconzexcon23Oct412:42learnToScriptInput-rw-rw-r--。1zexconzexcon010月4日16:42learnToScriptOutput-rw-rw-r--。1zexconzexcon5210月4日16:07learnToScriptOutputError-rwxrw-rw-。1zexconzexcon47710月4日15:01learnToScript.shdrwxr-xr-x。1zex0conzexconJul716:04Videos标准错误(stderr)将命令的错误消息输出重定向到2>,2>>>或>>>符号之前,将被写入与以下文件名对应的文件中。2>和2>>效果相同,但2>>将数据追加到文件末尾。你可能会想,这有什么好处?让我们想象一个场景,用户只是想捕获错误信息,然后你就会实现2>或2>>的作用。数字2表示应该输出到终端的标准错误信息输出。下面我们尝试追踪一个不存在的文件,来尝试一下这个知识点。[zexcon~]$ls-l/etc/invalidTest2>learnToScriptOutputError这会生成错误消息并将错误消息重定向到learnToScriptOutputError文件。ls:cannotaccess'/etc/invalidTest':Nosuchfileordirectory所有输出重定向&>,&>>,|&如果你不想要标准输出(stdout)和标准错误信息(stderr)到不同的文件,那么在Bash5中,您可以使用&>将标准输出和标准错误重定向到同一个文件,或者使用&>>附加到文件末尾。[zexcon~]$ls-l~&>>learnToScriptAllOutput[zexcon~]$ls-l/etc/invalidTest&>>learnToScriptAllOutput运行这些命令后,两者的输出都会进入同一个文件,不区分错误信息还是标准输出。总共128drwxr-xr-x。1zexconzexcon26810月1日16:02Desktopdrwxr-xr-x。1zexconzexcon80Sep1608:53文档drwxr-xr-x。1zexconzexcon010月1日15:59下载-rw-rw-r--。1zexconzexcon68510月4日16:00learnToScriptAllOutput-rw-rw-r--。1zexconzexcon23Oct412:42learnToScriptInput-rw-rw-r--。1zexconzexcon010月4日16:42learnToScriptOutput-rw-rw-r--。1zexconzexcon5210月4日16:07learnToScriptOutputError-rwxrw-rw-。1zexconzexcon47710月4日15:01learnToScript.shdrwxr-xr-x。1zex0conzexconJul716:04Videosls:cannotaccess'/etc/invalidTest':Nosuchfileordirectory实现。[zexcon~]$ls-l|&grep学习-rw-rw-r--。1zexconzexcon119710月18日09:46learnToScriptAllOutput-rw-rw-r--。1zexconzexcon34310月14日10:47learnToScriptError-rw-rw-r--。1zexconzexcon010月14日11:11learnToScriptOut-rw-rw-r--。1zexconzexcon34810月14日10:27learnToScriptOutError-rwxr-x---。1zexconzexcon328Oct1809:46learnToScript.sh[zexcon~]$标准输入(stdin)在这篇和上一篇文章中,我们多次使用标准输入(stdin),因为每次我们使用键盘输入,我们有使用标准输入。为了区分通常意义上的“键盘就是标准输入”,这次我们尝试在脚本中使用read命令。下面的脚本中使用了read命令,字面意思是“读取标准输入”。#!/bin/bash#这里我们提出一个问题来提示用户进行标准输入。即keyboardecho'Pleaseenteryourname.'#这里我们正在读取标准输入并使用读取命令将其分配给变量名称。readname#Wearenowgoingbacktostandardoutput,byusingechoandprintingyournametothecommandline.echo"Withstandardinputyouhavetellmeyournameis:$name"此示例通过标准输出给出提示,提醒用户输入信息,然后从标准输入(键盘)获取信息,使用read存储到变量name中,通过标准输出显示name中的值。[zexcon@fedora~]$./learnToScript.shPleaseenteryourname.zexconWithstandardinputyouhavetellmeyournameis:zexcon[zexcon@fedora~]$在脚本中使用现在我们把学到的东西放到脚本中,学习如何在实践中应用它。下面是添加几行后的新版本的learnToScript.sh文件。它附加标准输出、标准错误信息以及两到三个不同文件的混合信息。它将标准输出写入learnToScriptStandardOutput,将标准错误写入learnToScriptStandardError,并将两者都写入learnToScriptAllOutput文件。#!/bin/bash#我们知道这篇文章是关于脚本的。所以让我们#use我们在脚本中学到的东西。#让我们从用户那里获取一些信息,并将其添加到我们的脚本中,使用标准输入和readecho"Whatisyourname?"readname#HerestandardoutputdirectedtoappendafiletolearnToScirptStandardOutputecho"$name,thiswilltakestandardoutputwithappend>>并重定向到learnToScriptStandardOutput。”1>>learnToScriptStandardOutput#Here我们获取标准错误并将其附加到learnToScriptStandardError但要看到这一点,我们需要#createanerror.eco"Standarderrorwithappend>>redirecttolearnToScriptStandardError."2>>learnToScriptStandardError#Here我们将创建一个错误和一个标准输出,并查看它们去同一个地方。回声“带附加的标准输出>>重定向到learnToScriptAllOutput。”&>>learnToScriptAllOutputeco"附加标准错误>>redirecttolearnToScriptAllOutput."&>>learnToScriptAllOutput脚本在同一个目录下创建了三个文件。命令echo故意打错(LCTT译注:缺少字母h)产生错误信息。如果你看这三个文件,你会在learnToScriptStandardOutput中看到一条消息,在learnToScriptStandardError中看到一条消息,在learnToScriptAllOutput中看到两条消息。此外,脚本会提示再次输入名称值,然后将其写入learnToScriptStandardOutput。结论在至此,你应该能明白,在命令行可以执行的操作,在脚本中也可以执行。可能是别人在写文档的时候使用脚本的时候非常重要。标准输出使得很多如果您深入研究脚本,这是有道理的,因为您可以控制它们的生成方式。在脚本中,您可以应用与从命令行应用相同的内容。下一篇在本文中我们将讨论函数、循环和构建在它们之上的进一步结构。