如何使用Bash脚本始终回答“否”(No)来应对任何提示?

25
我有一个运行的程序,会询问用户一些问题。我想自动化它,使得每个问题都被回答为“否”。

1
我不知道为什么这个问题会被踩。它是一个完全合理的问题。 - Brian Campbell
1
合理,但不是很规范。让我们看看能否稍微整理一下。 - paxdiablo
5个回答

45
yes no | <command>

如果你要回答“no”,则<command>是你想回答“no”的命令。

(或者如果你只需要输出“n”,则可以使用yes n)

yes 命令默认情况下会持续输出 y,以回答每个提示都是“yes”。但你可以传入任意其他字符串作为参数,让它重复回答每个提示。

正如“just somebody”所指出的那样yes并没有实际上的标准。虽然它在我使用过的所有系统中都可用(不同的BSD、Mac OS X、Linux、Solaris、Cygwin),但如果你设法找到一个不支持该命令的系统,则应该使用以下方法:

while true; do echo no; done | <command>

或者作为yes的全功能shell脚本实现,您可以使用以下内容:

#!/bin/sh

if [ $# -ge 1 ]
then
    while true; do echo "$1"; done
else
    while true; do echo y; done
fi

终于我找到了yes命令的实际用途!:D 有一段时间我一直在想为什么会有这样一个命令。 - Automatico
顺便问一下,如果你执行 yes | <某些询问是/否的命令>,yes 命令会停止吗?如果我编写一个包含多个这些命令的 bash shell 脚本,会出现问题吗? - Automatico
3
当你把输出通过管道传送给另一个命令时,yes 命令会在那个命令停止时停止。如果那个命令问了 5 个问题,然后读取了 5 个答案,那么 yes 命令就会打印出 5 行。所以你可以编写一个包含多个这种命令的 bash 脚本,它会按照你的期望工作。 - Brian Campbell

8
对于没有这样命令的系统,只需要一个简单的回显即可。
echo "no" | command

对于重复操作,制作一个无限循环的while/for循环并不难。


点赞!不明白为什么会有-1。这很有效,使用标准命令并且简单易懂。谢谢! - Jan

7

actually, it looks funny ...

$ yes no

manpages摘录:

$ man yes 

YES(1)                    BSD General Commands Manual                   YES(1)

NAME
     yes -- be repetitively affirmative

SYNOPSIS
     yes [expletive]

DESCRIPTION
     yes outputs expletive, or, by default, ``y'', forever.

...

“Expletive”,据我所知,通常是某种脏话。我想知道这是否是作者开的玩笑。 - paxdiablo
@paxdiablo: 不是必然的: http://www.merriam-webster.com/dictionary/expletive 无论如何,在Unix中有许多“政治不正确”的笑话:/etc中的ttys文件是其中最著名的之一(它的发音类似于“titties”,意为“乳房”)。 - just somebody

1

如果您对某些可移植性感兴趣的话,需要注意:yes(1)在单一Unix规范(又名POSIX)中没有描述,因此是非标准化的。 但无论如何它仍然很容易移植(请参阅HISTORY段落; 遗憾的是MYYN没有引用整个内容):

YES(1)                  FreeBSD General Commands Manual                 YES(1)

NAME
     yes — be repetitively affirmative

SYNOPSIS
     yes [expletive]

DESCRIPTION
     The yes utility outputs expletive, or, by default, “y”, forever.

HISTORY
     The yes command appeared in Version 32V AT&T UNIX.

FreeBSD 9.0                      June 6, 1993                      FreeBSD 9.0

编辑

如果你遇到了一个不支持这个命令的奇怪系统,那么自己提供它也很简单。以下代码来自于FreeBSD-9:

int
main(int argc, char **argv)
{
 if (argc > 1)
  while (puts(argv[1]) != EOF)
   ;
 else
  while (puts("y") != EOF)
   ;
 err(1, "stdout");
 /*NOTREACHED*/
}

怪了。你说得对,这不是ins SUS。这太出乎意料了;难道还有没有包含它的现存系统吗? - Brian Campbell

0
如果你发现由于某些原因,yes的回答太快了,你可以通过使用修改过的@Brian Campbell的答案来稍微减缓速度——这样做可以在每个“no”的重复之间增加0.1秒的延迟。
while true; do echo no; sleep 0.1s; done | <command here> 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接