如何在bash中只要按“是”就执行“是/否”操作?

如何在bash中只要按“是”就执行“是/否”操作?

假设我在 bash 脚本中有“是/否”结构:

read -r -p "Yes or no?" response
if [[ $response =~ ^([yY][eE][sS]|[yY])$ ]]
 then 
 do ...
else
 exit 0
fi

我希望执行此构造,直到我按“否”为止。即,如果我按“是”,那么在完成操作“执行...”后,我想再次“是或否?”回复。

答案1

你需要不断地要求回应,直到它不是你想要的为止:

while true;
do
    read -r -p "Yes or no? " response   
    if [[ $response =~ ^([yY][eE][sS]|[yY])$ ]]
    then
        echo "You chose yes"
    else
        exit 0
    fi
done

答案2

使用 while 循环:

while
  read -r -p "Yes or no? " response &&
    [[ $response =~ ^([yY][eE][sS]|[yY])$ ]]
do
  ...
done

或者使该代码与 POSIXsh兼容,这样您就不需要bash安装:

while
   printf 'Yes or No? ' &&
     read answer
do
  case $answer in
    ([yY][eE][sS] | [yY]) ...;;
    (*) break;;
  esac
done

请注意,我们还检查失败退出状态printf(这可能表示管道损坏)和read(这将表示 eof)作为循环的退出条件,因为这通常是您想要的。

bash在s的情况下read -p,提示符将由read内置的 shell 进程发出,因此当 stdout 成为损坏的管道时,shell 将被杀死,但对于printf,是否会杀死 shellprintf取决于sh实现,因为并非所有实现都有printf内置。为了保持一致性,您可能还想将printf错误报告为您自己的脚本错误:

while
   printf 'Yes or No? ' || exit # with the exit status of printf
   read answer # eof not considered as an error condition
do
  case $answer in
    ([yY][eE][sS] | [yY]) ...;;
    (*) break;;
  esac
done

相关内容