我是如何开始编写 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 解决问题,我就会继续使用它 ?。

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

祝好,Oliver

你可以用 `mkdir -p` 代替 `mkdir` 来简单地做到这一点。手册页是这样描述 `-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,似乎这两者就像...花生酱和巧克力一样密不可分!谢谢你这篇非常 informative 的文章!!

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

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