DevOps 的 Shell 脚本:快速入门指南 💎

2025-06-08

DevOps 的 Shell 脚本:快速入门指南 💎

我们都有恐惧——水、高处、怪味,等等。我呢?我有一种特殊的恐惧,叫做“UI 变更恐惧症”。每次软件决定更改 UI 时,我的互联网之旅就像遇到了减速带。

以 Twitter 为例。想象一下,“推文”按钮每天都会从右下角跳到左上角。听起来像个游戏,对吧?现在,想象一下这种情况不仅发生在社交媒体上,也发生在像 AWS 仪表盘这样复杂的地方。现在就没那么有趣了,不是吗?

如果你喜欢看,我正在为整个博客精选短视频。如果你不想错过,请务必订阅。

订阅我的 YouTube 频道

回到博客。瞧,对于专家级的 UIUX 研究人员来说,布局就像是互联网的室内设计师。改变布局可以让他们进行分析,从而找到最佳方案。他们最终希望从长远来看让我们感到舒适。但猜猜在此期间谁会感到迷失?没错,就是我们!

就我个人而言,跟上这些变化真的让人精疲力尽。想象一下,每天要检查10台服务器,每次都要按无数个按钮才能找到日志。结果刚找到,却发现产品团队为了测试他们的逻辑图,调整了日志选项。这就像一场糟糕的捉迷藏游戏,如果有人感到有点沮丧,我也不会责怪。

而这正是 Shell 脚本的魔力所在。命令几乎不会改变,即使它们决定改变,也有一个黄金法则——它有详尽的文档,逻辑也保持不变。来看看一致性的超级英雄:你自己的 Shell 脚本🔥

超级壳牌

图片来源:Wallpaper Flare

想象一下:每天早晨,你醒来,端上一杯咖啡,运行一个简单的脚本。输入资源名称,脚本就像时钟一样准时地获取你想要的日志。这就像拥有一个值得信赖的助手,即使你随意按动按钮也不会感到畏缩。

我坚信 DRY(不要重复自己),你也应该如此!既然一个简单的脚本就能完成繁重的工作,何必费力地按下无数个按钮呢?所以,让我们拥抱 Shell 脚本的强大力量吧,在这里,你只需要决定如何舞动。毕竟,在瞬息万变的 UI 领域,脚本的稳定性至关重要。

如果你理解 Shell 脚本的必要性并且有足够的动力去学习,那么你就很棒了🚀✨

贝壳的种类🐚

Shell 是用户和操作系统内核之间的重要接口,支持命令行通信。它充当中介,解释用户命令并将其转换为内核可以执行的指令。

壳牌创始人史蒂夫·伯恩

史蒂夫·伯恩,又名壳牌之父
图片来源:Faces of OpenSource

Shell 大致可以分为5 个主要类别,每个类别都针对特定的任务和偏好而设计。我们将先了解一些 Shell 的知识,然后再学习相关的命令。

1️⃣ Bourne Shell(sh)

史蒂夫·伯恩 (Steve Bourne)于 1979 年开发了首个 UNIX Shell,名为sh。sh以其快速的运行速度而闻名,并因此广受欢迎。然而,作为第一个 Shell,它缺乏一些便捷的功能,例如使用向上箭头调出之前的命令,以及处理逻辑和算术运算。

2️⃣ C Shell(csh)

C shell(简称 csh)由加州大学的 Bill Joy 开发,以其面向编程的功能而著称。它内置了对算术运算的支持,并采用了类似 C 编程语言的语法。

为了弥补早期 Linux shell(例如 Bourne shell)的缺陷,C shell 引入了命令历史记录功能,允许用户高效地追踪和重用之前的命令。C shell 因加入“别名”功能而广受欢迎,它提供了一种灵活且可自定义的方式来定义常用命令的快捷方式。

3️⃣ Korn Shell(ksh)

Korn shell 由 David Korn 精心设计,是对传统shshell 的增强,简称ksh,是 的超集sh。它内置了对算术运算的支持,同时引入了类似于 C shell 的交互功能。

ksh的一个显著特点是其多功能性——它可以无缝执行为sh编写的脚本csh。除了这种兼容性之外,ksh还引入了字符串、数组和函数操作等高级功能,与 C 编程语言的表达能力相媲美。

ksh因其速度而广受好评,在首次发布时就被公认为最快的解释器。这种兼容性和高级功能的结合,使得 Ksh 在 Unix 和 Linux 社区中广受欢迎。

4️⃣ GNU Bourne Again Shell(bash)

GNU Bourne-Again shell 被广泛称为 Bash,其设计初衷是为了与 Bourne shell 兼容。它融合了各种 Linux shell 的功能,例如Korn shellC shell

Bash 的优势在于可以自动调用以前的命令并允许使用箭头键轻松编辑 - 这是对 Bourne shell 的增强,提供了更加用户友好和高效的命令行体验。

5️⃣ Z Shell(zsh)

Zsh是 MacOS 上的默认 Shell,它是一款以开创性功能而闻名的尖端 Shell。它引入了命令补全功能,允许用户使用 Tab 键快速补全命令。此外,它还基于指定条件生成动态文件名,从而提升了文件管理效率。Zsh 的创建者还大力支持插件,为用户提供了灵活的架构来自定义 Shell 环境。这种适应性使 Zsh 成为功能最丰富、用户友好的 Shell 之一。


回顾 Shell 的发展历程,可以深入了解这些关键组件的演变历程。例如,了解从最初的 Bourne Shell 到 Zsh 等 Shell 高级功能的演变历程,有助于理解 Shell 的迭代改进和创新。让我们快速回顾一下 Shell 的发展历程及其相应的演变路径。

小路
/bin/sh
计算机 /bin/csh
/bin/ksh
狂欢 /bin/bash
zsh /bin/zsh

在介绍了目前主流的 Shell 之后,我们现在将重点介绍ZshBash。这两个 Shell 在现代软件开发和自动化生命周期中占据着核心地位,是当代计算领域的关键工具。在深入探讨之前,

Bash 和 Zsh 是解释器

如果您混淆了解释器和编译器。解释器逐行读取并执行代码,并立即提供错误反馈。而编译器则会在执行之前翻译整段代码,创建一个独立的可执行文件,这就像在阅读整本书之前先翻译一遍。让我们先从学习基本命令开始。

UNIX 入门指南

即使你不想自动化或配置繁琐的作业,这些命令也能帮你处理文件和日常的 UI 任务。好吧,如果你从未见过终端,

Aniket ZSH Shell

我目前在 MacOS 上使用 Zsh。让我们重新开始学习命令。为了清晰起见,我不会用冗长的描述,而是用表格的形式呈现。随着我们深入学习,你会对每个命令及其功能有更深入的理解。

命令 描述 例子
ls 列出当前位置的文件和目录。 lsls -l查看详细列表
cd 更改当前目录。 cd Documents
pwd 显示当前工作目录。 pwd
cp 复制文件或目录。 cp file.txt destination/
mv 移动或重命名文件和目录。 mv file.txt newfile.txt
rm 移除/删除文件或目录。 rm file.txt
mkdir 创建新目录。 mkdir new_directory
rmdir 删除一个空目录。 rmdir empty_directory
cat 连接并显示文件的内容。 cat file.txt
grep 在文件中搜索某种模式。 grep pattern file.txt
chmod 更改文件权限。 chmod +x script.sh
ps 显示有关活动进程的信息。 ps aux
kill 发送信号来终止进程。 kill -9 process_id
ssh 安全地连接到远程服务器。 ssh username@remote_host
echo 显示文本或变量。 echo "Hello, World!"

恭喜你掌握了一些命令!不过,冒险还在继续。如果还有点不明白,别担心——直接试试那些命令就行了。现在,我们来聊聊两个容易让人摸不着头脑的命令冠军:chmodgrep

更改模式🎨

作为系统管理员,最重要的任务之一是控制访问权限。假设您创建了一个文件expenses.txt,您不希望每个人都能更改文件的内容,因此您授予了所需组读取权限。但是该怎么做呢?这里就涉及到了chmod

chmod命令是 UNIX 中用于更改文件权限的强大工具。它允许用户通过指定谁可以读取、写入和执行文件来控制对其文件的访问权限。在 UNIX 中,权限分为三类:所有者(u)、(g) 和其他(o),我们可以为每个组应用特定的权限👇

允许 象征 解释
-r 允许读取文件。
-w 允许修改文件。
执行 -x 授予执行能力。

让我们为上述expenses.txt文件编写命令,其中我们将赋予所有者读写权限,并将读取权限分组。



chmod u=rw,g=r expenses.txt


Enter fullscreen mode Exit fullscreen mode

或者



chmod u+rw g+r expenses.txt


Enter fullscreen mode Exit fullscreen mode

运行任何命令后,文件访问权限都会被修改。如需进一步更改,请参考上表,并使用所需的标志和参数运行该命令。

全局正则表达式打印🗂️

最困难的任务之一是从用户界面进行搜索。grep 命令是一个强大的文本搜索实用程序,允许用户在文件中搜索特定的模式或表达式。它在筛选大量文本以查找相关信息时非常方便。其基本语法如下:



grep [options] pattern [files...]


Enter fullscreen mode Exit fullscreen mode
  • 模式:我们要搜索的文本或正则表达式。
  • 文件:我们要在其中搜索的文件。

让我们使用grep命令在费用.txt文件中查找任何以salary结尾的单词。例如,它会搜索developerSalary、managerSalary、intrenSalary等等。



grep "Salary$" expenses.txt


Enter fullscreen mode Exit fullscreen mode

正则表达式符号$表示行尾。因此,“Salary$”表示搜索所有以“Salary”结尾的词。您可以使用正则表达式符号和表达式数组来提高搜索效率。如果您对正则表达式不太了解,希望我解释一下,请在评论区留言。

Shell 中的变量

在 UNIX 中,变量就像信息的容器。它们通过为值赋予有意义的名称、允许数据重用以及帮助处理动态信息(例如用户输入或命令结果)来使脚本更清晰。变量还在脚本的不同部分之间传递信息方面发挥着作用。

在我们开始编写脚本之前,让我们先通过在命令行中编写变量来明确基础知识。



greetings="Hello, World" && echo "$greetings"


Enter fullscreen mode Exit fullscreen mode

在这里,我们将字符串“Hello World”存储在名为greetings的变量中,然后借助echo命令将其打印出来。echo $greetings也可以正常工作,但添加引号"可以防止变量中可能出现的空格对数据造成破坏。因此,请记住始终在变量中添加引号,这是一个好习惯。


如果你使用过任何面向对象编程语言,我相信你一定理解作用域的重要性scope。简单来说,变量的作用域定义了它的有效边界。在 Shell 中,作用域主要分为三类。

1️⃣ 局部作用域:局部变量特定于当前 shell 会话或脚本。它们的作用域有限,对外部命令或脚本不可见。为了更清楚地说明含义,请看以下示例:



EDITOR=vim
crontab -e


Enter fullscreen mode Exit fullscreen mode

在特定的 shell 会话中,每当我们运行 crontab -e 时,它​​都会运行 vim 编辑器。当我们退出 shell 会话时,它将打开默认编辑器。

2️⃣ 环境作用域:环境变量可供当前 Shell 生成的任何子进程访问。它们提供了一种在 Shell 及其子进程之间共享信息的方法。



export EDITOR=vim
crontab -e


Enter fullscreen mode Exit fullscreen mode

当我们执行命令 export 时,它会被视为环境变量。每当我们启动 crontab -e 时,它​​都会打开 Vim 作为编辑器。环境变量用于设置多个会话中有效的值,除非手动删除。例如,每当我们设置 path 时,我们都会使用环境变量

3️⃣ 命令范围:适用于一个命令实例,一旦执行完成,实例就不会持久。



EDITOR=nano crontab -e


Enter fullscreen mode Exit fullscreen mode

在这里,EDITOR 变量仅限于命令。即使我们在当前 shell 会话中运行 crontab,它也会打开默认编辑器。

这三个变量各有其独特之处,且非常重要。我们会根据需要使用它们。但是,你不觉得使用 export 而不是 export 会给变量作用域的定义带来很大困扰吗?嗯,是的,所以我们通常习惯于Declare摆弄变量。

注意:所有预定义变量均采用大写形式

声明🤌

为了避免与 export 用法混淆,请使用 export 而不是 export,并将属性设置为变量declare以简化操作。此命令对于声明具有特定属性的变量特别有用。基本语法如下:



declare [options] variable=value


Enter fullscreen mode Exit fullscreen mode

选项标志允许我们决定变量的属性。默认情况下,变量存储在字符串中。可用的关键选项包括:

选项 描述
-i 将变量声明为整数。
-a 将变量声明为数组。
-r 使变量变为只读。
-x 将变量导出到环境。

让我们使用这些选项来进一步理解



declare -i n=10


Enter fullscreen mode Exit fullscreen mode

i标志将变量 n 定义为整数,并将值存储在 n 中。要使其变为只读,只需添加-ir而不是-i。Declare 命令当然非常灵活,您可以尝试使用各种选项来获得更清晰的理解。



declare -a arr
arr[0]=10
arr[1]=97 


Enter fullscreen mode Exit fullscreen mode

数组是最常用的数据结构,只需使用 声明即可创建。要打印任何索引值,请执行echo ${arr[1]}。如果您想创建关联数组(即基于键值对的数组),请使用-A而不是-a。请记住,关联数组适用于最新版本的 Shell,因此旧版本可能无法获得对它的支持。

变量可以引用为 $n

在编写脚本时,我们用 $n 传递变量的值,其中 n 表示变量的数量。为了进一步说明,我们稍后会进一步讨论这一点。

第一个脚本✨

让我们编写第一个 shell 脚本。



vim myscript


Enter fullscreen mode Exit fullscreen mode

执行上述命令后,我们创建了一个文件myscript.sh,默认情况下.sh会添加扩展名。除非另有说明,否则 Shell 会将所有从终端创建的文件视为脚本文件。vim我们指示打开 vim 编辑器来处理该文件。要在 vim 编辑器中开始编写,请使用 Esc 键 + 'i'。



#!/bin/bash
firstname="$1"
lastname="$2"
echo First Name is "$name" and Surname is "$lastname" 


Enter fullscreen mode Exit fullscreen mode

要运行此脚本,我们只需退出 vim 编辑器即可。如果您暂时没有使用过 Vim,只需按下 Esc 键,然后使用:wq。它将保存脚本的当前状态并退出 vim 编辑器。

#!/bin/bash告诉终端,当我们执行脚本时,应该使用 bash 来执行。如果你想使用,zsh只需使用#!/bin/zsh。Shebang 用于指示我们正在使用哪个脚本。让我们更改文件权限:



chmod +x myscript


Enter fullscreen mode Exit fullscreen mode

正如我们chmod之前讨论过的,我相信你知道这意味着什么。在这里,我们允许执行shell脚本。现在,让我们运行它:



./myscript


Enter fullscreen mode Exit fullscreen mode

好了,第一个 shell 脚本执行完毕🎉我们得到了输出。First Name is <space> and Surname is <space>但是,我们期望的是名字和姓氏,而不是空格,对吧?所以,让我们传递我们的值。



./myscript Aniket Pal


Enter fullscreen mode Exit fullscreen mode

现在我们得到了想要的输出,即……First Name is Aniket and Surname is Pal我们使用 $1,$2 而不是写变量名。我们本来可以使用



./myscript firstname="Aniket" lastname="Pal"


Enter fullscreen mode Exit fullscreen mode

但是,这会导致我们难以记住所使用的变量名。想象一下,当你编写一个登录脚本,并将usernamepassword作为参数传递时,很难记住创建脚本时所写的变量名。因此,在本例中,我们使用 $1、$2 等等。

但还有一个问题。假设你写了很多变量,却不记得确切的结束位置。那么,当你尝试初始化一个新变量时,就需要查找。因此,我们使用了shift关键字。



#!/bin/bash
firstname="$1"
shift
lastname="$1"
echo First Name is "$name" and Surname is "$lastname" 


Enter fullscreen mode Exit fullscreen mode

所以,即使你有数百个变量,你只需要使用 shift ,然后 use $1。这不是很棒吗?嗯,还有比这更酷的事情。

为什么是 1 美元,而不是 0 美元?

当向脚本传递参数时,它们会填充变量。$0 代表脚本本身。例如:



./namescript.sh aniket alice bob


Enter fullscreen mode Exit fullscreen mode
参数 变量数
./namescript.sh 0美元
阿尼凯特 1美元
爱丽丝 2美元
鲍勃 3美元

例如,要获取参数总数,请使用$#;要获取参数列表,请使用$*;要获取数组中的参数,请使用$@。对于上述脚本,请使用:

选项 输出
$# 3
$* “阿妮凯特·爱丽丝·鲍勃”
$@ [“aniket” “alice” “bob”]

关于变量就这些了。现在,我们来深入研究一下条件语句,没错,就是我们常用的 if-else 和 case 语句。

条件语句🤔

就像在任何编程语言中一样,条件语句用于根据条件做出决策。在 Shell 中if-else,我们有语句case。if-else 语句的基本语法如下:



if condition; then #Code to execute if condition is true; else # Code to execute if condition is true; fi


Enter fullscreen mode Exit fullscreen mode

等等,如果你觉得有点困惑,我知道这很容易理解。让我们写一个简单的 shell 命令来创建一个名为“aniket”的目录。如果目录不存在,它会打印一条自定义消息。



if mkdir "aniket"; then echo "created aniket"; else echo "come on use another name"; fi


Enter fullscreen mode Exit fullscreen mode

每当我们完成一行时,我们都会使用;。运行上述命令两次,第一次你会看到“created aniket”,然后使用ls命令检查它是否已创建该目录。再次运行同一命令时,它将显示:



mkdir: aniket: File exists
come on use another name


Enter fullscreen mode Exit fullscreen mode

至此,我们了解了如何使用 if-else。如果想使用else if,只需添加elif并继续即可。但是,如果我们想在条件语句中执行检查,该怎么办?那么:



if [ condition ]; then
    # Code to execute if condition is true
else
    # Code to execute if condition is false
fi


Enter fullscreen mode Exit fullscreen mode

如果你仔细观察,我们会把条件写在第三个括号内,也就是在 里面[...]。在 Shell 脚本中, 或 test 命令用于评估条件表达式。它是 if-else 结构的基本组成部分。记住,我们可以使用(),但最好使用[...]。当我们进一步研究时,你会更加清晰。让我们用一个简单的奇偶检测器来检查一下。



if [ $((number % 2)) -eq 0 ];then echo "even"; else echo "odd"; fi


Enter fullscreen mode Exit fullscreen mode

由于代码长度越来越长,最好使用脚本。太多的分号可能会让代码显得有点杂乱。如果我们想用脚本来写上面的例子,那么脚本应该是这样的:



#!/bin/bash

number=7

if [ $((number % 2)) -eq 0 ]; then
    echo "Even"
else
    echo "Odd"
fi


Enter fullscreen mode Exit fullscreen mode

💡 上面我们学习了如何将变量作为输入。作为你的学习任务,请修改上面的脚本,并尝试将number作为变量,检查其是否正常工作。

双方[[ ]]括号是增强版[ ],相比之下提供了更多功能和改进。它们通常是复杂条件的首选。我们来看一个例子:



#!/bin/bash

age=25

if [[ $age -ge 18 && $age -le 30 ]]; then
    echo "Person is between 18 and 30"
else
    echo "Person is not between 18 and 30"
fi 


Enter fullscreen mode Exit fullscreen mode

记住,以前 UNIX 中只有一个命令,即 test。因此,如果你想要检查而不是使用 [],则需要使用 [ [...] test] 。[[...]] 是一个 Bash 扩展,通常用于执行复杂的计算。例如:



if test "$age"="10"; then ...


Enter fullscreen mode Exit fullscreen mode

现在可以写成,



if ["$age"="10"]; then ....


Enter fullscreen mode Exit fullscreen mode

💡 如果你还和我在一起,那就太好了。相信我,我为你感到骄傲。这算是给你的额外奖励吧。

Shellcheck脚本名称.sh

Shellcheck 是一个用于检测脚本中 bug 和错误的实用程序。它或许能帮你节省数小时的调试时间。

案例🥺

Case 语句比使用多个 elif 语句更高效。其基本语法如下:



case $variable in
    pattern1)
        # Code to execute for pattern1
        ;;
    pattern2)
        # Code to execute for pattern2
        ;;
    pattern3)
        # Code to execute for pattern3
        ;;
    *)
        # Code to execute if none of the patterns match
        ;;
esac


Enter fullscreen mode Exit fullscreen mode

以 开头case,以 结尾esac,提醒一下,每个代码块都以 结尾;;。$variable 是要测试其值的变量,pattern1、pattern2、pattern3 是要匹配的模式。让我们通过水果示例进一步理解 Case 语句:



#!/bin/bash

fruit="apple"

case $fruit in
    "apple")
        echo "It's an apple."
        ;;
    "banana")
        echo "It's a banana."
        ;;
    "orange")
        echo "It's an orange."
        ;;
    *)
        echo "It's something else."
        ;;
esac


Enter fullscreen mode Exit fullscreen mode

*) 是一个通配符模式,用于匹配任何先前模式未匹配的内容。在本例中,脚本检查水果变量的值,并根据匹配的模式执行相应的代码块。如果所有模式均不匹配,则执行 *) 下的代码。case 语句是一个强大的工具,可以在 Shell 脚本中以简洁易读的方式处理多个条件。


循环人生🤩

在 Shell 脚本中,for、while 和 until 循环用于代码的迭代执行。以下是每种循环的概述以及示例:

1️⃣ for 循环
for 循环用于遍历一系列值,例如数字或数组中的元素。



#!/bin/bash

for ((i=0;i<5;i++))
do
  echo $i
done


Enter fullscreen mode Exit fullscreen mode

2️⃣ While 循环
只要指定条件为真,while 循环就会执行一段代码



#!/bin/bash
i=10
while [i -gt 0]
do
  echo $i
  ((i--))
done


Enter fullscreen mode Exit fullscreen mode

3️⃣ 直到循环
do-while 循环或直到循环与 while 循环类似,但它保证在检查条件之前至少执行一次代码块。



#!/bin/bash
i=1
until ((i==0))
do
  echo $i
  i = i-1
done


Enter fullscreen mode Exit fullscreen mode

只是为了好玩,让我们使用 for 循环来看看我们可以用它做什么,这对 shell 来说非常具体。



for i in {1..5};do touch file$i.cpp; done


Enter fullscreen mode Exit fullscreen mode

该特定命令将允许您在当前目录中创建文件,名称为 file1.cpp、file2.cpp、..file5.cpp。

💡现在,尝试删除使用 for 循环创建的文件。提示:将 touch 替换为 rm。

这些循环为 Shell 脚本中的重复性任务提供了灵活性,具体选择哪种循环取决于脚本的具体需求。如果你注意到,for、while 和 until 三个循环都包含关键字 done 和 done。

当我们开始循环时,我们提到 do;当我们完成循环时,我们以 done 结束。我敢肯定,到目前为止,你已经使用过多个循环,如果再逐一解释每个循环,那会很无聊。所以,让我们深入研究一下函数。

功能📚

在 Shell 脚本中,函数用于将一组命令组合成一个单元,以便可以重复使用并以特定名称调用。函数的基本语法如下:



functionName() {
    # Code to be executed
    # ...
    # Optionally, return a value
    return value
}


Enter fullscreen mode Exit fullscreen mode

Shell 中的函数定义与 JavaScript 非常相似,对吧? () 和 {} 定义函数的开始和结束,return 用于从函数返回值。让我们编写第一篇通用函数文章,我们将学习一个 Shell 特有的函数。



#!/bin/bash

addNumbers() {
    sum=$(( $1 + $2 ))
    echo "Sum: $sum"
}

addNumbers 5 7


Enter fullscreen mode Exit fullscreen mode

这里,我们定义了一个名为 的函数addNumbers。由于我们了解到函数参数可以通过 $1,$2 访问,因此我们解析这些参数并将它们相加。最后,我们调用函数 addNumbers ,参数分别为 5 和 7。



unset -f functionName


Enter fullscreen mode Exit fullscreen mode

如果您在终端的本地作用域(而不是脚本)中定义了函数,则用于删除该函数。如果您想直接从终端导出函数而不使用脚本:



declare -xf functionName(){...}


Enter fullscreen mode Exit fullscreen mode

使用 -x 标志定义导出,使用 -f 标志将其定义为函数。我告诉过你 的强大功能declare,还记得吗?如果没有,请稍微滚动一下并修改一下。

最终脚本💎

现在,正如承诺的那样,为了进一步理解,让我们来看一个 Shell 相关的示例。通过编写一个脚本,使用函数和并行执行来检查多个服务器的状态。我们不仅可以学习更多关于函数的知识,还可以复习到目前为止学过的所有知识。



#!/bin/bash

checkServerStatus() {
    local server=$1
    local status=$(curl -sI "$server" | head -n 1 | cut -d' ' -f2)

    if [ "$status" == "200" ]; then
        echo "$server is up."
    else
        echo "$server is down."
    fi
}


servers=("http://twitter.com" "http://google.com" "http://blahblah.in")

checkAllServersInParallel() {
    for server in "${servers[@]}"; do
        checkServerStatus "$server" &
    done
    wait
}


checkAllServersInParallel


Enter fullscreen mode Exit fullscreen mode

上面的函数包含不少概念,对吧?比如数组的使用、for 循环、if-else 语句,以及理解变量的作用域(例如 local)。为了更清晰地理解,我将对上面的脚本进行解释。

checkServerStatus函数接受一个服务器 URL 作为参数,并使用 curl 检查其 HTTP 状态。一个数组servers包含待检查的多个服务器的 URL。该checkAllServersInParallel函数遍历该数组,checkServerStatus在后台调用每个服务器的 URL(&),并等待所有后台作业完成(wait)。如果您之前了解过一些关于 Web 工作原理的知识,我相信您明白我们为什么在这里使用了 wait。然后,该脚本会并行检查多个服务器的状态。

虽然剧本几乎教会了我们所有的概念,也提醒了我们所有的概念,但有一句台词可能会让你感到困惑,对吧?



local status=$(curl -sI "$server" | head -n 1 | cut -d' ' -f2)


Enter fullscreen mode Exit fullscreen mode

这行代码的目的是让你感到困惑,并提醒你还有很长的路要走。这行代码使用三个命令来检查服务器响应的 HTTP 状态码。该curl命令获取指定服务器的标头,head -n 1选择包含 HTTP 状态的第一行,并cut -d ' -f2提取实际的状态码。生成的状态码存储在名为 status 的变量中。这种方法允许脚本根据服务器的 HTTP 状态确定其响应能力。

如前所述,本博客的目的是帮助初学者入门 Shell 脚本。在结束之前,我将补充一些可能对你的Shell 之旅有帮助的概念。

受限 Shell ✋

当目标是实现跨各种类 Unix shell 的代码可移植性时,集成 POSIX 特性至关重要,以确保与 Bash 或 Zsh 以外的旧版 shell 兼容。然而,在组织设置或安全环境中,限制用户权限对于安全性至关重要。系统管理员通过使用受限 shell 来实现这一点。如果您在个人电脑上,并且想要验证您的 shell 是否受限,可以运行以下命令进行检查:



echo $0


Enter fullscreen mode Exit fullscreen mode

此命令将显示当前 shell 的名称。如果是受限 shell,它的名称可能类似于 rsh 或 rbash。检查这些限制有助于在执行任意命令受到限制的情况下维护安全的计算环境。如果您在个人计算机上运行以下命令来检查它是否受限:



shopt restricted_shell


Enter fullscreen mode Exit fullscreen mode

其中,shopt表示Shell选项。默认情况下,限制处于关闭状态,要打开它,请运行



rbash


Enter fullscreen mode Exit fullscreen mode

受限 Shell 选项是只读的,无法使用 shopt 命令更改。限制通常可以阻止更改目录、访问特定文件等。它通常用于大型跨国公司和银行,以允许用户执行所需的操作。

借助shopt,我们甚至可以配置系统选项。比如,当你想更改目录时,只需cd dirName运行以下命令即可,而不是直接输入目录名称:



shopt -s autocd


Enter fullscreen mode Exit fullscreen mode

知道如何恢复总是很重要的,所以如果你想取消特定的配置,请执行以下操作:



shopt -u autocd


Enter fullscreen mode Exit fullscreen mode

有多种选项可供尝试,只需输入 shopt 并尝试一下。

接受输入🧩

在 Shell 脚本中,使用 read 实用程序捕获用户输入,类似于 C++ 中的 std::cin。使用提示符获取输入read正是我们想要的实用程序。



read


Enter fullscreen mode Exit fullscreen mode

如果未指定变量,输入将存储在名为 $REPLY 的默认变量中。如果需要更自定义的方法,可以使用 read 的选项。例如:



read var


Enter fullscreen mode Exit fullscreen mode

将值存储在变量中var。为了保护敏感信息(例如密码)的安全而不显示它们,请使用:



read -s var


Enter fullscreen mode Exit fullscreen mode

此外,您可以使用 -n10 之类的标志限制输入长度,将其限制为 10 个字符。有各种选项可用于根据特定需求定制 read 的行为。尝试使用这些选项可以为您提供在 Shell 脚本中处理用户输入的多种方法。

最后,当提示用户输入特定内容时,可以使用 -p 标志加上提示文本来增强用户体验。例如:



read -p  "Enter Favorite Dish" dish


Enter fullscreen mode Exit fullscreen mode

这不仅可以捕获用户输入,还能提供清晰的提示,从而改善 Shell 脚本的整体交互体验。尝试使用这些功能,您可以创建更加用户友好、交互性更强的脚本。

结尾💚

恭喜🥂,开启你的 Shell 脚本冒险之旅!本篇博文涵盖了丰富的内容,从变量的基础知识到 case 语句、循环、if-else 条件的复杂性,甚至还有完整脚本的编写。现在,你可能已经意识到 Shell 脚本的世界和命令行一样广阔,总有更多东西需要学习。

不妨将这篇博客视为您值得信赖的启动板,助您进入令人着迷的自动化和效率领域。我们只是触及了皮毛,还有无限的可能性等待您去探索。记住,罗马不是一天建成的,Shell 脚本大师也不是一天建成的!

在下一篇文章中,我们将深入探索 cron 任务调度的神秘世界,并深入探讨脚本的艺术。准备好提升你的脚本技能吧!

对于那些想着“嘿,我需要在内容中融入更多智慧和智慧”的人,不妨考虑聘请我作为你们的内容自由撰稿人。让我们一起创造成功!

如果您经营一家组织并希望我编写或创建视频教程,请与我联系🤝

鏂囩珷鏉ユ簮锛�https://dev.to/aniket762/shell-scripting-for-devops-quick-beginners-guide-24hk
PREV
JavaScript 初学者的技巧和窍门 参考 对象 数组 总结
NEXT
十大清洁代码规则🎨🚀