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
, fsck
和 rm
命令。这些命令都有自己的 -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
命令对于向长时间运行的脚本提供响应(以及其他一些技巧)仍然很有用,但它不会成为您日常命令工具包的一部分。 然而,当您真正需要它时,您会发现它非常简单易用,而且全部包含在六行精简的代码中。