我如何使用 Bash 在 Linux 上自动化任务

Bash 具有一些方便的自动化功能,这些功能使我在 Linux 上处理文件时更轻松。
12 位读者喜欢这篇文章。
bash logo on green background

Opensource.com

Bash 命令行是自动化任务的好方法。 无论您是在服务器上运行 Linux 并需要处理日志文件或其他数据,还是您只是希望保持文件整洁的桌面用户,您都可以使用 Bash 中的一些自动化功能来简化您的工作。

Linux for 命令:自动化文件任务

如果您有大量文件需要一次处理,并且您需要对每个文件执行相同的操作,请使用 for 命令。 此命令迭代文件列表,并执行一个或多个命令。 for 命令如下所示

for variable in list
do
    commands
done

我在其中添加了一些额外的空格,以帮助分隔 for 命令的不同部分。 该多行命令可能看起来难以在命令行上运行,但是您可以使用 ; 将所有内容放在一行上,如下所示

for variable in list ; do commands ; done

让我们看看它的实际应用。 我使用 for 命令的一种方式是重命名一堆文件。 最近,我有一堆想要重命名的屏幕截图。 这些屏幕截图的名称类似于 filemgr.pngterminal.png,我想在每个名称前面加上 screenshot。 我运行了一个 for 命令来一次重命名三十个文件。 这是一个仅包含两个文件的示例

$ ls
filemgr.png  terminal.png
$ for f in *.png ; do mv $f screenshot-$f ; done
$ ls
screenshot-filemgr.png  screenshot-terminal.png

for 命令使您可以轻松地对一组文件执行一个或多个操作。 您可以使用对您有意义的变量名,例如 imagescreenshot,或者您可以使用“速记”变量,例如 f,就像我在示例中所做的那样。 当我编写使用 for 循环的脚本时,我尝试使用有意义的变量名。 但是当我在命令行上使用 for 时,我通常会使用一个短变量名,例如 f 代表文件或 d 代表目录。

无论您为变量选择什么名称,都请确保在命令中使用 $ 引用该变量。 这会将变量扩展为您正在操作的文件名。 在 Bash 提示符下键入 help for 以了解有关 for 命令的更多信息。

Linux 条件执行 (if)

当您需要对每个文件执行相同的操作时,使用 for 循环遍历一组文件很有帮助。 但是,如果您需要对某些文件执行不同的操作怎么办? 为此,您需要使用 if 语句进行条件执行。 if 语句如下所示

if test
then
    commands
fi

您还可以通过使用 else 关键字来执行 if/else 测试

if test
then
    commands
else
    commands
fi

对于更复杂的处理,您可以使用 if/else-if/else 评估。 当我需要自动化一个作业以一次处理文件集合时,我可能会在脚本中使用它

if test
then
    commands
elif test2
then
    commands
elif test3
then
    commands
else
    commands
fi

if 命令允许您执行许多不同的测试,例如 if 文件是否真的是文件,或者 if 文件是否为空(零大小)。 在 Bash 提示符下键入 help test 以查看可以在 if 语句中使用的不同类型的测试。

例如,假设我想清理一个包含数十个文件的日志目录。 日志管理中的常见任务是删除所有空日志,并压缩其他日志。 解决此问题的最简单方法是删除空文件。 没有完全匹配的 if 测试,但是我们有 -s 文件来测试 if 某物是否是文件,以及 if 文件是否不为空(它有大小)。 这与我们想要的相反,但是我们可以使用 ! 对测试进行否定,以查看 if 某物不是文件或为空。

让我们看一个例子,看看它是如何工作的。 我创建了两个测试文件:一个是空的,另一个包含一些数据。 如果文件为空,我们可以使用 if 来打印消息“empty”

$ ls
datafile  emptyfile
$ if [ ! -s datafile ] ; then echo "empty" ; fi
$ if [ ! -s emptyfile ] ; then echo "empty" ; fi
empty

我们可以将其与 for 结合使用,以检查日志文件列表,从而为我们删除空文件

$ ls -l
total 20
-rw-rw-r--. 1 jhall jhall 2 Jul  1 01:02 log.1
-rw-rw-r--. 1 jhall jhall 2 Jul  2 01:02 log.2
-rw-rw-r--. 1 jhall jhall 2 Jul  3 01:02 log.3
-rw-rw-r--. 1 jhall jhall 0 Jul  4 01:02 log.4
-rw-rw-r--. 1 jhall jhall 2 Jul  5 01:02 log.5
-rw-rw-r--. 1 jhall jhall 0 Jul  6 01:02 log.6
-rw-rw-r--. 1 jhall jhall 2 Jul  7 01:02 log.7
$ for f in log.* ; do if [ ! -s $f ] ; then rm -v $f ; fi ; done
removed 'log.4'
removed 'log.6'
$ ls -l
total 20
-rw-rw-r--. 1 jhall jhall 2 Jul  1 01:02 log.1
-rw-rw-r--. 1 jhall jhall 2 Jul  2 01:02 log.2
-rw-rw-r--. 1 jhall jhall 2 Jul  3 01:02 log.3
-rw-rw-r--. 1 jhall jhall 2 Jul  5 01:02 log.5
-rw-rw-r--. 1 jhall jhall 2 Jul  7 01:02 log.7

使用 if 命令可以为脚本添加一些智能,以便仅在需要时执行操作。 当我需要测试 if 文件是否存在于我的系统上,或者 if 脚本正在检查的条目是文件还是目录时,我经常在脚本中使用 if。 使用 if 允许我的脚本根据需要采取不同的操作。

标签
photo of Jim Hall
Jim Hall 是一位开源软件倡导者和开发人员,以在 GNOME 中进行可用性测试以及作为 FreeDOS 的创始人兼项目协调员而闻名。

3 条评论

我一直遇到的关于 bash 的这种用法的问题之一是记住复杂的语法。 我通过创建别名命令或制作 shell 脚本来解决这个问题,shell 脚本只是一个包含您显示的命令列表的文本文件。

这很方便,谢谢。 我有一个 bash 脚本,这些命令在其中运行良好。 有点像 Greg 说的那样,如果我不经常使用命令,我会很快忘记它! 我还收藏了这篇文章以供以后参考。 :)

好文章。 感谢。 不知道你可以这样做...

for f in *.ext

...因为我以为你必须这样做.....

for f in $(ls *.ext)

很棒。 👍🏿

© . All rights reserved.