一,for循环

概述

for 循环用于遍历列表或范围中的每个元素。它在 Shell 脚本中非常常见,可用于逐一处理列表或基于范围执行循环体。

列表循环

用于遍历给定的列表中的每一个元素。

for 变量 in 列表
do
    命令
done
或者
for 变量 in {列表}
do
    命令
done
#比如
for name in 李叶 王大炮 小丽
do
    echo "Hello, $name!"
done

在 Shell 脚本中,{} 可以用于定义一个范围或生成一组序列,主要用于 for 循环和其他命令中批量生成或处理内容。以下是常见的用法

用法示例说明输出结果
数字范围 {起始..结束}{1..5}生成指定起始到结束的数字范围1 2 3 4 5
字母范围 {A..Z}{a..z}{A..C}生成指定范围内的连续字母A B C
设置步长 {起始..结束..步长}{1..10..2}指定范围和步长来生成序列1 3 5 7 9
简单排列组合 {A,B}{1,2}{A,B}{1,2}生成两个集合的组合,每个集合用逗号分隔A1 A2 B1 B2
多组排列组合{A,B,C}{1,2,3}多组组合,生成各集合中的每个元素组合A1 A2 A3 B1 B2 B3 C1 C2 C3
添加分隔符 {A,B}_{1,2}{A,B}_{1,2}添加分隔符如 _ 或其他字符,可用作带前缀的文件或目录名A_1 A_2 B_1 B_2
复杂多级排列组合{red,blue}_{A,B}_{1,2}多级组合,生成所有指定属性的排列组合red_A_1 red_A_2 red_B_1 red_B_2
文件批量生成touch file_{A,B,C}_{1,2}批量生成文件,可结合前缀、后缀创建多个文件或目录file_A_1 file_A_2 file_B_1
命令输出中的 {} 使用echo file{1..3}.txt用于生成带特定范围和格式的文件名或字符串,可批量操作文件名file1.txt file2.txt file3.txt
{} 嵌套使用echo {A,B}_{1..2}_{X,Y}多层次嵌套生成排列组合,适合生成复杂的命名方案或批量文件操作A_1_X A_1_Y A_2_X A_2_Y B_1_X B_1_Y

非列表循环

在这种情况下,for 循环不依赖于固定的列表,而是可以基于命令输出。

for file in $(ls *.txt)
do
    echo "Processing $file"
done

类c循环

for 循环可以像 C 语言一样设置起始值、结束条件和增量。

for (( 初始值; 条件; 增量 ))
do
    命令
done
#比如
for (( i=1; i<=5; i++ ))
do
    echo "Iteration $i"
done

二,while循环

while 循环在条件为真时执行循环体,直到条件为假时退出。

语法结构

[结束条件]
while 条件
do
    命令
done
#比如
count=1
while [ $count -le 5 ]
do
    echo "Count is $count"
    ((count++))
done

三,untill循环

until 循环在条件为假时执行循环体,直到条件为真时退出。

语法结构

[结束条件]
until 条件
do
    命令
done
#比如
count=1
until [ $count -gt 5 ]
do
    echo "Count is $count"
    ((count++))
done
特殊用法

while read 语句是一种常见且有效的方法,用于从文件或输入中逐行读取数据,并对每行内容进行操作。

while 【IFS=','】 read 变量1 变量2 ...
do
    # 循环体中的命令,通常会使用到上面定义的变量
done < 输入文件
主要组成部分
while read 变量1 变量2 ...:

while 循环的条件部分,由 read 命令逐行读取输入。
每一行会根据分隔符(默认为空格或制表符)被拆分并依次赋值给变量 变量1、变量2 等。
如果行中字段数超过变量数量,最后一个变量会包含剩余所有字段;如果字段数少于变量数量,未匹配的变量则为空。

循环体 do ... done:

do 和 done 之间是循环体,在每次读取一行后执行。
在循环体中,可以使用 变量1、变量2 等对读取的数据进行处理,例如输出、计算或格式化。

< 输入文件:

while 循环的输入重定向,指定待读取的文件。
此处 输入文件 会作为 while 循环的输入来源,通常是一个包含多行内容的文本文件。
如果不指定文件,可以从标准输入(如命令输出管道)中读取数据。

IFS=','

默认情况下,read 使用空格或制表符分隔字段。可以使用 IFS(内部字段分隔符)变量来改变分隔符

四,循环控制

在do……done之间,使用continue,break可以控制跳出循环

exit可以跳出程序

continue:跳出本次循环

break:跳出整个循环

五,随机数

概述

Shell 提供了一个内置的 $RANDOM 变量,可以生成 0 到 32767 之间的随机整数。可以通过对 $RANDOM 进行取模运算来生成特定范围的随机数。

语法结构

echo $((RANDOM % 取余x + 1))
范围【1   ---    x,不加1就是0  ---  x-1】
生成特定范围的随机数,例如 1 到 100:
echo $((RANDOM % 100 + 1))

六,扩展(程序并行,关注红色就行)

使用 & 实现后台执行

在 Shell 中,在命令后加上 &,可以将该命令放入后台执行,使脚本可以继续运行而不等待该命令完成。

command1 &
command2 &
command3 &
wait  # 等待所有后台任务完成
  • command1 &command2 &command3 & 会同时启动并在后台运行。
  • wait 命令用于等待所有后台任务完成后再继续执行脚本后续内容。

使用 &wait 控制并行任务数量

可以通过计数器和 wait 控制并发的最大任务数量。例如,在批量下载文件或处理数据时,这种方式能有效控制并发数,避免资源过载。

max_jobs=3   # 最大并行任务数
count=0

for url in url1 url2 url3 url4 url5
do
    curl -O "$url" &  # 并行下载
    ((count++))

    if ((count >= max_jobs)); then
        wait         # 等待前 max_jobs 个任务完成
        count=0
    fi
done

wait  # 等待最后一批任务完成
  • 通过计数器 count 监控当前并行任务数,达到 max_jobs 后调用 wait 等待当前任务完成再继续。
  • 这样可以控制最大并行任务数量,减少系统资源占用。

xargs 配合 -P 参数并行执行

xargs 是一个强大的工具,可以将输入分配给指定的命令执行。通过 -P 参数,可以指定并行执行的最大进程数。

echo -e "task1\ntask2\ntask3" | xargs -P 3 -I {} bash -c "{}"
  • -P 3 指定最多同时运行 3 个并行任务。
  • -I {}{} 替换输入中的每一项,并执行 bash -c "{}",在每个任务中调用 Bash 执行具体命令。

使用子 Shell 并行执行任务

 通过将命令放入 () 中,可以创建子 Shell。每个子 Shell 可以独立执行,而主脚本继续运行或等待子 Shell 完成。

(command1) &
(command2) &
(command3) &
wait  # 等待所有子 Shell 任务完成
  • 每个 () 中的命令都作为一个独立的子 Shell 执行,并在后台运行。
  • wait 命令会等待所有子 Shell 完成后再继续。

parallel 命令进行并行处理

parallel 是一个非常高效的并行执行工具,可以将多条命令或输入并行处理。它在处理大规模任务时性能优异,但需要安装 GNU parallel(通常通过包管理器安装)。

parallel echo "Processing {}" ::: task1 task2 task3
  • parallelecho "Processing {}" 并行执行多次,每次用 task1task2task3 依次替换 {}
  • ::: 后列出所有任务,这些任务会被分配到并行的命令执行。

使用 backgroundtrap 捕获并处理信号

在一些复杂的并行任务中,可以使用 trap 捕获中断信号,确保在任务被终止时安全退出或清理资源。

trap 'kill $(jobs -p); exit' SIGINT SIGTERM  # 捕获中断信号并终止所有子进程

for task in task1 task2 task3 task4
do
    (
        # 假设每个任务为一个函数调用
        my_task_function "$task"
    ) &
done

wait  # 等待所有任务完成
  • trap 'kill $(jobs -p); exit' SIGINT SIGTERM 用于捕获 SIGINTSIGTERM 信号,一旦捕获会终止所有后台任务(子进程),并退出脚本。
  • wait 命令用于等待所有任务完成。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部