【问题标题】:Bash confirmation won't wait for user inputBash 确认不会等待用户输入
【发布时间】:2018-07-16 08:59:04
【问题描述】:

我正在尝试使用 bash 脚本实现确认提示,但由于某种原因,提示不会等待用户输入。我已经尝试了很多例子,但到目前为止还没有运气。如果有什么不同,我在 MacOS 上。

只是我尝试的几个例子(所有复制+粘贴来自 SO 中的其他答案):

#!/bin/bash

read -p "Are you sure? " -n 1 -r
echo    # (optional) move to a new line
if [[ $REPLY =~ ^[Yy]$ ]]
then
    # do dangerous stuff
fi

#!/bin/bash

read -p "Continue (y/n)?" CONT
if [ "$CONT" = "y" ]; then
  echo "yaaa";
else
  echo "booo";
fi

#!/bin/bash

while true; do
read -rsn1 input
if [ "$input" = "a" ]; then
    echo "hello world"
fi
done

#!/bin/bash

read -p "Continue (y/n)?" choice
case "$choice" in
  y|Y ) echo "yes";;
  n|N ) echo "no";;
  * ) echo "invalid";;
esac

这甚至不会提示任何内容:

#!/bin/bash
read -n 1 -s -r -p "Press any key to continue"

【问题讨论】:

  • 不清楚。什么不工作,什么是预期行为?
  • 1.运行 bash 脚本。 2. 提示用户“你想继续吗?[y/N]” 3. 用户按任意键。 4.如果是“y”,那么做一些事情,否则继续。问题:第 2 步只是在终端上打印消息并在没有提示用户的情况下完成。
  • 脚本是如何启动的?
  • 它实际上是一个.git/hooks/commit-msg 文件,所以当用户运行git commit -m 'Hello' 时,commit-msg 会被触发/启动。
  • 看到这个答案how-do-i-prompt-the-user-from-within-a-commit-msg-hook,好像标准输入已经关闭了,确实可以加ls -l /dev/fd/看:0 -> /dev/null,另一种解决方案,可能是exec 0

标签: bash githooks pre-commit-hook


【解决方案1】:

最初的问题缺少重要的部分,这是我的错,一开始就没有说清楚。在@NahuelFouilleul 发表评论后,这一点变得很明显。确认/问题提示没有等待用户按键。原因是我的 bash 脚本被 git 钩子调用。在这种情况下,事情的处理方式似乎略有不同。解决方案如下,但原始答案是here

#!/bin/bash

exec < /dev/tty

while true; do
    read -p "Accepting the offer? (y/n) " answer

    if [[ $answer =~ ^[Yy]$ ]] ;
    then
        echo "Accepted"
    else
        echo "Not accepted"
    fi

    break
done

【讨论】:

    【解决方案2】:

    从评论更改为回答:在 commit-msg 钩子中,标准输入似乎已关闭,确实可以通过添加以下命令进行检查

    ls -l /dev/fd/
    

    给了

    ... 0 -> /dev/null
    

    this post中所述

    exec 0< /dev/tty
    

    将标准输入恢复到tty,另一种解决方案注意到标准输出和错误仍然重定向到tty

    exec 0<&1
    

    【讨论】:

      【解决方案3】:

      试试这个:

      echo -n "Continue  (y/n)?"
      read CONT
      if [ "$CONT" = "n" ]
      then
        echo "NO"
      else
        echo "YES"
      fi
      

      echo -n 表示没有换行符

      【讨论】: