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

如何使用Bash编程:语法和工具_0

时间:2023-03-19 17:58:47 科技观察

让我们学习基本的Bash编程语法和工具,以及如何使用变量和控制运算符,这是系列三篇文章中的第一篇。Shell是操作系统的命令解释器,其中Bash是我最喜欢的。每当用户或系统管理员向系统输入命令时,Linuxshell解释器都会将这些命令转换为操作系统可以理解的形式。执行结果返回给shell程序后,它会将结果输出到STDOUT(标准输出),默认情况下,这些结果会显示在你的终端中。我熟悉的所有shell也是编程语言。Bash是一个功能强大的shell,包括许多方便的功能,例如:制表符补全、命令回溯和重新编辑、别名等。它的命令行默认编辑模式是Emacs,但我最喜欢的Bash功能之一是我可以将其更改为Vi模式以使用存储在我的肌肉记忆中的那些编辑命令。但是,如果将Bash用作纯shell,则无法体验其真正的功能。在设计本系列文章所依据的Linux上的三卷自学课程时,我学到了很多我在Linux工作20年中没有学到的关于Bash的知识,包括我的一些知识是关于Bash的编程用法。不得不说,Bash是一门强大的编程语言,它是一个完美的设计,可以同时用于命令行和shell脚本。本系列文章探讨了如何将Bash用作命令行界面(CLI)编程语言。第一篇文章简要介绍了Bash命令行编程、变量和控制运算符。其他文章讨论了以下内容:Bash文件的类型;字符串、数字和一些逻辑运算符,它们提供对代码执行流程的逻辑控制;不同类型的外壳扩展;并使用for、while和until控制循环操作。ShellBash是BourneAgainShell的缩写,因为Bashshell是基于更早的Bourneshell,由StevenBourne于1977年开发的。还有许多其他的shell可用,但以下四种是我最常看到的:csh:适用于习惯C语言语法的开发人员的Cshell。ksh:Kornshell,由DavidKorn开发,在Unix用户中更受欢迎。tcsh:csh的变体,增加了一些易用性。zsh:结合了许多其他流行shell的功能的Zshell。所有shell都有内置命令来补充或替换核心工具集。打开shell的manpage,找到“BUILT-INS”部分,可以查看内置命令。每个shell都有自己的特性和语法风格。我用过csh、ksh和zsh,但我仍然更喜欢Bash。您可以尝试一些以找到更适合您的shell,尽管这可能需要一些工作。但幸运的是,shell之间的切换很容易。所有这些shell既是编程语言又是命令解释器。让我们快速浏览一下Bash中集成的编程结构和工具。Bash作为一种编程语言在大多数情况下,系统管理员使用Bash来发送简单明了的命令。但是Bash不仅仅是用来输入单个命令的,许多系统管理员可以编写简单的命令行程序来执行一系列任务,这些程序可以作为通用工具使用,省时省力。CLI程序被编写成高效的(成为一个“懒惰的”系统管理员)。在CLI程序中,您可以按特定顺序列出多个命令并一条一条执行。这样一来,你就不用盯着显示屏,等一个指令执行完毕,再输入另一个指令,省下来的时间就可以用来做其他事情了。什么是“程序”?免费在线计算词典(FOLDOC)将程序定义为:“由计算机执行的指令,而不是它们运行的??物理硬件。”普林斯顿大学的WordNet将程序定义为:“......计算机可以理解和执行的一系列指令......”维基百科也有一篇关于计算机程序的好文章。总之,一个程序由一条或多条指令组成,目的是完成特定的相关任务。对于系统管理员来说,一个程序通常由一系列shell命令组成。Linux下所有的shell(至少我知道的)都有基本的编程功能,Bash作为大多数linux发行版的默认shell也不例外。本系列以Bash为例(因为它无处不在),使用不同的shell也没关系。虽然结构和语法不同,但编程思想是一样的。有些shell支持某些功能,有些则不支持,但它们都提供编程功能。Shell程序可以存储在一个文件中以供重用,也可以只在需要时创建。简单的CLI程序最简单的命令行程序只是在按下Enter键之前在命令行中输入的一两个语句,它们可能相关也可能不相关。程序中的第二条语句(如果有的话)可能依赖于第一条语句的操作,但不是必须的。这里有一个特殊的标点符号需要说明一下。当你在命令行中输入命令并按下回车键时,实际上在命令的末尾有一个隐含的分号(;)。当CLIshell程序在命令行上作为单行指令串在一起时,必须使用分号来终止每个语句并将其与下一个分开。但是CLIshell中的最后一条语句可以使用显式或隐式分号。一些基本语法下面的例子将说明这个语法规则。该程序由带有明确终止符的单个命令组成:[student@studentvm1~]$echo"Helloworld.";你好世界。看起来不像一个程序,但它是我学习每个新程序时用编程语言编写的第一个程序。不同的语言可能有不同的语法,但输出是一样的。让我们扩展一下这段微不足道但无处不在的代码。您的结果可能与我的不同,因为我的主目录有点乱,您可能是第一次在GUI桌面上登录您的帐户。[student@studentvm1~]$echo“我的主目录。”;ls;Myhomedirectory.chapter25TestFile1.Linuxdmesg2.txt下载newfile.txtsoftlink1testdir6chapter26TestFile1.macdmesg3.txtfile005PicturesTemplateslinkmextestdirTestFiles3Desktopdlic是testdirVideosTestFile1.dosdmesg1.txtDocumentsMusicrandom.txttestdir1现在更明显了。结果是相关的,但两个陈述是相互独立的。您可能已经注意到,我喜欢在分号前后多加一个空格,这样可以使代码更具可读性。让我们再次运行该程序,这次没有尾随分号:[student@studentvm1~]$echo"Myhomedirectory.";ls输出没有区别。关于变量与所有其他编程语言一样,Bash支持变量。变量是一个符号名称,它指向内存中存储相应值的位置。变量的值是可以改变的,所以称为“变量~量”。与C等语言不同,Bash需要强制指定变量类型,例如:整型、浮点型或字符型。在Bash中,所有变量都是字符串。整数变量可用于整数运算,这是Bash唯一可以处理的数学类型。更复杂的计算需要像bc这样的命令,可以在命令行编程或脚本中使用。变量具有预先分配的值,可用于命令行编程或脚本编写。您可以通过名称为变量赋值,但不能在开头使用$符号。例如,VAR=10会将VAR的值设置为10。要打印变量的值,可以使用语句echo$VAR。变量名称必须以文本开头(即不是数字)。Bash保留定义的变量,直到它们被撤销。在下面的示例中,在分配变量之前,它的值为空(null)。然后给它赋值打印出来检查。您可以在CLI程序的同一行中执行此操作:[student@studentvm1~]$echo$MyVar;MyVar="你好世界";echo$MyVar;HelloWorld[student@studentvm1~]$注意:变量赋值的语法非常严格,等号(=)两边不能有空格。该空行表示MyVar的初始值为空。变量以相同的方式分配和重新赋值,此示例显示原始值和新值。如前所述,Bash支持整数运算,这在您想要计算数组中元素的位置或进行简单的算术运算时很有用。但是这种方式不适合科学计算,或者一些需要小数运算的场景,比如金融统计。这些场景有更好的工具。下面是一道简单的算术题:[student@studentvm1~]$Var1="7";Var2="9";echo"Result=$((Var1*Var2))"Result=63貌似没问题,但是如果运算Theresult是浮点数怎么办?[student@studentvm1~]$Var1="7";Var2="9";echo"Result=$((Var1/Var2))"Result=0[student@studentvm1~]$Var1="7";Var2="9";echo"Result=$((Var2/Var1))"Result=1[student@studentvm1~]$结果会四舍五入。请注意,计算包含在echo语句中,但由于Bash的内部优先级,计算是在echo命令结束之前完成的。有关更多信息,请在Bash手册页中搜索“precedence”。控制运算符Shell的控制运算符是语法运算符,可以轻松创建一些有趣的命令行程序。在命令行上按顺序将几个命令串在一起成为最简单的CLI程序:command1;命令2;命令3;命令4;...;ETC。;但是,如果出现问题怎么办?您可以使用Bash的内置控制运算符&&和||来预定义如何处理错误。这两个运算符提供流控制,允许您更改代码执行的顺序。分号也可以看作是Bash运算符,表示新行的开始。&&运算符提供简单的逻辑,如“如果command1成功,则执行command2。如果command1失败,则跳过command2。”语法如下:command1&&command2现在,让我们使用命令创建一个新目录,如果成功,则切换到当前目录。确保你的主目录(~)是当前目录,首先尝试在/root目录下创建它,你应该没有权限:[student@studentvm1~]$Dir=/root/testdir;mkdir$Dir/&&cd$Dirmkdir:cannotcreatedirectory'/root/testdir/':Permissiondenied[student@studentvm1~]$上面的错误信息是mkdir命令抛出的,因为创建目录失败。&&运算符收到非零返回码,因此cd命令被跳过,前者阻止后者继续,因为创建目录失败。此控制流程可防止后续错误累积并导致更严重的问题。是时候处理一些更复杂的逻辑了。当程序的返回码大于零时,使用||运算符允许您继续执行另一个程序。简单语法如下:command1||command2解释,“如果command1失败,执行command2”。隐藏的逻辑是,如果command1成功,则跳过command2。我们来练习一下,还是新建一个目录:[student@studentvm1~]$Dir=/root/testdir;mkdir$目录||echo"$Dir没有创建。"mkdir:cannotcreatedirectory'/root/testdir':Permissiondenied/root/testdirwasnotcreated.[student@studentvm1~]$不出所料,第一条命令失败,因为无法创建目录,所以执行第二条命令.结合&&和||运营商充分利用它们。请参见以下示例中的流量控制方法:pre-commands;命令1&&命令2||命令3;按照命令的语法解释:“如果command1退出的返回码为零,则执行command2,否则执行command3。”具体代码试试:[student@studentvm1~]$Dir=/root/testdir;mkdir$目录&&cd$目录||echo"$Dir没有创建。"mkdir:cannotcreatedirectory'/root/testdir':Permissiondenied/root/testdirwasnotcreated.[student@studentvm1~]$现在再试一次,将/root目录替换为你的主目录,你将有创建权限这个目录:[student@studentvm1~]$Dir=~/testdir;mkdir$目录&&cd$目录||echo"$Dirwasnotcreated."[student@studentvm1testdir]$command1&&command2这样的控制语句之所以起作用,是因为每条命令在执行时都会给shell发送一个返回码,用来表示是否执行成功与否。默认情况下,返回代码0表示成功,任何其他正值表示失败。系统管理员使用的一些工具用返回代码1来指示失败,但许多其他程序使用其他数字来指示失败。Bash的内置变量$?可以显示上一条命令的返回码,在脚本或者命令行中可以很方便的查看。要查看返回码,让我们从运行一个简单的命令开始,返回码的结果总是由前一个命令给出。[student@studentvm1测试目录]$ll;回声“RC=$?”学生92Mar2015:53TestFile1drwxrwxr-x。2名学生学生663552Feb2114:12testdirdrwxr-xr-x。2studentstudent4096Dec2213:15VideosRC=0[student@studentvm1testdir]$在此示例中,返回代码为零表示命令已成功执行。现在测试root的家目录,你应该没有权限:[student@studentvm1testdir]$ll/root;echo"RC=$?"ls:cannotopendirectory'/root':PermissiondeniedRC=2[student@studentvm1testdir]$本例返回码为2,说明非root用户没有权限进入这个目录。您可以利用这些返回代码并使用控制运算符来更改程序执行的顺序。总结本文将Bash视为一种编程语言,并从这个角度介绍了它的简单语法和基本工具。我们学习了如何将数据输出到STDOUT,如何使用变量和控制运算符。在本系列的下一篇文章中,我们将重点关注控制指令执行流程的逻辑运算符。