如何在 Linux 上使用 yes 命令

yes 命令看似简单,似乎没有实际用途,但在本文中,我们将揭示其在 Linux 和 macOS 系统中的应用,以及如何利用它隐藏的强大功能。

yes 命令简介

yes 命令是类 Unix 操作系统(如 Linux 和 macOS)中最基础的命令之一。这里的 “基础” 指的是它使用的简便性和最初的实现方式。 最初版本在 System 7 Unix 中发布,由 Ken Thompson 编写,源代码仅包含 区区几行代码

但是,不要因为它简单而小看它。 yes 命令可以通过多种有趣且实用的方式来使用。

yes 命令的功能

当不带任何命令行参数运行时,yes 命令会重复输出字符 “y”,然后自动换行,就像您不断按下键盘上的 “y” 键和回车键一样。 它会一直重复此操作,直到您使用 Ctrl+C 中断它。

yes

实际上,yes 命令可以重复生成您指定的任何文本。 您只需键入 yes、一个空格,然后输入您希望重复的字符串,最后按 Enter 键。 通常,这被用来生成 “yes” 或 “no” 字符串的输出流。

yes yes

yes 你喜欢什么都行

yes 命令的实际应用

yes 命令的输出可以通过管道传递给其他程序或脚本。

您是否遇到过这种情况:您启动了一个耗时较长的进程,然后就离开了。 当您返回时,发现该进程并未完成,因为它在您离开时提示您输入 “yes” 或 “no” 的回答。

如果您事先知道所有问题的答案都是肯定的(”yes” 或 “y”)或否定的(”no” 或 “n”),您可以使用 yes 命令自动提供这些答案。 这样,您的耗时进程就可以在无人值守的情况下运行到完成,yes 命令将自动回答进程中出现的所有问题。

在脚本中使用 yes 命令

请看下面这个 Bash shell 脚本的示例。(假设这是一个大型脚本的一部分,需要较长时间才能运行。)

#!/bin/bash

# ...
# 在一个漫长的脚本中
# 从用户那里获取一个响应
# ...

echo "您是否愿意继续? [y,n]"
read input

# 是否获得了输入值?
if [ "$input" == "" ]; then

   echo "用户没有输入任何内容"

# 输入的是 y 还是 yes?
elif [[ "$input" == "y" ]] || [[ "$input" == "yes" ]]; then

   echo "肯定响应:$input"

# 将其他任何输入视为否定响应
else

   echo "否定响应:$input"

fi

该脚本会提出问题,并等待用户输入响应。 脚本中的逻辑流程取决于用户的输入。

“是”或“yes”表示肯定响应。
任何其他输入都被视为否定响应。
如果在没有输入任何文本的情况下按下 Enter 键,则不会执行任何操作。

要进行测试,请将此脚本复制到文件中,并将其另存为 long_script.sh。 使用 chmod 使其可执行。

chmod +x long_script.sh

使用以下命令运行该脚本。 尝试输入 “yes”、”y” 和其他任何内容作为输入,包括在不输入文本的情况下按 Enter 键。

./long_script.sh

要使 yes 命令为脚本的问题提供响应,请将 yes 命令的输出通过管道传递给该脚本。

yes | ./long_script.sh

有些脚本的要求更加严格,只接受完整的 “yes” 作为肯定响应。您可以使用以下方式将“yes”作为参数提供给 yes 命令:

yes yes | ./long_script.sh

谨慎使用 yes 命令

您需要确保输入到脚本或程序的输入,肯定会产生您期望的结果。要做出这样的决定,您必须了解这些问题以及您应该给出的答案。

脚本、命令或程序中的逻辑可能与您的预期不同。 在我们的示例脚本中,问题可能是 “您想停止吗? [y,n]”。 在这种情况下,否定响应将允许脚本继续运行。

在您放心地将 yes 命令的输出输入到脚本中之前,您必须熟悉该脚本、命令或程序。

在命令中使用 yes 命令

早些时候,yes 命令通常与其他 Linux 命令一起使用。 如今,大多数其他 Linux 命令都有自己的机制,无需人工干预即可运行。不再需要 yes 命令来完成此操作。

以 Ubuntu 包管理器 apt-get 为例。 要安装应用程序而不必在安装过程中按 “y”,以前会使用 yes 命令,如下所示:

yes | sudo apt-get install fortune-mod

可以使用 apt-get 中的 -y (假设为 “yes”) 选项来实现相同的结果:

sudo apt-get -y install fortune-mod

您会发现 apt-get 甚至没有像往常那样询问 “您想继续吗? [Y/n]” 这个问题。它只是假设答案是 “yes”。

在其他 Linux 发行版上,情况也是如此。 在 Fedora 上,以前会这样使用软件包管理器命令:

yes | yum install fortune-mod

dnf 包管理器已取代 yum,并且 dnf 有自己的 -y (假设为 “yes”) 选项。

dnf -y install fortune-mod

这同样适用于 cp, fsckrm 命令。这些命令都有自己的 -f (强制) 或 -y (假设为 “yes”) 选项。

那么,yes 命令是否似乎已降级为仅用于脚本? 并不完全是。这个老家伙还有一些技巧。

yes 命令的更多技巧

您可以将 yes 命令与 seq 命令生成的数字序列一起使用,来控制重复操作的循环。

下面这个单行命令会将生成的数字输出到终端窗口,然后调用 sleep 命令暂停一秒钟。

您可以调用其他命令或脚本,而不只是将数字输出到终端窗口。 该命令或脚本甚至不需要使用这些数字,它们只是用来启动循环中的每次迭代。

yes "$(seq 1 20)" | while read digit; do echo digit; sleep 1; done

有时,使用大文件进行测试很有用。 也许您想练习使用 zip 命令,或者想拥有一个相当大的文件来测试 FTP 上传。

可以使用 yes 命令快速生成大文件。 您只需提供一个很长的文本字符串给它,然后将输出重定向到一个文件中。 务必小心,这些文件会迅速增长。 请准备好在几秒钟内按下 Ctrl+C。

yes 用于文件填充的无意义长文本 > test.txt
ls -lh test.txt
wc test.txt

在用于本文研究的测试机器上,此处生成的文件大约花费了 5 秒。 ls 命令报告其大小为 557 Mb,而 wc 命令则告诉我们其中有 1240 万行。

我们可以通过在命令字符串中包含 head 命令来限制文件的大小。 我们告诉 head 命令在文件中包含多少行。 -50 表示 head 命令只允许 50 行传递到 test.txt 文件中。

yes 用于文件填充的无意义长文本 | head -50 > test.txt

一旦 test.txt 文件中有 50 行,该过程就会停止。 您不需要使用 Ctrl+C。 它会优雅地自行停止。

wc 命令报告该文件有 50 行、400 个字,大小为 2350 字节。

尽管 yes 命令对于向长时间运行的脚本提供响应(以及其他一些技巧)仍然很有用,但它不会成为您日常命令工具包的一部分。 然而,当您真正需要它时,您会发现它非常简单易用,而且全部包含在六行精简的代码中。