Bash脚本是一种高效的自动化任务的方法,特别是那些利用其他现有程序的任务。这种自动化通常需要重复几次类似的操作,这正是for循环进入自己的位置。
Linux和Mac系统管理员通常都熟悉通过终端编写脚本,但即使是Windows用户也可以使用Windows子系统for Linux来进行操作。
bash脚本只是一个纯文本文件,其中包含bashshell可以读取和执行的一系列命令。Bash是catalinamacos之前版本和大多数Linux发行版中的默认shell。
如果您以前从未使用过shell脚本,那么应该从最简单的情况开始。这将允许您练习关键概念,包括脚本的创建和执行。
首先,在方便的位置创建以下文件(理想情况下,首先打开终端并导航到所需的目录):
#!/bin/bashecho "Hello, World"第一行告诉运行这个程序的人如何运行它(即使用bash解释器)。第二个命令与您在命令行中输入的任何其他命令一样。将该文件另存为hello_世界.sh,然后:
$ chmod +x hello_world.sh$ ./hello_world.sh第一行上的chmod命令使文件可执行,这意味着可以通过键入其名称来运行,如第二行所示。
如果您看到“Hello,World”字样出现在终端的一行上,那么一切都按要求工作。
在一般编程中,for循环有两种主要类型:numeric和foreach。传统上,数字类型是最常见的,但是在bash的用法中,通常是相反的。
Numeric for循环通常关注单个整数,该整数决定将执行多少次迭代,例如:
for (i = 0; i < 100; i++) { /* statements to execute repeatedly */}这是一个熟悉的查找循环,它将精确地迭代100次,除非我在循环中被更改,或者另一个语句导致for循环的执行停止。
相反,Foreach循环倾向于对列表或数组等结构进行操作,并对集合中的每个项进行迭代:
people = [ "Peter", "Paul", "Mary" ]foreach (people as person) { if (person == "Paul") { ... }}有些语言使用稍有不同的语法来交换集合和项的顺序:
people = [ "Peter", "Paul", "Mary" ]for (person in people) { if (person == "Paul") { ... }}在bash中,foreach或for In循环更为常见。基本语法是:
for arg in [list]do /* statements to execute repeatedly */ /* the value of arg can be obtained using $arg */done例如,要遍历三个显式命名的文件:
for file in one.c two.c three.cdo ls "$file"done如果当前目录中存在此类文件,则此脚本的输出将为:
one.ctwo.cthree.c可以通过glob模式(包括通配符——表示其他字符的特殊字符)获取列表,而不是固定的一组文件。在下面的示例中,for循环遍历名称以“.xml”结尾的所有文件(在当前目录中):
for file in *.xmldo ls -l "$file"done下面是一些示例输出:
$ -rw-r--r-- 1 bobby staff 2436 3 Nov 2019 feed.xml$ -rw-r--r-- 1 bobby staff 6447 27 Oct 16:24 sitemap.xml这看起来很像一个冗长的方法:
$ ls -l *.xml但是有一个显著的区别:for循环执行ls程序两次,每次只传递一个文件名。在单独的ls示例中,glob模式(*.xml)首先匹配文件名,然后将所有文件名作为单独的命令行参数发送到ls的一个实例。
下面是一个使用wc(单词计数)程序使差异更加明显的示例:
$ wc -l *.xml44 feed.xml231 sitemap.xml275 totalwc程序分别计算每个文件中的行数,然后打印所有行的总计数。相反,如果wc在for循环中运行:
for file in *.xmldo wc -l $filedone您仍将看到每个文件的计数:
44 feed.xml231 sitemap.xml但是没有总的摘要汇总,因为wc是独立运行的,每次循环迭代。
由于bash处理带引号的参数/字符串的方式,在处理for循环时有一个非常简单和常见的错误。循环浏览文件列表的方式如下:
for file in one.c two.c不是这样的:
for file in "one.c two.c"第二个示例将文件名括在双引号中,这将导致只包含一个参数的列表;for循环将只执行一次。在以下情况下,可以通过使用变量来避免此问题:
FILES="one.c two.c"for file in $FILESdo ...done请注意,变量声明本身需要将其值括在双引号中!
由于没有可迭代的内容,for循环在调用时对提供给脚本的任何命令行参数进行操作。例如,如果您有一个名为args.sh文件包含以下内容:
#!/bin/shfor ado echo $adone然后执行args.sh文件将为您提供以下信息:
$ ./args.sh one two threeonetwothreeBash认识到这种情况,并将do视为in$@do中for的等价物,其中,$@是表示命令行参数的特殊变量。
Bash脚本通常处理文件列表或其他命令的输出行,因此for-in类型的循环很常见。但是,仍然支持传统的c型操作:
for (( i=1; i<=5; i++ ))do echo $idone这是一个经典的形式,包括三个部分:
在两个值之间迭代是一个非常常见的要求,因此有一个更短、稍微不那么混乱的替代方案:
for i in {1..5}do echo $idone发生的支架扩展有效地将上述for循环转换为:
for i in 1 2 3 4更复杂的for循环通常需要一种方法,即提前退出主循环或立即使用下一个值重新启动主循环。为此,bash借用了其他编程语言中常见的break和continue语句。下面的示例使用这两种方法查找第一个长度超过100个字符的文件:
#!/bin/bashfor file in *do if [ ! -f "$file" ] then echo "$file is not a file" continue fi num_chars=$(wc -c < "$file") echo $file is "$num_chars characters long" if [ $num_chars -gt 100 ] then echo "Found $file" break fidone这里的for循环操作当前目录中的所有文件。如果该文件不是常规文件(例如,如果它是一个目录),则使用continue语句依次用下一个文件重新启动循环。如果它是一个常规文件,第二个条件块将确定它是否包含超过100个字符。如果是这样,则使用break语句立即离开for循环(并到达脚本的末尾)。
bash脚本是包含一组可以执行的指令的文件。for循环允许脚本的一部分重复多次。通过使用变量、外部命令以及break和continue语句,bash脚本可以应用更复杂的逻辑并执行范围更广的任务。
...表中,您将永远不会缺少选项。有一系列课程可供选择,所有这些课程都可以在舒适的家中进行。 ...
...发人员的需求,命令行下面隐藏着更多的特性。了解更多关于Bash-on-Windows的信息,从您应该如何以及为什么安装它,到您可能不知道的隐藏特性。 ...
... 您可以在“设置”&gt;“系统”&gt;“关于”中进行检查,在那里可以找到“系统类型”条目。要继续,应将其改为“64位操作系统”。如果不是,并且您正在运行64位硬件,则需要将Windows10从32位升级到64位。 ...
...含在2018年Windows 10周年更新中,并在秋季Creators更新中向所有用户推出,它基本上可以让您在Windows 10中运行Linux软件。 ...
... 我们这里也有关于如何利用的文章,这些文章将训练您成为一个更好的Bash脚本编写者。例如,我们可以向您展示如何在Bash中编写for循环,或者将您的脚本转换为可单击的应用程序。 ...
...这些例子是C,java,C++等等。信不信由你,你的计算机把所有东西都看成是1s,或者是众所周知的二进制代码或机器代码。 ...
...与最大的数字相同。 以下命令以100为单位从0到1000计数,所有数字都将用零填充: seq -w 0 100 1000 最长的数字需要四个字符,因此所有较窄的数字都用零填充到该宽度(即使0也填充到四个零)。 管道顺序进入bc 通过将分隔符设...
...该文件系统无法与常规文件系统进行交互。chroot环境中的所有内容都被写入和包含。chroot环境中的任何东西都不能在不升级到root权限的情况下看到它自己的、特殊的根目录。这就为这种环境赢得了一个chroot监狱的绰号。术语“ja...