什么是Linux相当于DOS暂停?


236

我有一个Bash shell脚本,我想在其中暂停执行,直到用户按下一个键为止。在DOS中,可以使用“ pause”命令轻松完成此操作。我可以在脚本中使用等效的Linux吗?

Answers:


329

read 做这个:

user@host:~$ read -n1 -r -p "Press any key to continue..." key
[...]
user@host:~$ 

-n1指定它只是等待一个字符。在-r将其放入原始模式,这是必要的,否则,如果按类似反斜杠,它不会注册,直到你遇到下一个关键。在-p指定的提示,如果包含空格,必须用引号括起来。key仅当您想知道他们按下了哪个键时才需要该参数,在这种情况下,您可以通过以下方式访问它$key

如果您使用的是Bash,则还可以使用来指定超时-t,这会导致未按任何键时read返回失败。因此,例如:

read -t5 -n1 -r -p 'Press any key in the next five seconds...' key
if [ "$?" -eq "0" ]; then
    echo 'A key was pressed.'
else
    echo 'No key was pressed.'
fi

5
严格说来就是"Enter any non-NUL character to continue"。一些键不发送任何字符(如Ctrl...),而某些键则发送多个字符(如F1Home...)。bash忽略NUL字符。
Stephane Chazelas 2014年

2
通常,最好输入一个特定的键,例如回车键,空格键或Y键。“ ANY”可能会使某些用户感到困惑,因为有一个TAB键,所以为什么没有ANY键,并且肯定有一些潜在危险的键例如ESCAPE,CTRL,CMD,电源按钮等。今天这已经不那么重要了,因为如今控制台通常仅由能够正确解释“任何键”的高级计算机用户使用。《 Apple 2设计手册》虽然很老,但是却有一个有趣的章节专门针对这一主题(apple2scans.net/files/1982-A2F2116-m-a2e-aiiedg.pdf)。
Gellweiler '18 -4-6

3
如果您改为使用该消息,Press a key to continue...那么即使是新手用户也可以找到该a密钥并按下它; o)
DJDaveMark

1
command | myscript.sh或会有问题myscript.sh | command。请参阅此答案以获取解决方案。
汤姆·黑尔

如果有人得到read: 1: read: Illegal option -n确保将您的命令包装在bash -c 'command && command'等中,因为该错误很可能来自sh。我正在用Lando包装器命令执行此操作。
伊利亚·林恩

155

我使用了很多非常简短的方法,它们就像@theunamedguy和@Jim解决方案一样,但是还有超时和静默模式。

我特别喜欢最后一种情况,并将其用在许多循环运行的脚本中,直到用户按下为止Enter

指令

  • 输入解决方案

    read -rsp $'Press enter to continue...\n'
  • 转义解决方案 (带有-d $'\ e')

    read -rsp $'Press escape to continue...\n' -d $'\e'
  • 任何关键解决方案 (带有-n 1)

    read -rsp $'Press any key to continue...\n' -n 1 key
    # echo $key
  • 具有预选选项的问题 (带有-ei $'Y')

    read -rp $'Are you sure (Y/n) : ' -ei $'Y' key;
    # echo $key
  • 超时解决方案 (使用-t 5)

    read -rsp $'Press any key or wait 5 seconds to continue...\n' -n 1 -t 5;
  • 睡眠增强别名

    read -rst 0.5; timeout=$?
    # echo $timeout

说明

-r指定原始模式,该模式不允许使用诸如“ \”或“ ^”之类的组合字符。

-s指定静默模式,并且因为我们不需要键盘输出。

-p $' 提示符 '指定提示符,提示符必须在$'和'之间,以允许空格和转义字符。注意,必须在单引号之间加上美元符号以使转义字符受益,否则可以使用简单的引号。

-d $' \ e '将 escappe指定为分隔符,因此作为当前输入的最后一个字符,可以放置任何字符,但请小心放置用户可以键入的字符。

-n 1指定仅需要一个字符。

-e指定读取行模式。

-i $' Y '在读取行模式下将Y指定为初始文本。

-t 5指定5秒的超时

关键服务的情况下,你需要知道的投入,在-N1的情况下,已被按下的键。

$?用于了解最后一个程序的退出代码,以供读取;如果超时,则为142,正确的输入为0。放$?如果需要在某些命令后对其进行测试,请尽快将其放入变量中,因为所有命令都会重写$?


1
+1解释-s; man readread --help帮助在Ubuntu 10.04.1 LTS上无济于事。编辑:help read做了;是否已弃用?
Cees Timmerman 2014年

1
1+的绝佳解释:但我read: -i: invalid option对前任有所了解。read -rp $'Are you sure (Y/n) : ' -ei $'Y' key;在#osx上read -rp $'kill-server: Are you sure (Y/n) : ' -d $'Y' key;适合我。`
蒂诺·鲁布(TinoRüb)2016年

我不知道它在OSX上如何工作,但是我已经做了一些测试并且-i可以在Ubuntu上完美地工作,而且我也不知道-d在OSX上如何工作。
y.petremann '16

可以通过在读取前使用回显来解决提示问题,从而非常快速,好用,最终回显-n
THESorcerer

15

read如果没有任何参数,则只有按Enter键才能继续。pause如果您按任意键,DOS 命令将继续。read –n1如果您想要这种行为,请使用。


15

这对我来说适用于多种版本的Linux,而其他一些解决方案则没有(包括此处最受欢迎的解决方案)。我认为它也更具可读性...

echo Press enter to continue; read dummy;

请注意,需要提供一个变量作为参数read


这个答案解决我的问题,如果我复制并粘贴此行出于某种原因,我得到了更多的附加线路,附加线路不被执行,就像是用DOS暂停
塞尔吉奥

10

read -n1不便携。一种可移植的方法可以是:

(   trap "stty $(stty -g;stty -icanon)" EXIT
    LC_ALL=C dd bs=1 count=1 >/dev/null 2>&1
)   </dev/tty

除了使用 read,只需按一下ENTER即可继续提示,您可以执行以下操作:

sed -n q </dev/tty

2
status=none也不是便携式的。将stdout和stderr重定向到/ dev / null。按ENTER ...read -r line < /dev/tty就足够了。
Stephane Chazelas 2014年

@StephaneChezales谢谢-我不知道。现在就解决它。再次感谢-已修复。顺便说一句,您是无价之宝。
mikeserv 2014年

1
还要注意settings=$(stty -g); stty raw; dd ...; stty "$settings"保存和恢复tty设置。
Stephane Chazelas 2014年

@StephaneChezales-不是在计算机上-您认为tr编辑的东西也可以工作吗?
mikeserv 2014年

1
否,因为tr会将其输出缓冲为管道,并且非美国键盘的键会发送超出\1-\177范围的字符。dd这是惯用的方式。
Stephane Chazelas 2014年

2

如果您只需要暂停循环或脚本,并且很乐意按Enter键而不是任何键,则read可以自行完成此工作。

do_stuff
read
do_more_stuff

它不是最终用户友好的,但是在您自己编写快速脚本并且需要暂停它以在后台手动执行某些操作的情况下,这可能就足够了。


的确如此,但是对于数据库来说,显示一个示例最有帮助。
SDsolar

谢谢,我接受了您的建议。事后看来,仅编写命令名称并不十分清楚。
mwfearnley

1

试试这个:

function pause(){
   read -p "$*"
}

1
有人可以解释为什么这被否决吗?是因为内容不足,还是一个不好的解决方案?
3ocene

4
@ 3ocene这不会显示所创建函数的用法;加上这缺乏任何解释。
parvus

同意 您能否举例说明如何调用此函数?
SDsolar

1

此功能可在bash和中使用zsh,并确保对终端的I / O:

# Prompt for a keypress to continue. Customise prompt with $*
function pause {
  >/dev/tty printf '%s' "${*:-Press any key to continue... }"
  [[ $ZSH_VERSION ]] && read -krs  # Use -u0 to read from STDIN
  [[ $BASH_VERSION ]] && </dev/tty read -rsn1
  printf '\n'
}
export_function pause

将其放入.{ba,z}shrc大正义中!


0

是的,可以使用read-并且有一些调整使其cron在终端和终端中都最有用。

例:

time rsync (options)
read -n 120 -p "Press 'Enter' to continue..." ; echo " "

-n 120使read语句在2分钟后超时,因此它不会阻塞 cron

在终端中,需要2分钟才能看到rsync命令执行了多长时间。

然后echo是下一个,因此下一个bash提示将出现在下一行。

否则,Enter在终端中按“继续...”后,它将直接显示在同一行上。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.