LabHub
学习 学习路径 课程

Shell 脚本

循环与函数

在 LabHub 中继续学习

目标

以实际可用的形式掌握循环与函数。尤其要确保脚本在‘没有匹配文件’、‘参数中包含空格’、‘完全没有参数’等边界情况下也不会出错。

为什么重要

shell 函数不返回值。计算结果通过标准输出传出,成功或失败则通过退出码表示。只有遵守这一约定,才能自然地写出 if is_number "$x" 这样的用法。处理文件列表时也不要解析 ls,而应交给 shell 的 glob——$(ls *.log) 遇到包含空格的文件名时会出错,没有匹配项时还会把错误消息送入循环。改用 glob 后,又会出现没有匹配项时模式字符串原样保留的另一种陷阱,因此需要 [ -f "$f" ] || continue 这道防线。

步骤

  1. 创建 /root/bin/loop1.sh,逐行输出从 15
  2. 创建 /root/loops/logs 目录,在其中放置 4 个 .log 文件和 2 个 .txt 文件。再创建 /root/bin/count.sh <디렉터리>,只输出该目录直属的 .log 文件数量。传入空目录时必须输出 0。
  3. /root/loops/users.csv 中按 이름,역할 格式写入至少 3 行,再创建 /root/bin/readcsv.sh,读取该文件并按 이름(역할) 格式逐行输出(不带参数运行)。
  4. /root/bin/lib.sh 中定义 slugify 函数,把单词转成小写并用连字符连接。/root/bin/use.sh 必须通过 source 加载该文件后使用函数。use.sh Hello World -> hello-world
  5. 创建 /root/bin/isnum.sh <문자열>。字符串只由数字组成时返回退出码 0,否则返回非 0。**不能输出任何内容。**空字符串、正负号和小数点都不算数字。
  6. 创建 /root/bin/each.sh,将收到的每个参数按 [인자] 格式逐行输出。each.sh "a b" c 必须输出两行。没有参数时不输出任何内容。
  7. 创建 /root/bin/sum.sh,输出所有数字参数的总和。没有参数时输出 0
  8. 创建 /root/bin/summary.sh <디렉터리>,用以下两行输出该目录中的 .log 文件数量和总行数。
    • files=<개수>
    • total_lines=<합계>

提示

输出 1 到 5

创建 /root/bin/loop1.sh,逐行输出从 15

可以使用 for x in 1 2 3 4 5,也可以使用花括号展开 {1..5}。

使用 glob 统计文件

创建 /root/loops/logs 目录,在其中放置 4 个 .log 文件和 2 个 .txt 文件。再创建 /root/bin/count.sh <디렉터리>,只输出该目录直属的 .log 文件数量。传入空目录时必须输出 0。

没有匹配文件时,模式字符串会原样保留。请用 [ -f "$f" ] || continue 将其过滤掉。

逐行读取 CSV

/root/loops/users.csv 中按 이름,역할 格式写入至少 3 行,再创建 /root/bin/readcsv.sh,读取该文件并按 이름(역할) 格式逐行输出(不带参数运行)。

使用 while IFS=, read -r a b 这种形式,并在 done 后通过重定向提供输入。

把函数拆分到库中

/root/bin/lib.sh 中定义 slugify 函数,把单词转成小写并用连字符连接。/root/bin/use.sh 必须通过 source 加载该文件后使用函数。use.sh Hello World -> hello-world

在 lib.sh 中定义函数,再从 use.sh 使用 . 或 source 加载。不能复制粘贴函数。

通过退出码进行判断

创建 /root/bin/isnum.sh <문자열>。字符串只由数字组成时返回退出码 0,否则返回非 0。**不能输出任何内容。**空字符串、正负号和小数点都不算数字。

如果输出判断结果,就无法直接用于 if 语句。只通过 return 0 / return 1 表示结果。

安全遍历含空格的参数

创建 /root/bin/each.sh,将收到的每个参数按 [인자] 格式逐行输出。each.sh "a b" c 必须输出两行。没有参数时不输出任何内容。

比较 for x in "$@" 与 for x in $* 的差异。没有参数时必须什么也不做。

对可变参数求和

创建 /root/bin/sum.sh,输出所有数字参数的总和。没有参数时输出 0

不要忘记把累加变量初始化为 0。没有参数时必须输出 0。

目录摘要报告

创建 /root/bin/summary.sh <디렉터리>,用以下两行输出该目录中的 .log 文件数量和总行数。

同时统计文件数和总行数。即使目录为空,也必须输出 0/0。