大家好,又见到大家真好!对于我们程序员来说,学习Bash脚本真的很重要。主要是创建脚本,这些脚本用于自动化那些繁琐的重复工作。我们不再需要一遍又一遍地手动运行命令,而是用脚本来简化这些操作。
通过自动执行繁琐的任务来让我们的生活更便捷,这样我们就能专注于开发中更有意思的部分。
在接下来的几分钟内,我们将通过实际示例来探讨 Bash 脚本的基本概念。到最后,你将学会如何让工作更高效,对 Bash 脚本的应用有扎实的理解。
你是不是很激动?
GIF 这是一个GIF图片
有先决条件吗?
如果你是Windows用户,你需要在系统中安装并配置WSL来使用Linux。你可以在这里了解更多有关信息这里(英文原文)。
基础知识概览注意:在本文中,“shell 脚本”和“Bash 脚本”这两个词可以互换使用。Bash 是最常用的 shell,在本讨论中,可以被视为相同。
什么是 Bash 脚本?
可以把它看作一个小型程序,用来自动化你平时需要手动完成的任务。这些脚本是由你在命令行中输入的命令组成的纯文本文件。举个例子,比如你需要将文件夹 A 中的 100 个文件复制到文件夹 B 中,这个任务既无聊又重复,所以你可以写一个 Bash 脚本来批量复制 A 文件夹中的所有文件到 B 文件夹。
我们为什么需要它?它真的那么重要吗?
我们需要 Bash 脚本因为它们能节省我们的时间和精力。把它想象成有个助手吧,能够处理所有无聊且重复的任务,这样你就可以专注于有趣的部分。确实,它真的能帮组织自动化大型任务,让工作变得更轻松。
我们该在哪里写这些脚本?
我们使用文本编辑器编写这些脚本。我们这里会使用自带的VIM编辑器。
这个壳看起来是这样的:
{.tooltip="查看shell图像"}
在这里,我们将介绍常用的 bash 命令。
知道你现在所在的路径是很重要的,特别是当你同时处理多个项目时,这会很混乱。要获取当前目录,我们可以使用命令 pwd
,这个命令的意思是“打印当前工作目录”。
pwd (打印工作目录)
全屏进入,全屏退出
既然我们知道当前目录,让我们创建一个新的文件夹(也就是文件夹)来存放文件。为此,我们用 mkdir
命令,意思是“创建文件夹”。
mkdir <输入你的文件夹名称> # 请在这里输入你的文件夹名称
进入全屏;退出全屏
创建目录之后,你可以用 ls
命令查看里面的内容。
ls(列出目录内容)
全屏模式 全屏退出
或
你也可以用 ls -ltr
命令,这个命令会以长格式(-l)列出内容,按修改时间(-t)顺序排列,并且以最旧条目先显示(-r)。
显示按时间逆序排序的文件列表
ls -ltr
点击进入全屏,点击退出全屏
当你想在文件夹/目录内切换时,你输入命令 cd
,这代表切换目录。使用 cd
你可以进入文件夹,输入 ls
将会显示该文件夹内的所有文件。
cd <文件夹名称>
全屏模式,退出全屏
搬家的照片
为了返回上级目录,你可以使用命令 cd ..
,这会带你离开当前目录。
在命令行中输入 `cd ..` 来返回上一级目录。
全屏,退出全屏
要删除一个文件或整个目录,我们使用命令 rm -r
这个
你可以使用 `rm -r <文件名或文件夹名> (请替换为实际的文件名或文件夹名)`
进入全屏 退出全屏
我们可以使用命令 mv
来重命名文件。
将文件名从 `<你的文件名(例如:example.txt)>` 改为 `<新文件名(例如:new_example.txt)>`
全屏显示,退出全屏
我们现在来创建一个文件,用“touch
”命令即可。
运行 touch <filename>
命令来更新文件的最后修改时间。
点击进入全屏, 点击退出全屏
要打印文件中的内容,可以使用cat
命令。
cat <filename>
在Unix/Linux系统中,此命令用于显示文件内容:cat <filename>。
点击此处进入全屏模式 点击此处退出全屏
文件开始时是空的,因为我们还没有向文件里添加任何内容。让我们给文件添点内容。我们将用vim编辑器来编辑文件(后面文章会详细介绍vim编辑器的使用),保存后,使用cat命令。
文件现在显示了我们写的东西。
最后,如果我们想在终端上显示一些内容,那么就使用命令 echo
。
好的,太好了!我们已经学会了在命令行中基本的移动命令。现在我们可以开始学习一些更有趣的东西了。这并不难,所以别担心哦!
Bash 脚本编程与 VIM 编辑器现在,如果你之前从未写过脚本,你可能对 vim 以及与之相关的所有梗并不熟悉。vim 是一个在终端上编写 bash 脚本的编辑器,还有许多其他编辑器,比如 neovim 和 nano,帮助你编写脚本,而在接下来的教程中我们将使用 vim。
注意:对于 vim 新手来说,可能会觉得有点棘手,这很正常,别担心。
<img class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="https://imgapi.imooc.com/67ad5638096ddfa303640429.jpg" alt="vimimg" title="vimimg 图片">
咱们写我们的第一个bash脚本
`#` 符号用于表示内容是注释,而不是程序的一部分。
# 在 shell 中输入以下命令。
vim bashscriptfile.sh
切换到全屏 退出全屏
哇!你现在在 vim 编辑器里了。
你现在在编辑器里没法输入或插入任何东西,因为默认情况下它不会处于
插入
模式。
按一下i
键就能进入插入
模式,现在你可以像在普通编辑器里那样输入文字了。
你现在应该能看到,编辑器现在处于插入模式。
这是一张关于Vim编辑器的图片。
棘手的部分来了
现在你已经在vim里写完了,接下来需要保存并退出编辑器。按一下esc
键,退出插入模式,然后输入:w
,保存进度。保存后,再输入:q
退出vim。
我们可以使用 :wq!
命令来保存并退出编辑器。
或
也可以用 :x
命令,效果一样。
你可以简单地运行命令 bash
或 sh
(我们之后会讲到这两个命令),加上文件名即可来运行你的示例程序。
你可能已经注意到了,我将文件扩展名改成了 .sh
,在文件名如 bashscriptfile.sh 中使用 .sh
扩展名表示这是一个 shell 脚本,包含一系列由 Unix shell 运行的命令。
现在,让我们写一个更好的 shell 脚本,。在上面的文件中,我们在上面的文件中没有加入 #!/bin/bash
,这是因为这个脚本非常简单,仅仅会打印我们提供的命令,但是实际上我们通常会编写包含大量需要编译或解释代码的复杂的脚本。
在脚本开头的 shebang 行 #!/bin/bash
告诉操作系统应该使用哪个解释程序来执行脚本,在这种情况下,使用位于 /bin/bash 的 Bash 解释程序,确保脚本能正确且一致性地运行,不管用户的默认 shell 是什么。
#!
:这两个字符表示文件是一个脚本,后面的路径指向解释器。
/bin/bash
:这是 Bash shell 解释器的路径,通常位于 Linux 系统中。
现在,咱们来写一个 Shell 脚本以自动化文件和文件夹的创建。运行脚本时,它将创建一个文件夹,并在该文件夹里生成 5 个文件。
vim firstscript.sh
全屏模式 退出全屏
#!/bin/bash
# 这用于输入你想要创建的文件夹或目录的名称。
read -p "请输入目录名: " dir_name
# 如果文件夹/目录已经存在,显示错误
if [ -d "$dir_name" ]; then
echo "错误:目录 '$dir_name' 已经存在。"
exit 1
fi
# 创建目录
mkdir "$dir_name"
# 检查是否创建成功了目录
if ! [ -d "$dir_name" ]; then
echo "错误:创建目录 '$dir_name' 失败。"
exit 1
fi
# 接着,在新创建的目录中创建五个文件。
for i in {1..5}; do
file_name="$dir_name/file_$i.txt"
touch "$file_name"
if ! [ -f "$file_name" ]; then
echo "错误:创建文件 '$file_name' 失败。"
fi
done
echo "目录 '$dir_name' 及其五个文件创建成功。"
exit 0
全屏——退出全屏
写完脚本后保存一下,回到终端,运行下面的命令,看看我们是否真的实现了文件的自动生成。
现在运行这个命令:bash firstscript.sh
全屏模式,全屏退出
然后它会提示你输入一个文件夹名称,我输入了"firstdirectory"。
🎉🎉 哇!你终于写出了你的第一个 Bash 脚本。如果你觉得这个有意思,可以关注我一下,了解更多这样的内容!
文件权限设置当你执行你的 shell 脚本时,当你输入 ./${sample.sh}
命令来运行它时,你会看到权限不足的错误信息,这是因为当前你不具备执行该文件的权限。
在Shell脚本中,文件权限对于权限管理至关重要,特别是在类Unix系统(如Linux和macOS)中。使用chmod
命令来更改这些权限,决定谁可以读取、写入和执行文件。
chmod
命令使用4-2-1规则的数字代码来设置权限,其中每个数字分别对应所有者、组和其他人的权限。
4 代表读取权限。
2 代表写入权限。
1 代表执行权限。
4+2+1 = 7,这表示让所有人都能完全访问文件(不推荐)。
chmod 777 demo.txt
# 将 demo.txt 文件的权限改为 777
全屏模式:进入/退出
或
chmod +x demo.txt
将 demo.txt 文件设置为可执行文件 (Jiǎng demo.txt file shì zhěn wéi kě zhí háng wén jiàn)
全屏。退出。
在上述命令里,你赋予了任何人对该文件的完全访问,可以读、写和执行。
你可以在这里通过这个链接了解更多关于 chmod
命令的内容:here。
以上我们讨论了用于执行我们的shell脚本的命令。在上文,我们提到可以使用sh
和bash
。sh
更注重可移植性,严格遵循POSIX标准,以确保与各种Unix-like系统的兼容性。bash
是一种功能更丰富的shell,在Linux和macOS中更为常见,提供了诸如命令行编辑和存储命令历史的数组功能等便利,但牺牲了部分可移植性。
如需了解sh与bash的区别,请点击图片查看
可以说,bash 是 sh 的升级版,具有更多高级功能。
Shell脚本中的网络连接技巧在 shell 脚本中进行网络操作涉及使用命令行工具来与网络进行交互、传输数据和管理网络配置。它能够自动化处理网络相关任务,例如检查网络连通性、下载文件、配置网络接口设置、连接到远程服务器等。
Shell 脚本能够自动化任务、管理配置和处理文件,对于系统管理员、DevOps 和开发人员来说非常有用。
常用命令
curl
:通过网络协议与服务器传输数据。
下面这条命令会输出 Dev 社区首页的 HTML 代码到终端。
curl https://dev.to
切换到全屏,退出全屏
ping
:检查系统与另一主机之间的连通性。
ping www.google.com
在命令行中输入上述命令来测试与 Google 服务器的连接。
切换到全屏 退出全屏
ssh
:安全连接到远程主机。比如连接像 Ec2 这样的远程服务器时,这个命令非常有用。
在终端输入下面的命令来使用SSH连接到远程服务器:
ssh 用户名@IP地址
全屏模式(进入/退出)
关于条件语句和位置参数它们就是像其他语言一样的 if/else 语句。但它们的结尾有所不同,用 fi
来结尾。
if [[ 条件1 ]];
then
命令1;
elif [[ 条件2 ]];
then
命令2;
else
命令3;
fi
点击全屏播放 点击退出全屏
咱们来写一个超级简单的脚本
vim condition.sh # 打开 condition.sh 文件以检查条件 (Open the condition.sh file to check the conditions)
点击全屏进入全屏模式,点击退出退出全屏
把脚本保存好
位置参数:在 shell 脚本中,位置参数是指用于存储传递给脚本的命令行参数。它们分别称为 $1, $2, $3 等,其中 $1 是第一个参数,$2 是第二个参数,依此类推。$0 通常用于表示脚本文件名。
你可以在 bash 命令后面跟上文件名和参数或选项。
点击这里查看编辑使用的vim图片。
Shell脚本中主要有三种类型的循环:for、while和until。for循环遍历一系列项目或值,while循环在条件为真时持续执行,until循环在条件为假时才执行。
for i in {INITIAL_VALUE..TERMINATING_VALUE}
do
# 这里是代码
done
切换到全屏 退出全屏
vim forloop.sh # 这是用于编辑名为forloop.sh的Shell脚本的Vim命令
全屏进入 全屏退出
查看图片
现在就保存文件
点击图片查看
函数,就是可以命名的代码块,可以在脚本中调用和重用。
function_name() {
# 注释
}
点击这里全屏,点击这里退出全屏
在Vim中打开文件:
vim functions.sh
全屏。退出
此脚本定义了一个名为 follow 的函数,该函数接收一个参数并打印一条消息。
咱们用函数和循环来写一个脚本吧。
在终端中运行 `vim sumScript.sh`
开启全屏 关闭全屏
提示:如果你忘记了如何在 vim 中打字,请记得按
i
进入插入模式,
#!/bin/bash
# 计算从1到n的所有数字的总和。
sum_numbers() {
local n=$1
local sum=0
local i=1
while [[ $i -le $n ]]; do
sum=$((sum + i))
i=$((i + 1))
done
echo "从1到$n的数字总和是: $sum"
}
while true
do
read -p "输入一个正整数,或按q退出:" input
if [[ "$input" == "q" ]]; then
break
fi
# 检查输入是否是数字
if ! [[ "$input" =~ ^[0-9]+$ ]]; then
echo "无效输入"
continue
fi
sum_numbers "$input"
done
echo "脚本已完成。"
全屏模式 退出全屏
先保存一下这个脚本
管道符 | 及 重定向操作 (>>)
管道,用 | 符号表示,是 shell 脚本中的强大功能之一,它允许你将命令串接在一起。管道符号后面的命令依赖于前面的命令。
echo '你好,Bash 管道!' | wc -w
全屏显示 退出全屏
wc -w
命令会统计其输入中的单词数量,结果是3个词,这表明该命令的输出完全取决于输入内容。
grep查找命令
grep
命令是Linux中一个强大的工具,用于在文件中查找文本或模式。当你需要在特定组织中搜索关键词、进程或其他特定信息时,grep
命令就显得特别有用。
使用 grep
命令在文件中搜索关键词,例如:grep "关键词" example.txt
。
grep "keyword" <filename>
切换到全屏模式或退出它
这是我在刚才创建的文件中搜索 demo 单词的方法。
这是一个显示grep1的图片。
现在,我来展示如何使用grep
命令找出系统中正在运行的进程。在行业中,grep
命令非常有用,可以用来在大型日志文件中搜索感兴趣的关键词,就像我们刚才搜索特定进程一样。
运行以下命令来查找与 postgres 相关的进程:
ps -ef | grep "postgres"
全屏查看,退出全屏
sed 命令
sed
命令,也称为“流编辑”,是在类Unix系统中用于文本处理任务的命令行工具。
您可以对文件或输入流中的文本执行搜索、替换、插入和删除文本,无需在文本编辑器中打开文件。
让我们运行一个 bash 脚本来替换文件中的文本内容。让我们创建一个 sedfile.txt
文件,并在里面写入 "This is a bash scripting tutorial",然后是:
vim sedsamplefile.sh
全屏查看;退出全屏
这会打开 vim 编辑器,并切换到插入模式(Insert模式)。
现在我们来运行脚本吧。
注意:我已经用 vim 编辑器写好了 sedfile.txt 的内容。现在就运行脚本。
你可以看到,脚本按预期运行了,而 bash 被 shell 替换掉了。
sed 可用于转换数据格式,整理杂乱数据,自动化 shell 脚本中的重复文本编辑工作,跨多个文件查找替换,等生成代码片段。
awk (一种编程语言和工具)命令
awk
命令是 shell 脚本中的一个强大文本处理工具,用于扫描和处理模式。它可以过滤和操作文本内容,适用于生成报告、执行计算和转换文本。AWK 逐行处理文件内容,将每一行拆分成多个字段。
vim awk_script.sh
切换到全屏/退出全屏
我们来添加一个脚本,只显示登录用户的用户名。
这是一张图片,看看。
存一下文件
你可以清楚地看到它显示了今天登录的用户名。
# $2 表示对应第2列的用户名,类似地,$1 对应日期。
awk '{print "用户:, " $2 " 于 " $1 " 登入"}'
全屏 退出全屏
AWK常用于处理日志、提取数据和转换文本。如下所示,如果我们有一个包含日期、用户名和执行的操作等列的日志文件,我们可以用AWK提取相关信息,比如上面的用户名。
输入输出重定向:重定向允许你更改命令的输入源和输出目的地。命令默认从键盘接收输入并输出到终端,但你可以通过重定向改变输入来源或输出目的地,或文件。
将输出重定向到文件,使用符号 >
之前我们用 vim 编辑器编辑了 sedfile.txt,但这也可以仅通过终端和重定向命令来完成。
>
运算符用于将输出重定向到文件,覆盖任何已存在的内容。
echo "Hello, World!" > sample.txt
这行命令将 "Hello, World!" 输出到 sample.txt 文件中。
切换到全屏模式/退出全屏
这会在 sample.txt 里插入 'Hello, world!'。
向文件追加内容 (追加符号 >>)
>>
运算符将输出追加到已存在的文件中而不是覆盖文件中的内容,而不是重新写入它。
echo "这是一行添加的内容。" >> sample.txt
全屏 退出全屏
这将在“Hello, world!”下面添加下一行。
输入重定向(< 命令符)
<
符号用于从文件而不是从键盘接收输入。
输入命令 cat < output.txt
来查看文件内容
全屏切换 退出全屏
同时重定向输出和错误信息(&> 和 2>&)
将错误信息转到文件里。
ls random_file 2> error_log.txt
列出随机文件的内容并将错误信息输出到error_log.txt文件中:
全屏模式 / 退出全屏
输出为 ls: 无法读取 random_file: 没有此文件或目录
输出和错误信息的重定向(&> 命令)
将程序的正常输出和错误信息一起写入同一个文件。
ls valid_file Invalid_file &> output.txt
运行此命令将列出有效文件并将其输出重定向到output.txt文件中。
进入全屏,退出全屏
预期的结果:
valid_file
ls: 无法访问 Invalid_file: 没有那个文件或目录
点击这里进入全屏模式,点击这里退出全屏模式
之前我们使用了vim编辑器编辑sedfile.txt,但也可以仅通过终端和重定向操作符来完成。
I/O 重定向是 Linux 中一个基本的概念,它允许用户更高效地进行数据管理。
处理错误和调试错误处理始终是创建可靠的 shell 脚本的关键所在。它涉及到在程序执行过程中处理可能出现的意外情况,并确保脚本在遇到问题时能够稳定运行。
基本错误处理方法:
# 此选项会使脚本当命令失败时立即终止。
试试全屏,然后退出
我们来写一个样例脚本吧。
在终端中运行以下命令来编辑名为 sample.sh 的 Shell 脚本:
vim sample.sh
点击此处 > 进入全屏\n点击此处 > 退出全屏
添加一个可以打印文件内容的脚本,但在下面我们将学习set -e
在发生错误时如何发挥作用。
在上面的脚本里,我尝试访问一个不存在的文件,set -e
立即生效,从而中断脚本。
(点击图片查看详细内容)
实际场景:假设任何 AWS CLI 命令(例如 aws ec2 run-instances
、aws ec2 authorize-security-group-ingress
)失败的话,脚本会立即退出。这可以防止脚本在可能出错的状态下继续分配资源的话。
陷阱:在 Bash 中,trap
是一个内置命令,允许你在脚本接收到特定信号时执行特定的命令或动作。
信号:信号是发送给进程的软件信号,用来告诉进程某个事件发生了。
任务调度我相信我们都知道“安排任务的时间”意味着什么。在 shell 脚本中,可以使用如 crontab 这样的工具来安排任务。它是一个允许你在类 Unix 系统中自动在特定时间运行任务的工具。这些任务通常被称为“定时任务”。
实际应用包括管理 EC2 实例的运行、与数据库同步等。
要更深入地了解任务安排和Crontab,可以在这里了解更多:here。
后台任务和前台任务在终端直接运行并阻塞进一步输入直到完成的任务;后台作业则通过在命令后面加上 "& " 来启用,从而释放终端以便进行其他操作。
这些工作对效率至关重要,特别是在软件开发领域,编译代码、运行测试以及部署应用这些步骤可能很耗时。
通过在后台运行长时间的任务,例如模型训练或数据库备份,同时在前台进行其他监控任务,用户可以继续工作,从而提高工作效率并充分利用资源。
是时候通过脚本来理解这个了。
试试运行 vim sample.sh
全屏 退出全屏
复制下面这段代码。
#!/bin/bash
# 正在开始一个前台任务...
echo "正在开始一个前台任务..."
sleep 3 # 等待3秒
echo "前台任务完成了。"
# 后台任务
echo "正在启动一个后台任务..."
sleep 5 & # 将sleep命令放到后台运行
echo "后台任务已启动!"
echo "在后台任务运行期间,正在做其他事情..."
sleep 1
echo "脚本还在运行。"
# 在显示这条消息的同时,另一个进程在运行。
sleep 2
echo "全部完成啦。"
切换到全屏 退出全屏
这个脚本展示了如何使用前台任务和后台任务。
- 你可以看到“启动前台任务...”,然后需要等待3秒钟才能看到其他内容。这表明前台任务会阻塞进一步的输入直到任务完成。
- 你可以几乎立即看到“启动后台任务...”和“后台任务启动!”,即使 sleep 5 命令还没有完成。这是因为 & 将 sleep 5 命令放在了后台。
- 启动后台任务之后,脚本会立即打印“后台任务运行时执行其他任务...”,然后暂停另一个 sleep 1。这表明终端可以自由地做其他事情。
- 最终的“所有完成。”消息即使后台任务(sleep 5)还在运行也会出现。脚本不会等待后台任务完成就退出了。
这是一个动图
-
保持脚本简单:通过确保每个脚本只做一件事情来追求简单。
-
利用版本控制系统:将代码存储在版本控制系统中,以便跟踪修改并与其他团队成员协作。
-
检查工作目录:确保脚本在正确的位置运行。
-
日志记录和故障排除:实施日志记录来记录脚本执行细节和错误。
-
文档和帮助选项: 在脚本中通过注释包含文档,并提供帮助选项(例如使用 -h 或 --help 选项),以帮助用户有效使用脚本。
- 在函数里使用局部变量:定义函数的时候,使用局部变量来限制它们的作用范围,避免意外影响全局变量。
-
基础设施的自动化:AWS 依赖于 shell 脚本来自动化许多基础设施管理任务。比如说,shell 脚本可以自动创建新实例、配置资源并管理更新等等,确保其庞大的基础设施始终保持一致和可靠。
-
常规检查任务:Google 使用 shell 脚本来自动处理常规系统管理任务,例如,用户账户管理、日志文件维护和系统资源监控。这种自动化有助于保持系统的健康和稳定。
-
配置管理:Shell脚本确保所有应用设置正确且一致,避免出现错误。可以设置数据库配置,管理应用与其他服务的交互,以及处理日志。
- 部署应用程序:可以编写 shell 脚本来自动化应用程序的部署,包括打包应用程序、并将其复制到服务器,以及配置它在所需的环境中运行。
是的,终于熬过来了。我们详细了解了 shell 脚本的方方面面,我们看到了它在 DevOps、系统管理、数据处理等关键领域中的作用,无论是在小公司还是大公司,比如 AWS 和 Google。通过自动化日常任务、管理配置、监控系统和部署,shell 脚本仍然不可或缺。
恭喜你🎉🎉,非常感谢你真的看到底了。
如果你喜欢这篇整个教程,不妨分享给真正需要它的人,并关注我,获取更多类似的内容。
如有付费合作需求,请发邮件联系我:harshit77dev@gmail.com
你可以随时通过 Twitter, LinkedIn, Youtube, Github 联系我一下。
再次感谢!祝好!
共同学习,写下你的评论
评论加载中...
作者其他优质文章