命令行技巧:放下管道符

作者:Kyle Rankin

学习一些避免使用管道符并提高命令行效率的技巧。

任何使用命令行的人都会承认管道符的强大之处。由于管道符,您可以将一个命令的输出作为输入馈送到另一个命令。更重要的是,您可以将一个命令接一个命令地链接起来,直到得到您想要的输出为止。

管道符很强大,但人们也倾向于过度使用它们。虽然这样做不一定是错误的,甚至可能效率也不低,但它确实使您的命令更加复杂。但更重要的是,它还浪费了击键次数!在这里,我重点介绍一些常用管道符但并非必要的示例。

停止在管道中使用 Cat 命令

最常见的管道符过度使用之一是与 cat 命令结合使用。 cat 命令将来自输入的多个文件连接成单个输出,但它已成为管道命令中过度劳累的主力。您经常会发现人们使用 cat 只是为了输出单个文件的内容,以便将其馈送到管道中。这是最常见的例子


cat file | grep "foo"

很多时候,如果人们想知道文件是否包含特定模式,他们会使用 cat 命令将文件通过管道传递到 grep 命令。这可以工作,但是 grep 可以直接将文件名作为参数,因此您可以用以下命令替换上面的命令


grep "foo" file

另一个最常见的 cat 命令的过度使用情况是当您想要对一个或多个文件的输出进行排序时


cat file1 file2 | sort | uniq

grep 一样,sort 支持将多个文件作为参数,因此您可以用以下命令替换上面的命令


sort file1 file2 | uniq

总的来说,每次您发现自己将文件通过管道传递到管道时,请重新检查管道命令,看看它是否可以首先直接接受文件作为输入,无论是作为直接参数还是作为 STDIN 重定向。例如,正如您之前看到的,sortgrep 都可以接受文件作为参数,但如果它们不能,您可以使用重定向来实现相同的目的


sort < file1 file2 | uniq
grep "foo" < file

无需 xargs 即可删除文件

xargs 命令在命令行中非常强大,特别是当从 find 命令通过管道传递到它时。通常,您会使用 find 命令来挑选出符合特定条件的文件。一旦您确定了这些文件,您自然希望将该输出通过管道传递到某个命令来对它们进行操作。您最终会发现,命令通常对其可以接受的参数数量有上限。

例如,如果您想执行有点危险的操作,即查找并删除目录下与特定模式匹配的所有文件(例如,所有 mp3 文件),您可能会想这样做


find ./ -name "*.mp3" -type f -print0 | rm -f

当然,您永远不应该直接将 find 命令通过管道传递给 remove。首先,您始终应该通过管道传递给 echo 以确保您要删除的文件是您想要删除的文件


find ./ -name "*.mp3" -type f -print0 | echo

如果您有很多文件与该模式匹配,您可能会收到有关命令行上参数数量的错误,这就是 xargs 通常派上用场的地方


find ./ -name "*.mp3" -type f -print0 | xargs echo
find ./ -name "*.mp3" -type f -print0 | xargs rm -f

这更好,但如果您想删除文件,您根本不需要使用管道。相反,首先只需使用不带管道命令的 find 命令来查看将删除哪些文件


find ./ -name '*.mp3" -type f

然后利用 find-delete 参数来删除它们,而无需通过管道传递到另一个命令


find ./ -name '*.mp3" -type f -delete

因此,下次您发现您的小指伸向管道键时,请暂停一下,想想您是否可以将两个命令合并为一个命令。您的效率和可怜的过度劳累的小指(谁认为让小指在键盘上承担最重的工作量是有道理的?)会感谢您的。

Kyle Rankin 是Linux Journal 的技术编辑和专栏作家,也是 Purism 的首席安全官。他是Linux Hardening in Hostile NetworksDevOps TroubleshootingThe Official Ubuntu Server BookKnoppix HacksKnoppix Pocket ReferenceLinux Multimedia HacksUbuntu Hacks 的作者,也是许多其他 O'Reilly 书籍的贡献者。Rankin 经常就安全和开源软件发表演讲,包括在 BsidesLV、O'Reilly Security Conference、OSCON、SCALE、CactusCon、Linux World Expo 和 Penguicon 上。您可以在 @kylerankin 上关注他。

加载 Disqus 评论