shell脚本基础之详解结构化命令(二)

详解结构化命令

    • for循环
      • 读取列表中的值
      • 读取列表中的复杂值
      • 从变量读取列表
      • 从命令中读取值
      • 更改字段分隔符
        • 注意:
      • 用通配符去读取目录
    • C语言风格的for命令
      • C语言版的for命令
      • 使用多个变量
    • while命令
      • while 的基本格式
      • 使用多个测试命令
    • until命令
    • 嵌套循环
    • 循环处理文件数据
    • 控制循环
      • break命令
        • 跳出单个循环
        • 跳出内部循环
        • 跳出外部循环
      • continue命令
    • 处理循环输出

  • 上篇博客shell脚本基础之详解结构化命令(一),我们学习了如何通过检查命令的退出状态码变量的值来改变shell脚本的执行顺序,在此篇博客我们会继续学习shell脚本的更多结构化命令,学习如何重复一些过程和命令,就是循环,循环执行一组命令直至达到我们预设的某个特定条件,如循环命令for、while、until

for循环

  • 重复执行一系列命令在各种编程中都是很常见的,通常是要重复一组命令直至达到某个特定的条件, 比如我们需要处理某个目录下的所有文件、系统上的所有用户或者某个文本文件的所有行
  • bash shell给我们也提供了for命令,允许我们创建一个遍历一系列值的序列,每次迭代都是使用其中的一个值来执行已定义好的一组命令,for命令格式如下:
for val in list
do
	commands
done
  • list参数就是我们需要提供给迭代的一系列的值,可以通过几种不同的方法指定列表中的值
  • 与常见编程语言语言,我们在每次迭代的时候,变量var会包含列表中的当前值,第一次迭代就是列表中的第一个值,第二次迭代就是第二个值,以此类推,直到将列表中的所有值都过一遍
  • do与done语句之间输入的命令可以是一条或多条标准的bah shell命令,在这些命令中,$var变量包含着每次迭代对应的当前列表中的值
  • 注意:当然,和之前的if语句一样,你也可以将do语句与for语句放在同一行,但必须使用分号(;)将其同列表的值分开,如下:
for val in list; do

读取列表中的值

  • for命令最基本的用法就是遍历列表中一系列的值,如下:
#!/bin/bash
for name in cky cbh xjc njc fl jjh
do
        echo "您的名字是$name"
done

运行结果如下:
shell脚本基础之详解结构化命令(二)_第1张图片

  • for命令每次遍历值列表,它都会将列表中的下个值赋给$name变量。$name变量可以像for命令语句中的其他脚本变量一样使用。在最后一次迭代后,$name变量的值会在shell脚本的剩余部分一直保持有效。它会一直保持最后一次迭代的值(除非我们修改了它),如下:
#!/bin/bash
for name in cky cbh xjc njc fl jjh
do
        echo "您的名字是$name"
done
echo "最后一个名字为$name"
name=wy
echo "修改后的名字为$name"

运行结果如下:
shell脚本基础之详解结构化命令(二)_第2张图片

  • $name变量保持其循环的最后一个值,也允许我们修改它,并可以在for命令循环之外跟其它变量一样使用

读取列表中的复杂值

  • 事实上我们并不会总是使用如此简单的for循环,有时也会碰到难搞的情况,如下:
####  错误示范
#!/bin/bash
for word in I dont't know if this'll work
do
        echo "单词是:$word"
done

运行结果如下:
shell脚本基础之详解结构化命令(二)_第3张图片

  • 出现上述的情况原因是,shell看到了列表值中的单引号并尝试使用它们来定义一个单独的值,才会导致上述的错误,有如下两种解决办法:
    • 使用转义字符(反斜线 \)来将单引号转义
    • 使用双引号来定义用到单引号的值
  • 如下测试:
#### 正确操作
#!/bin/bash
for word in I dont\'t know if "this'll" work
do
        echo "单词是:$word"
done

运行结果:
shell脚本基础之详解结构化命令(二)_第4张图片

  • 我们在第一个有问题的地方添加了反斜线字符来转义don’t中的单引号。在第二个有问题的地方用双引号将this’ll包起来,这两种方法都能正常辨别出这个值
  • 还有就是,我们可能遇到的另一个问题是有多个词的值。记住,for循环假定每个值都是用空格分割的。如果有包含空格的数据值,那么就会变成奇奇怪怪的,如下:
#!/bin/bash
echo "展示城市如下:"
for city in New York New Mexico
do
        echo "城市是:$city"
done

shell脚本基础之详解结构化命令(二)_第5张图片

  • 上述并不是我们想要的展示结果,for命令用空格来划分列表中的每个值。如果在单独的数据值中有空格,就必须用双引号将这些值圈起来,如下:
#!/bin/bash
echo "展示城市如下:"
for city in "New York" "New Mexico"
do
        echo "城市是:$city"
done

shell脚本基础之详解结构化命令(二)_第6张图片

  • 上述的for命令可以正确区分不同值了。注意:在某个值两边使用双引号时,shell并不会将双引号当成值的一部分

从变量读取列表

  • 通常shell脚本遇到的情况是,我们需要将一系列值都集中存储在了一个变量中,然后需要遍历变量中的整个列表。当然可以通过for命令完成,如下:
#!/bin/bash
old_list="wy wwy wwyy wyy"
new_list=$old_list" wwwyyy"
echo $new_list
for name in $new_list
do
        echo "name is $name!!"
done

shell脚本基础之详解结构化命令(二)_第7张图片

  • $old_list变量包含了用于迭代的标准文本值列表。注意,还使用了另一个赋值语句向$old_list变量包含的已有列表中添加(或者说是拼接)了一个值用来创建一个新的变量new_list。这是向变量中存储的已有文本字符串尾部添加文本的一个常用方法

从命令中读取值

  • 我们还可以使用命令的输出作为列表来进行迭代。可以用命令替换来执行任何能产生输出的命令,如下:
#!/bin/bash
file="name_list"


for name in $(cat $file)
do
        echo "name is $name!!"
done

文件名为name_list文件内容为:
shell脚本基础之详解结构化命令(二)_第8张图片
运行结果如下:
shell脚本基础之详解结构化命令(二)_第9张图片

  • 上述例子在命令替换中使用了cat命令来输出文件name_list的内容。你会注意到name_list文件中每一行是一个名字,而不是通过空格分隔的
  • 注意:上述我们使用文件时没有加入路径。这要求文件和脚本位于同一个目录中。如果不是的话,你需要使用全路径名(不管是绝对路径还是相对路径)来引用文件位置
  • for命令仍然以每次一行的方式遍历了cat命令的输出,假定每个名字都是在单独的一行上。但这并没有解决数据中有空格的问题。如果你列出了一个有空格的名字,for命令仍然会将每个单词当作单独的值。这是有原因的,下面我们也会学习到

更改字段分隔符

  • 造成上述问题的原因是特殊的环境变量IFS,叫作内部字段分隔符(internal field separator)。IFS环境变量定义了bash shell用作字段分隔符的一系列字符。默认情况下,bash shell会将下列字符当作字段分隔符:
    • 空格
    • 制表符
    • 换行符
  • 如果bash shell在数据中看到了这些字符中的任意一个,它就会认为这表明了列表中一个新数据字段的开始。在处理可能含有空格的数据(比如文件名)时,会非常麻烦
  • 要解决上述问题,可以在shell脚本中临时更改IFS环境变量的值来限制被bash shell当作字段分隔符的字符。例如,如果你想修改IFS的值,使其只能识别换行符,需要这么做:
IFS=$'\n'
  • 将这个shell语句加入到脚本中,会告诉bash shell在数据值中忽略空格和制表符,如下:
    新的name_list内容,红框中就是以空格分隔的:
    shell脚本基础之详解结构化命令(二)_第10张图片
#!/bin/bash
file="name_list"
IFS=$'\n'

for name in $(cat $file)
do
        echo "name is $name!!"
done

运行结果如下:
shell脚本基础之详解结构化命令(二)_第11张图片

  • 下面还有其他一些IFS环境变量的绝妙用法。假定你要遍历一个文件中用冒号分隔的值(比如在/etc/passwd文件中)。要做的就是将IFS的值设为冒号:
IFS=: 

如果要指定多个IFS字符,只要将它们在赋值行串起来就行:

IFS=$'\n':;" 

这个赋值会将换行符、冒号、分号和双引号作为字段分隔符。如何使用IFS字符解析数据没
有任何限制

注意:

  • 在需要处理代码量较大的脚本时,可能在一个地方需要修改IFS的值,然后忽略这次修改,在脚本的其他地方继续沿用IFS的默认值。一个可参考的方法是在改变IFS之前保存原来的IFS值,之后再恢复它。这种技术可以如下这样实现:
 IFS_OLD=$IFS 
 IFS=$'\n' 
 <在shell代码中使用新的IFS值> 
 IFS=$IFS_OLD 
  • 这就保证了在脚本的后续操作中使用的是IFS的默认值

用通配符去读取目录

  • 甚至还可以用for命令来自动遍历目录中的文件。进行此操作时,必须在文件名或路径名中使用通配符。它会强制shell使用文件扩展匹配。文件扩展匹配是生成匹配指定通配符的文件名或路径名的过程(正则匹配),如果不知道所有的文件名,这个特性在处理目录中的文件时就非常好用,如下:
    当前目录的文件类型:
    shell脚本基础之详解结构化命令(二)_第12张图片
    循环通配符判断:
#!/bin/bash
for file in /root/shell-23-04-10/*
do
        if [ -d "$file" ]
        then
                echo "$file是个目录!!"
        elif [ -f "$file" ]
        then
                echo "$file是个文件!!"
        fi
done

shell脚本基础之详解结构化命令(二)_第13张图片

  • for命令会遍历/root/shell-23-04-10/*输出的结果。该代码用test命令测试了每个条目(使用方括号方法),以查看它是目录(通过-d参数)还是文件(通过-f参数),在之前我们已经详细学习过了
  • 注意,我们在这个例子的if语句中做了一些不同的处理:
if [ -d "$file" ]
if [ -f "$file" ]
  • 在Linux中,目录名和文件名中包含空格当然是合法的。要适应这种情况,应该将$file变量用双引号圈起来。如果不这么做,遇到含有空格的目录名或文件名时就会有错误产生
  • 在test命令中,bash shell会将额外的单词当作参数,进而造成错误
  • 还可以在for命令中列出多个目录通配符,将目录查找和列表合并进同一个for语句,如下:
#!/bin/bash
for file in /root/shell-23-04-10/* /root/shell-23-04-07/*
do
        if [ -d "$file" ]
        then
                echo "$file是个目录!!"
        elif [ -f "$file" ]
        then
                echo "$file是个文件!!"
        fi
done

shell脚本基础之详解结构化命令(二)_第14张图片

  • for语句首先使用了文件扩展匹配来遍历通配符生成的文件列表,然后它会遍历列表中的下一个文件。可以将任意多的通配符放进列表中
  • 注意:我们可以在数据列表中放入任何东西。即使文件或目录不存在,for语句也会尝试处理列表中的内容。在处理文件或目录时,这可能会是个问题。我们无法知道正在尝试遍历的目录是否存在:在处理之前测试一下文件或目录是由必要的!!

C语言风格的for命令

  • 如果你在之前已经接触过C语言编程,可能会对bash shell中for命令的工作方式有点惊奇。在C语言中,for循环通常定义一个变量,然后这个变量会在每次迭代时自动改变。通常程序员会将这个变量用作计数器,并在每次迭代中让计数器增一或减一。bash shell的for命令也提供了这个功能,如下学习:

C语言版的for命令

  • C语言的for命令有一个用来指明变量的特定方法,一个必须保持成立才能继续迭代的条件,以及另一个在每个迭代中改变变量的方法。当指定的条件不成立时,for循环就会停止。条件等式通过标准的数学符号定义,如下:
for (i = 0; i < 10; i++) 
{ 
 printf("The next number is %d\n", i); 
}
  • 上述代码中变量i作为计数器。第一部分将一个默认值赋给该变量。中间的部分定义了循环重复的条件。当定义的条件不成立时,for循环就停止迭代。最后一部分定义了迭代的过程。在每次迭代之后,最后一部分中定义的表达式会被执行。在上例中,i变量会在每次迭代后增一
  • bash shell也支持一种类似于C语言格式的for循环,但有一些细微的不同,bash中C语言风格的for循环的基本格式如下:
for (( a = 1; a < 10; a++ ))
  • 注意:上述部分代码并没有遵守bash shell的标准for命令:
    • 变量复制可以存在空格
    • 条件中的变量不易美元符($) 开头
    • 迭代过程的算式未使用expr命令格式
  • bash shell提供这种格式以更贴切地模仿C语言风格的for命令,无疑是好用的,如下:
#!/bin/bash
for (( i = 1; i <= 6; i++))
do
        echo "number Is $i"
done

shell脚本基础之详解结构化命令(二)_第15张图片

  • for循环通过定义好的变量(本例中是变量i)来迭代执行这些命令。在每次迭代中,$i变量包含了for循环中赋予的值。在每次迭代后,循环的迭代过程会作用在变量上

使用多个变量

  • C语言风格的for命令也允许为迭代使用多个变量。循环会单独处理每个变量,你可以为每个变量定义不同的迭代过程。尽管可以使用多个变量,但你只能在for循环中定义一种条件,如下:
#!/bin/bash
for (( a=1,b=6; a<=6; a++,b-- ))
do
        echo "$a - $b"
done

shell脚本基础之详解结构化命令(二)_第16张图片

  • 变量a和b分别用不同的值来初始化并且定义了不同的迭代过程。循环的每次迭代在增加变量a的同时减小了变量b

while命令

  • while命令某种意义上是if-then语句和for循环的混合体。while命令允许定义一个要测试的命令,然后循环执行一组命令,只要定义的测试命令返回的是退出状态码0。它会在每次迭代的一开始执行test命令。在test命令返回非零退出状态码时,while命令会停止执行那组命令

while 的基本格式

  • while基本格式如下:
while test command 
do 
	other commands 
done
  • while命令中定义的test command和if-then语句中的格式一模一样。可以使用任何普通的bash shell命令,或者用test命令进行条件测试,比如测试变量值
  • while命令的关键在于所指定的test command的退出状态码必须随着循环中运行的命令而改变。如果退出状态码不发生变化, while循环就将一直不停地进行下去
  • 最常见的test command的用法是用方括号来检查循环命令中用到的shell变量的值,如下:
#!/bin/bash
var1=6
while [ $var1 -gt 0 ]
do
        echo "var1的值为$var1"
        var1=$[ $var1 - 1 ]
done

shell脚本基础之详解结构化命令(二)_第17张图片

  • while命令定义了每次迭代时检查的测试条件:
while [ $var1 -gt 0 ] 
  • 只要测试条件成立,while命令就会不停地循环执行定义好的命令。在这些命令中,测试条件中用到的变量必须修改,否则就会陷入无限循环。在上例中,我们用shell算术来将变量值减一,while循环会在测试条件不再成立时停止:
var1=$[ $var1 - 1 ] 

使用多个测试命令

  • while命令还允许你在while语句行定义多个测试命令。只有最后一个测试命令的退出状态码会被用来决定什么时候结束循环,如果使用不当,可能会达不到你想要的效果,如下:
#!/bin/bash
var1=6
while echo $var1
        [ $var1 -ge 0 ]
do
        echo "循环内!!"
        var1=$[ $var1 - 1 ]
done

shell脚本基础之详解结构化命令(二)_第18张图片

  • 第一个测试简单地显示了var1变量的当前值。第二个测试用方括号来判断var1变量的值。在循环内部,echo语句会显示一条简单的消息,说明循环被执行了

  • while循环会在var1变量等于0时执行echo语句,然后将var1变量的值减一。接下来再次执行测试命令,用于下一次迭代。echo测试命令被执行并显示了var变量的值(现在小于0了)。直到shell执行test测试命令,whle循环才会停止

  • 这说明在含有多个命令的while语句中,在每次迭代中所有的测试命令都会被执行,包括测试命令失败的最后一次迭代。要留心这种用法。另一处要留意的是该如何指定多个测试命令。注意,每个测试命令都出现在单独的一行上

until命令

  • until命令和while命令工作的方式完全相反。until命令要求你指定一个通常返回非零退出状态码的测试命令。只有测试命令的退出状态码不为0,bash shell才会执行循环中列出的命令。一旦测试命令返回了退出状态码0,循环就结束了,格式如下:
until test commands 
do
	other commands 
done
  • 和while命令类似,你可以在until命令语句中放入多个测试命令。只有最后一个命令的退出状态码决定了bash shell是否执行已定义的other commands,如下:
#!/bin/bash
var1=100
until [ $var1 -eq 0 ]
do
        echo "var1的值为$var1!!"
        var1=$[ $var1 - 25 ]
done

shell脚本基础之详解结构化命令(二)_第19张图片

  • 上例测试var1变量来决定until循环何时停止。只要该变量的值等于0,until命令就会停止循环。同while命令一样,在until命令中使用多个测试命令时要注意

嵌套循环

  • 循环语句可以在循环内使用任意类型的命令,包括其他循环命令。这种循环叫作嵌套循环(nested loop)。注意,在使用嵌套循环时,在迭代中使用迭代,与命令运行的次数是乘积关系。如下:
#!/bin/bash
for (( a = 1; a <= 3; a++ ))
do
        echo "第一层循环$a"
        for (( b = 1; b <= 3; b++ ))
        do
                echo "  第二层循环$b"
        done
done

shell脚本基础之详解结构化命令(二)_第20张图片

  • 这个被嵌套的循环(也称为内部循环,inner loop)会在外部循环的每次迭代中遍历一次它所有的值。注意,两个循环的do和done命令没有任何差别。bash shell知道当第一个done命令执行时是指内部循环而非外部循环
  • 在混用循环命令时也一样,比如在while循环内部放置一个for循环,如下:
#!/bin/bash
a=3

while [ $a -ge 0 ]
do
        echo "外层循环值为:$a"
        for (( b = 1; $b < 3; b++))
        do
                c=$[ $a * $b ]
                echo "内部循环:$a * $b = $c"
        done
        a=$[ $a - 1 ]
done

shell脚本基础之详解结构化命令(二)_第21张图片

  • 同样,shell能够区分开内部for循环和外部while循环各自的do和done命令
  • 还可以混用比较复杂的until循环与while循环,如下:
#!/bin/bash
var1=3

until [ $var1 -eq 0 ]
do
        echo "外层循环为$var1"
        var2=1
        while [ $var2 -lt 5 ]
        do
                var3=$(echo "scale=4;$var1 / $var2" | bc)
                echo "  内层循环为$var1 / $var2 = $var3"
                var2=$[ $var2 + 1]
        done
        var1=$[ $var1 - 1 ]
done

shell脚本基础之详解结构化命令(二)_第22张图片

  • 外部的until循环以值3开始,并继续执行到值等于0。内部while循环以值1开始并一直执行,只要值小于5。每个循环都必须改变在测试条件中用到的值,否则循环就会无止尽进行下去

循环处理文件数据

  • 通常遍历存储在文件中的数据。可以结合使用已经学过的两种技术:
    • 使用嵌套数据
    • 修改IFS环境变量
  • 通过修改IFS环境变量,就能强制for命令将文件中的每行都当成单独的一个条目来处理,即便数据中有空格也是如此。一旦从文件中提取出了单独的行,可能需要再次利用循环来提取行中的数据
  • 典型的例子是处理/etc/passwd文件中的数据。这要求你逐行遍历/etc/passwd文件,并将IFS变量的值改成冒号,这样就能分隔开每行中的各个数据段,为防止我们在操作过程中的失误,我们将/etc/passwd文件复制部分到当前目录如下:
    在这里插入图片描述
#!/bin/bash
IFS_OLD=$IFS
IFS=$'\n'
for line in $(cat cp-passwd)
do
        echo "行值为$line"
        IFS=:
        for value in $line
        do
                echo "  值为$value"
        done
done

shell脚本基础之详解结构化命令(二)_第23张图片

  • 内部循环会解析出cp-passwd每行中的各个值。这种方法在处理外部导入电子表格所采用的逗号分隔的数据时也很方便

控制循环

  • 你可能会想,一旦启动了循环,就必须苦等到循环完成所有的迭代,并不是这样的。有两个命令能帮我们控制循环内部的情况:
    • break命令
    • continue命令

break命令

  • break命令是退出循环的一个简单方法。可以用break命令来退出任意类型的循环,包括
    while和until循环,可以分为一下几种情况:

跳出单个循环

  • 在shell中执行break命令时,会尝试跳出当前正在执行的循环,如下:
#!/bin/bash
num_list="11 22 33 44 55 66 77 88"
for var in $num_list
do
        if [ $var -eq 66 ]
        then
                break
        fi
        echo "当前的值为$var"
done

shell脚本基础之详解结构化命令(二)_第24张图片

  • for循环通常都会遍历列表中指定的所有值。但当满足if-then的条件时,shell会执行break命令,停止for循环,这种方法同样适用于while和until循环

跳出内部循环

  • 在处理多个循环时,break命令会自动终止你所在的最内层的循环,如下:
#!/bin/bash
for (( a = 1; a < 4; a++  ))
do
        echo "外层循环的值为$a"
        for (( b = 1; b < 1000; b++ ))
        do
                if [ $b -eq 5 ]
                then
                        break
                fi
                echo "  内部循环值为$b"
        done
done

shell脚本基础之详解结构化命令(二)_第25张图片

  • 内部循环里的for语句指明当变量b等于1000时停止迭代。但内部循环的if-then语句指明当变量b的值等于5时执行break命令。注意,即使内部循环通过break命令终止了,外部循环依然继续执行

跳出外部循环

  • 有时你在内部循环,但需要停止外部循环。break命令接受单个命令行参数值:
break n
  • 其中n指定了要跳出的循环层级。默认情况下,n为1,表明跳出的是当前的循环。如果你将
    n设为2,break命令就会停止下一级的外部循环,如下:
#!/bin/bash
for (( a = 1; a < 4; a++ ))
do
        echo "外层循环值为$a"
        for (( b = 1; b < 100; b++ ))
        do
                if [ $b -gt 4 ]
                then
                        break 2
                fi
                echo "  内层循环值为$b"
        done
done

shell脚本基础之详解结构化命令(二)_第26张图片

  • 注意,当shell执行了break命令后,外部循环就停止了

continue命令

  • continue命令可以提前中止某次循环中的命令,但并不会完全终止整个循环。可以在循环内部设置shell不执行命令的条件,如下:
#!/bin/bash
for (( var1 = 1; var1 < 15; var1++))
do
        if [ $var1 -gt 5 ] && [ $var1 -lt 10 ]
        then
                continue
        fi
        echo "当前值为:$var1"
done

shell脚本基础之详解结构化命令(二)_第27张图片

  • 当if-then语句的条件被满足时(值大于5且小于10),shell会执行continue命令,跳过此次循环中剩余的命令,但整个循环还会继续。当if-then的条件不再被满足时,一切又回到正轨
  • 也可以在while和until循环中使用continue命令,但要特别注意,当shell执行continue命令时,它会跳过剩余的命令。如果你在其中某个条件里对测试条件变量进行增值,就会出现如下问题:
#!/bin/bash
# 不恰当举例
var1=0
while echo "外部值为:$var1"
        [ $var1 -lt 15 ]
do
        if [ $var1 -gt 5 ] && [ $var1 -lt 10 ]
        then
                continue
        fi
        echo "  内部值为:$var1"
        var1=$[ $var1 + 1 ]
done

shell脚本基础之详解结构化命令(二)_第28张图片

  • 使用CTRL+C停止shell脚本。在if-then的条件成立之前,所有一切看起来都很正常,然后shell执行了continue命令。当shell执行continue命令时,它跳过了while循环中余下的命令。但是,被跳过的部分正是$var1计数变量增值的地方,而这个变量又被用于while测试命令中。这意味着这个变量的值不会再变化了,从上图连续的输出显示中你也可以看出来
  • 和break命令一样,continue命令也允许通过命令行参数指定要继续执行哪一级循环:
braek n
  • 其中n定义了要继续的循环层级。如下:
#!/bin/bash

for (( a = 1; a <= 5; a++ ))
do
        echo "外部值为:$a"
        for (( b = 1; b < 3; b++ ))
        do
                if [ $a -gt 2 ] && [ $a -lt 4 ]
                then
                        continue
                fi
                var3=$[ $a * $b ]
                echo "  变量var3的值为:$var3"
        done
done

shell脚本基础之详解结构化命令(二)_第29张图片

  • 此处用continue命令来停止处理循环内的命令,但会继续处理外部循环。注意,值为3的那次迭代并没有处理任何内部循环语句,因为尽管continue命令停止了处理过程,但外部循环依然会继续

处理循环输出

  • 最后,在shell脚本中,你可以对循环的输出使用管道或进行重定向。这可以通过在done命令之后添加一个处理命令来实现,如下:
....
....
done > output.txt
  • shell会将for命令的结果重定向到文件output.txt中,而不是显示在屏幕上,如下:
#!/bin/bash
for (( a = 1; a <= 10; a++ ))
do
        echo "变量a的值为:$a"
done > output-a.txt

shell脚本基础之详解结构化命令(二)_第30张图片

  • shell创建了output-a.txt文件并将for命令的输出重定向到这个文件,这种方法同样适用于将循环的结果管接给另一个命令,如下:
#!/bin/bash
for num in 9 5 7 1 6 4 2
do
        echo "排序好的数字为:$num"
done | sort
echo "排序结束!!"

shell脚本基础之详解结构化命令(二)_第31张图片

  • num值并没有在for命令列表中以特定次序列出。for命令的输出传给了sort命令,该命
    令会改变for命令输出结果的顺序。运行这个脚本实际上说明了结果已经在脚本内部排好序了

你可能感兴趣的:(shell脚本,bash,linux,服务器)