我是如何开始编写 bash 脚本的

通过几次简单的 Google 搜索,一位编程新手学会了编写代码来自动化以前繁琐且耗时的任务。
522 位读者喜欢这篇文章。
Perl tricks for system administrators

Opensource.com

前几天我写了一个脚本。对于你们中的一些人来说,这句话听起来没什么大不了的。但对于另一些人,我知道你们就在那里,这句话意义重大。你看,我不是程序员。我是一名作家。

我需要解决的问题

我的问题相当简单:我必须将工程文件整理到我们的文档中。这些文件以 .zip 格式从 Web URL 获取。我当时手动将它们复制到我的桌面,然后将它们移动到不同的目录结构以匹配我的文档需求。一位作家同事给了我这个建议:“你为什么不直接编写一个脚本来为你做这件事呢?”

我当时想“就写一个脚本?!?”——就好像这是世界上最容易做的事情一样。

Google 如何提供帮助

我同事的问题让我开始思考,当我在思考时,我使用了 Google 搜索。

Linux 上有哪些脚本语言?

这是我的第一个 Google 搜索条件,你们中的许多人可能在想,“她真够菜的。” 嗯,我当时确实很菜,但这确实让我走上了解决问题的道路。最常见的结果是 Bash。嗯,我见过 Bash。 实际上,我必须记录的文件之一就有 Bash,就是那行无处不在的代码 #!/bin/bash。 我再次查看了该文件,我知道它在做什么,因为我必须记录它。

所以这引导我进行了下一次 Google 搜索请求。

如何从 URL 下载 zip 文件?

那真的是我的基本任务。 我有一个 URL,其中包含一个 .zip 文件,其中包含我需要包含在文档中的所有文件,所以我请求万能的 Google 帮助我。 那次搜索的精华,以及更多,让我找到了 Curl。 但这里是最好的部分:我不但找到了 Curl,而且其中一个热门搜索结果向我展示了一个 Bash 脚本,该脚本使用 Curl 下载 .zip 文件并将其解压缩。 这比我要求的还要多,但那时我意识到,在我的 Google 搜索请求中具体说明可以为我提供编写此脚本所需的信息。 所以,乘着势头,我编写了最简单的脚本

#!/bin/sh

curl http://rather.long.url | tar -xz -C my_directory --strip-components=1

看到它运行的那一刻真是太棒了! 但是后来我意识到一个问题:URL 可能会更改,具体取决于我要访问的文件集。 我还有另一个问题要解决,这导致了我的下一次搜索。

如何将参数传递到 Bash 脚本中?

我需要能够使用不同的 URL 和不同的目标目录来运行此脚本。 Google 向我展示了如何放入 $1$2 等来替换我在命令行中键入的内容。

bash myscript.sh http://rather.long.url my_directory

这样好多了。 一切都按照我需要的运行,我有了灵活性,我有一个可用的脚本,最重要的是,我有一个简短的命令可以输入,从而节省了 30 分钟的复制粘贴苦力活。 这是一个度过美好的早晨。

然后我意识到我还有一个问题。 你看,我的记忆力很差,而且我知道我每隔几个月才会运行一次这个脚本。 这给我留下了两个问题

  • 我怎么记得我的脚本要输入什么(URL 在前?目录在前?)?
  • 如果我被卡车撞了,其他作者怎么知道如何运行我的脚本?

我需要一个用法消息——如果我使用不正确,脚本会显示一些内容。

usage: bash yaml-fetch.sh <'snapshot_url'> <directory>

否则,运行脚本。 我的下一次搜索是

如何在 Bash 脚本中编写 “if/then/else”?

幸运的是,我已经知道 if/then/else 存在于编程中。 我只需要找出如何做到这一点。 在此过程中,我还学会了使用 echo 从 Bash 脚本打印。 我最终得到的是这样的

#!/bin/sh

URL=$1
DIRECTORY=$2

if [ $# -eq 0 ];
 then
 echo "usage: bash yaml-fetch.sh <'snapshot_url'> <directory>".
 else

     # make the directory if it doesn't already exist
 echo 'create directory'

 mkdir $DIRECTORY

 # fetch and untar the yaml files
 echo 'fetch and untar the yaml files'

 curl $URL | tar -xz -C $DIRECTORY --strip-components=1
fi

Google 和脚本编写如何震撼了我的世界

好吧,有点夸张了,但现在是 21 世纪,学习新事物(尤其是有点简单的事情)比过去容易得多。 我学到的东西(除了如何编写一个简短的、自文档化的 Bash 脚本)是,如果我有一个问题,很可能以前有人也有过相同或类似的问题。 当我被难住时,我可以问下一个问题,再问下一个问题。 最后,我不仅有一个脚本,而且我还掌握了一项新技能的开始,我可以掌握并用它来简化我一直避免的其他任务。

不要让第一个脚本(或编程步骤)难倒你。 这是一种技能,就像任何其他技能一样,并且那里有大量信息可以帮助你。 你不需要阅读一本厚厚的书或参加一个月的课程。 你可以用更简单的方式来做,从小步骤和小脚本开始,然后在此技能和你的信心基础上构建。 总是需要人们编写那些成千上万行代码的程序,其中包含所有的分支、合并和错误修复。

但是,也强烈需要简单的脚本和其他自动化/简化任务的方法。 而这正是一个小脚本和一点信心可以给你一个快速开始的地方。

标签
User profile image.
Sandra McCann 是一位 Linux 和开源倡导者。 她曾担任软件开发人员、学习资源的内容架构师和内容创作者。 Sandra 目前是位于马萨诸塞州韦斯特福德的 Red Hat 的内容创作者,专注于 Ansible。 

14 条评论

多么精彩的故事。 我仍然通过 bash 解决日常工作中大量的任务。 它非常适合很多事情,我总是惊讶于 bash 脚本可以实现的功能。 同事们总是取笑我学习一些不同的东西,比如 Python,但是只要我可以用 bash 解决它,我就会继续使用 bash ?。

一个建议... 也许在创建目录之前检查目录是否存在。 这样您就只在目录不存在时才创建它。

干杯 Oliver

您可以使用 mkdir -p 而不是 mkdir 简单地做到这一点。 man 手册中关于 -p 选项的说明是

“如果目录已存在,则不报错,并根据需要创建父目录”

回复 ,作者:Sandra McCann

如果有一个 Bash 101 入门课程,那么这就是新生入学周的“001 你好 Bash 学生!”演示文稿。

这太棒了! 最重要的是,它教授获取信息的方法(实际上,这几乎是我们现在大多数人学习它的方式),而不是仅仅是基本命令。

Slackware 的软件包管理工具都是用 Bash 编写的。 这很好,因为它易于阅读、理解和移植。 我在 RISC Debian 机器上使用过 slackpkg 和相关工具,并且非常喜欢它。

由此,我了解到不要低估或贬低 Bash 作为工具的价值,或 POSIX 与 shell 脚本的集成。 我知道其他操作系统也可以编写脚本,但我还没有见过哪个操作系统像 POSIX 那样尊重用户。

一个很棒的工具,可以验证您编写的内容并提供推荐的修复方案 Shellcheck。 https://www.shellcheck.net/

这似乎确实是一个很棒的工具。 感谢分享。

回复 ,作者:Kenny Jones (未验证)

嘿 Sandra!
这启发了我开始编写 Bash 脚本。 我刚刚编写了一个脚本,以便在最新的构建文件夹创建后立即下载它! 从现在开始关注您的博客!

谢谢大家! 评论区的一些非常有用的补充。

您需要检查命令行参数是否不小于 2。 您当前的用法消息仅在您不提供任何命令时才会显示。

很高兴感到自己有能力。 恭喜。

哦,谢谢 John! 我肯定需要添加该检查!

回复 ,作者:John Keiffer (未验证)

我仍然是一个新手,所以这一切对我来说都是新的... 我将继续努力学习所有我可以使用 Bash 学习的东西。 当然还有 Linux,似乎这两者就像...花生酱和巧克力一样密不可分! 感谢这篇非常内容丰富的文章!!

#!/bin/sh 和 #!/bin/bash 之间存在差异

Creative Commons License本作品根据 Creative Commons Attribution-Share Alike 4.0 International License 获得许可。
© . All rights reserved.