- 文档
- 教程
- DevOps
- 运维
【免费下载链接】devops-exercises
Linux, Jenkins, AWS, SRE, Prometheus, Docker, Python, Ansible, Git, Kubernetes, Terraform, OpenStack, SQL, NoSQL, Azure, GCP, DNS, Elastic, Network, Virtualization. DevOps Interview Questions
本篇技术指南以 devops-exercises 仓库中 topics/shell/hello_world.md(及其配套 topics/shell/solutions/hello_world.md)为骨架,系统讲解 Bash 脚本最基础的三大能力:变量定义、变量引用与标准输出重定向。读者完成本篇后,将能够独立编写一个"定义变量并将其输出写入文件"的可运行 Bash 脚本,同时掌握 shebang、echo、>重定向等核心语法,并可通过仓库内系列练习(Basic Date、Great Day、Argument Check 等)继续进阶,为后续 DevOps 面试题(条件判断、循环、函数、调试)打下地基。
练习目标:来自 devops-exercises 的原始任务
该练习位于仓库 topics/shell/hello_world.md,是topics/shell/README.md练习清单中的第一个任务,被标注为Basic(基础)难度、主题为Variables(变量)。原始目标只有两条:
- 定义一个变量,其值为字符串
'Hello World'; - 打印该变量的值,并将输出重定向写入文件
amazing_output.txt。
虽然任务简单,但它同时覆盖了 Bash 脚本中两个高频考点——变量的定义与展开、标准输出(stdout)的重定向,是后续所有 Shell 练习(日期、条件判断、循环、函数)的公共基础。
官方解决方案:一行变量 + 一行输出
仓库中 topics/shell/solutions/hello_world.md 给出的官方实现如下:
#!/usr/bin/env bash HW_STR="Hello World" echo $HW_STR > amazing_output.txt下面逐行拆解这段只有 5 行的脚本,把每行的作用和背后的规则讲透。
第一行:shebang —— 脚本解释器声明
#!/usr/bin/env bash这是 Bash 脚本的 shebang(又称 hash-bang)行,作用是告诉操作系统:当脚本被直接执行(./script.sh)时,应该使用哪个解释器来运行它。此处使用#!/usr/bin/env bash而非写死的#!/bin/bash,其优势是:env会在用户PATH中查找bash,从而提升脚本在不同发行版、不同安装路径下的可移植性。
topics/shell/README.md 的自测问答区也专门考察了这一知识点,要点如下:
/bin/bash是最常见的用户登录默认 shell,bash是Bourne-again shell的缩写;- Bash 能执行绝大多数脚本,功能完善、语法成熟,因此被广泛使用;
- 写 shebang 后,还需要为脚本文件添加可执行权限(例如
chmod +x hello_world.sh)才能直接运行;若不加权限,也可以用bash hello_world.sh显式调用。
第二行:变量定义 —— 等号两侧不能有空格
HW_STR="Hello World"HW_STR是变量名,值"Hello World"用双引号包裹。由于值中包含空格,必须加引号,否则Hello与World会被解析为两个独立的词。- Bash 变量赋值的语法是
变量名=值,等号两侧绝对不能有空格。这一点是经典陷阱:HW_STR = "Hello World"会被当成执行一个名为HW_STR的命令并传入两个参数,而不是赋值。README 自测区的题目"Running the following bash script, we don't get 2 as a result, why?"给出的答案就是应写为x=2而非x = 2。 - 变量名通常约定使用大写字母(如
HW_STR),便于与命令区分;命名只能由字母、数字、下划线组成,且不能以数字开头。 - 除直接赋值外,变量还可以通过命令替换得到值,例如 README 自测题中的
DATE=$(date)—— 将date命令的输出存入变量DATE。这一写法在 topics/shell/solutions/basic_date.md 中也有体现:echo $(date) > the_date.txt。
第三行:echo 打印 + 重定向写入文件
echo $HW_STR > amazing_output.txt这行同时完成了两件事:
echo $HW_STR:展开变量。$HW_STR会替换为变量中的实际值Hello World,echo将其打印到标准输出。注意官方写法未加引号,在实际使用中建议写成echo "$HW_STR",用双引号包裹变量,以保留值内部的空格并避免通配符展开等副作用。> amazing_output.txt:输出重定向。>会将命令的标准输出(stdout)写入文件amazing_output.txt。行为要点如下:- 若文件不存在,则创建它;
- 若文件已存在,则先清空再写入(截断模式);
- 覆盖写场景下如需追加内容,应改用
>>; - 若需把错误信息写入文件,则使用
2>;2>&1可将标准错误与标准输出合并重定向。
运行后,amazing_output.txt中的内容就是一行Hello World,可通过cat amazing_output.txt验证。相比直接echo "Hello World" > amazing_output.txt,本练习刻意要求"先定义变量再输出",目的是让学习者建立"变量是数据容器、echo 是输出通道、重定向决定数据去向"的完整心智模型。
源码佐证:变量与重定向在仓库系列练习中的延伸
Hello World 只是变量主题的起点,devops-exercises 的topics/shell/目录围绕变量、算术、条件、循环、函数、case、杂项组织了一整套渐进式练习(见 topics/shell/README.md 的练习表格)。Hello World 中学到的变量与重定向技能,会在下列练习中反复复用:
- Basic Date(变量):把当前日期写入
the_date.txt。官方解 topics/shell/solutions/basic_date.md 为echo $(date) > the_date.txt,演示了命令替换结果的重定向——与 Hello World 的> file语法完全一致,只是数据来源从静态字符串变成了命令输出。 - Great Day(变量):无参数时打印
Today is a great day!,有参数时打印参数。官方解 topics/shell/solutions/great_day.md 为echo "Today is ${1:-a great day!}",其中${1:-default}是参数默认值展开:$1未提供时回退到a great day!。这与 Hello World 的$HW_STR同属变量展开范畴,但引入了"特殊位置参数"与"默认值兜底"两个新概念。 - Argument Check(条件判断):判断参数是否为字符串
pizza。官方解 topics/shell/solutions/argument_check.md 为[[ ${1} == "pizza" ]] && echo "with pineapple?" || echo "I want pizza!",展示了如何用[[ ]]测试表达式配合&&/||实现 Bash 风格的三元逻辑——README 自测区把这种写法归纳为[[ $a = 1 ]] && b="yes, equal" || b="nope"。
从源码结构看,Hello World 之后的学习路径是先熟练变量(Basic Date、Great Day),再进入算术(Factors)、条件(Argument Check)、循环(Count Chars、Files Size)、函数(Sum)、case(Number of Arguments),形成一条完整的 Shell 能力进阶链。
变量深入:从HW_STR到面试高频考点
结合 topics/shell/README.md 的 "Shell Scripting - Variables" 自测区,把变量知识补全到面试深度:
位置参数与特殊变量
| 写法 | 含义 |
|---|---|
$0 | 脚本自身的名称 |
$1、$2… | 依次传入脚本的第 1、2… 个位置参数,echo $1即可打印第一个参数 |
$# | 传入参数的个数 |
$? | 上一条命令的退出状态码(0 表示成功) |
$$ | 当前进程的 PID |
$@ | 所有参数组成的数组 |
$* | 所有参数组成的单个字符串 |
${1:-default} | 参数 1 为空/未提供时,回退为default |
README 自测区特别区分了$@与$*:$@是参数数组,$*是拼接后的单个字符串;在需要逐个遍历参数时应使用$@。
变量作用域:local 与函数
README 自测区有一个经典作用域题:脚本先定义NINJA_TURTLE=Donatello,函数内用local NINJA_TURTLE=Michelangelo并echo $NINJA_TURTLE,函数调用前又赋值NINJA_TURTLE=Raphael,最终输出是Michelangelo。原因在于:local声明使函数内的同名变量只作用于函数作用域,函数返回后外部变量不受影响。这与 Hello World 中"全局赋值 + 直接展开"的简单模型形成对照,也是 DevOps 面试中高频考察的作用域知识点。
用户输入与字符串操作
- 获取用户输入用
read:read x会等待输入并把内容存入变量x(README 自测区与 topics/shell/solutions/count_chars.md 均有使用)。 - 比较两个变量长度可用
${#1}:if [ ${#1} -ne ${#2} ]; then ...。 - 子串提取:
${var%.*}取出最后一个点之前的部分,${var//*.}取出最后一个点之后的部分(README 子串章节)。
输出重定向深入:数据该流向哪里
Hello World 只用了>一种重定向,把这一语法族完整列出,可覆盖大多数实战场景:
| 语法 | 作用 |
|---|---|
cmd > file | stdout 写入 file(覆盖) |
cmd >> file | stdout 追加到 file |
cmd 2> file | stderr 写入 file |
cmd 2>&1 | stderr 合并进 stdout |
cmd < file | 从 file 读取 stdin |
cmd 2>/dev/null | 丢弃错误输出 |
此外,README 自测区还提到进程替换(process substitution):diff <(ls /tmp) <(ls /var/tmp)可以把命令输出当作文件传给不支持 stdin 的命令(如diff),适合需要同时比较多个命令输出的场景——它属于"重定向的进阶形态",面试常被追问。
调试与最佳实践:从能跑通到写得稳
Hello World 脚本能跑通,但进入生产或面试环节时,README 自测区总结的调试与规范同样值得固化:
- 默认行为:Bash 脚本中某条命令失败时,脚本默认不会退出,而是继续执行后续命令。若希望"失败即停",在脚本开头加入
set -e。 - 调试手段:运行脚本时加
-x(如bash -x script.sh)逐行跟踪展开后的命令;传统做法是在关键位置加echo打印中间值。 - 脚本注释:README 自测区建议在每个脚本中写清"如何运行、做什么事",并视情况使用
set -e。 - 三元/简写:
[[ $a = 1 ]] && b="yes" || b="nope"是 if/else 的紧凑写法,Argument Check 的官方解即采用了该风格。
为什么还要学 Shell:与 CM 工具的定位差异
针对"有 Ansible、Puppet、Chef 为何还学 Shell"这一 DevOps 经典问题,topics/shell/README.md 自测区给出了值得背诵的要点:速度与灵活性;某些场景缺少所需模块(多数 CM 工具也确实提供 shell 模块);以及需要把脚本交付给无外网、未安装 CM 工具的客户环境。这与本仓库定位一致——topics/shell/系列(含solutions/目录下的全部官方解答)正是为面试速成与日常自动化打底的最小闭环。
动手验证:三步跑通并扩展
- 参照官方解创建
hello_world.sh,写入 shebang、变量定义与echo $HW_STR > amazing_output.txt; - 执行
bash hello_world.sh后运行cat amazing_output.txt,看到Hello World即为成功; - 依次挑战 topics/shell/basic_date.md、topics/shell/great_day.md、topics/shell/argument_check.md,对照
solutions/目录下的官方解自查;进阶可继续完成 topics/shell/factors.md(算术与取模)、topics/shell/sum.md(函数与输入校验)、topics/shell/count_chars.md(while 循环与字符计数)。
小结
Hello World 练习虽然只有"定义变量 + 输出重定向"两行核心逻辑,却是整个 topics/shell/README.md 练习体系(变量 → 算术 → 条件 → 循环 → 函数 → case → 杂项)的起点。掌握变量=值(等号无空格)、$VAR展开、> file重定向,再叠加set -e、bash -x等调试习惯,即可从容迈入仓库中更复杂的 Shell 练习与 DevOps 面试题。建议将本篇与solutions/目录中的官方答案对照阅读,逐行追问"为什么这样写",这是该仓库设计的初衷,也是 Shell 能力提升最快的方式。
- 文档
- 教程
- DevOps
- 运维
【免费下载链接】devops-exercises
Linux, Jenkins, AWS, SRE, Prometheus, Docker, Python, Ansible, Git, Kubernetes, Terraform, OpenStack, SQL, NoSQL, Azure, GCP, DNS, Elastic, Network, Virtualization. DevOps Interview Questions
相关推荐
devops-exercises 实战:从 Hello World 出发掌握 Bash 变量定义、echo 输出与重定向
devops exercises 实战:从 Hello World 出发掌握 Bash 变量定义、echo 输出与重定向 本篇技术指南以 devops exer
文档教程DevOps运维learnyounode 入门第一课:用 HELLO WORLD 练习掌握 Node.js stdout 输出与 verify 验证机制
learnyounode 入门第一课:用 HELLO WORLD 练习掌握 Node.js stdout 输出与 verify 验证机制 learnyounod
教程CLIAnsible 入门第一课:编写第一个 Task 创建目录 —— devops-exercises 实战指南
Ansible 入门第一课:编写第一个 Task 创建目录 —— devops exercises 实战指南 本指南以 devops exercises 仓库中
文档教程DevOps运维
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考