【问题标题】:What is the Linux equivalent to DOS pause?Linux 相当于 DOS 暂停是什么?
【发布时间】:2010-09-10 16:54:58
【问题描述】:

我有一个 Bash shell 脚本,我想在其中暂停执行,直到用户按下一个键。在 DOS 中,这很容易通过pause 命令完成。我可以在我的脚本中使用 Linux 等效项吗?

【问题讨论】:

    标签: linux bash shell


    【解决方案1】:

    read 这样做:

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

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

    如果您使用 Bash,您还可以使用 -t 指定超时,这会导致读取在未按下键时返回失败。比如:

    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
    

    【讨论】:

    • 严格来说,应该是"Enter any non-NUL character to continue"。有些键不发送任何字符(如Ctrl...),有些发送多个字符(如F1Home...)。 bash 忽略 NUL 字符。
    • 通常最好要求输入一个特定的键,例如输入、空格或 Y。“ANY”可能会让一些用户感到困惑,因为有一个 TAB 键,所以为什么没有 ANY 键?确定有一些潜在危险的键,如 ESCAPE、CTRL、CMD、电源按钮等。今天这不再那么重要了,因为现在控制台通常只由能够正确解释“ANY 键”的高级计算机用户使用. Apple 2 设计手册,相当古老,有一个有趣的部分专门讨论这个主题 (apple2scans.net/files/1982-A2F2116-m-a2e-aiiedg.pdf)。
    • 如果您改为使用消息Press a key to continue...,那么即使是新手用户也可以找到a 键并按下它;o)
    • 这会对command | myscript.shmyscript.sh | command 产生问题。请参阅this answer 以获得解决方案。
    • 如果有人得到read: 1: read: Illegal option -n,请确保将您的命令包含在bash -c 'command && command' 等中,因为该错误可能来自sh。我在 Lando 包装器命令中执行此操作。
    【解决方案2】:

    我经常使用这些非常短的方法,它们就像@theunamedguy 和@Jim 解决方案,但还具有超时和静默模式。

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

    命令

    • 输入解决方案

      read -rsp $'Press enter to continue...\n'
      
    • 逃生解决方案 (with -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 $'prompt' 指定提示符,需要在 $' 和 ' 之间允许空格和转义字符。请注意,您必须在带有美元符号的单引号之间加上转义字符,否则您可以使用单引号。

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

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

    -e 指定 readline 模式。

    -i $'Y' 将 Y 指定为 readline 模式下的初始文本。

    -t 5指定超时5秒

    key 在您需要知道输入的情况下提供服务,在 -n1 情况下,为已按下的键。

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

    【讨论】:

    • +1 用于解释-sman readread --help help 在 Ubuntu 10.04.1 LTS 上没有帮助。编辑:help read 做了;其余的是否已弃用?
    • 1+ 很好的解释:但我得到了read: -i: invalid option 的前任。 read -rp $'Are you sure (Y/n) : ' -ei $'Y' key;on #osx read -rp $'kill-server: Are you sure (Y/n) : ' -d $'Y' key; 为我工作。 `
    • 我不知道它在 OSX 上是如何工作的,但我已经做了一些测试,-i 在 Ubuntu 上完美运行,我也不知道-d 是否能以同样的方式在 Ubuntu 上运行OSX。
    • 一个人可以通过在阅读前使用 echo 来解决提示非常快速和好的问题,最终 echo -n
    【解决方案3】:

    这对我来说适用于多种 Linux 风格,而其他一些解决方案却没有(包括这里最流行的解决方案)。我认为它也更具可读性...

    echo Press enter to continue; read dummy;
    

    请注意,需要将变量作为参数提供给read

    【讨论】:

    • 这个答案解决了我的问题,如果我复制并粘贴这一行并且由于某种原因我附加了更多行,则附加的行不会被执行,就像 DOS 暂停一样
    【解决方案4】:

    read 不带任何参数,只有按回车才会继续。 如果您按任意键,DOS pause 命令将继续。如果您想要这种行为,请使用 read –n1

    【讨论】:

      【解决方案5】:

      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
      

      【讨论】:

      • status=none 也不是可移植的。将 stdout 和 stderr 重定向到 /dev/null 。 read -r line &lt; /dev/tty 足以按 ENTER...
      • @StephaneChezales 谢谢 - 我不知道。我现在修复它。再次感谢 - 修复。顺便说一句,你是一个无底洞的有价值信息。
      • 还要注意settings=$(stty -g); stty raw; dd ...; stty "$settings"以保存和恢复tty设置。
      • 否,因为tr 会将其输出缓冲为管道,并且非美国键盘具有发送\1-\177 范围之外的字符的键。 dd 是这里的惯用方式。
      • 我之前使用过read -rsp $'Press any key to continue...\n' -n 1 key,但它总是无法重置我的终端设置,所以我必须在之后运行reset。这个命令非常适合我(在 macOS 10.15 上)!我还在trap 行之后添加了stty -echo,因为我不想看到我输入的字符。
      【解决方案6】:

      如果您只需要暂停循环或脚本,并且您乐于按 Enter 而不是按任何键,那么 read 自己就可以完成这项工作。

      do_stuff
      read
      do_more_stuff
      

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

      【讨论】:

      • 这是对的,但是对于数据库来说,展示一个例子是最有帮助的。
      • 谢谢,我采纳了您的建议。事后看来,仅仅写一个命令名称并不是很清楚。
      【解决方案7】:

      此函数在bashzsh 中均有效,并确保对终端的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 中,以实现大正义!

      【讨论】:

        【解决方案8】:

        这修复了它,所以按 ENTER 以外的任何键仍会转到新行

        read -n1 -r -s -p "Press any key to continue..." ; echo
        

        比windows暂停要好,因为你可以改变文字让它更有用

        read -n1 -r -s -p "Press any key to continue... (cant find the ANY key? press ENTER) " ; echo
        

        【讨论】:

        • 我认为您的解决方案是唯一真正类似于 Windows 提示的解决方案,您被要求在同一行键入任何键。除了提示符中的每个点 . 之前,由于某种原因,还有一个额外的空格
        • 在 system() 调用中不起作用。例如。此 C++ 代码 system("read -n1 -r -s -p \"Press any key to continue...\" ; echo"); 显示错误:sh: 1: read: Illegal option -n。尽管 read -n1 命令在同一个 Ubuntu shell 中运行良好。 pause 命令可以在 Windows 程序中用作system("pause");
        【解决方案9】:

        是的,使用read - 并且有一些调整使它在cron 和终端中都非常有用。

        例子:

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

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

        在终端中,它需要 2 分钟才能查看 rsync 命令的执行时间。

        那么后面的echo就是这样后面的bash提示符会出现在下一行。

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

        【讨论】:

          【解决方案10】:

          试试这个:

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

          【讨论】:

          • 有人能解释一下为什么这被否决了吗?是因为缺乏内容还是这是一个糟糕的解决方案?
          • @3ocene 这不显示创建的函数的用法;加上这缺乏任何解释。
          • 同意。能否举例说明如何调用此函数?
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2010-10-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多