【问题标题】:#!/bin/bash read if then return to read#!/bin/bash read if then 返回读取
【发布时间】:2026-02-19 11:35:01
【问题描述】:

我想制作一个脚本,在你输入第一个命令后,我想被送回上一个。

#!/bin/bash
read -p " Please enter [x ; y ; z]: " COMMAND
if [ "$COMMAND" = x ] ; then
    echo " This is command X. "
#Then return to    read -p " Please enter [x ; y ; z]: " COMMAND

elif [ "$COMMAND" = y ]; then
    echo " This is command y. "
#Then return to    read -p " Please enter [x ; y ; z]: " COMMAND

elif [ "$COMMAND" = z ]; then
    echo " This is command z"
#Then return to    read -p " Please enter [x ; y ; z]: " COMMAND

else
    echo " Command not found! "
fi

例如,如果您输入 x ,我希望可以在 y 或 z 之后输入。可以在同一个脚本中完成吗?

【问题讨论】:

    标签: bash if-statement return


    【解决方案1】:

    将要重复的部分包装在一个循环中,并考虑如何退出循环。在这里,如果您输入qbreak 命令将退出循环。否则,if 语句完成后,您将返回到循环的顶部进行另一轮。

    while true; do
        read -p " Please enter [x ; y ; z; q]: " COMMAND
        if [ "$COMMAND" = x ] ; then
            echo " This is command X. "        
        elif [ "$COMMAND" = y ]; then
            echo " This is command y. "        
        elif [ "$COMMAND" = z ]; then
            echo " This is command z"
        elif [ "$COMMAND" = q ]; then
            break
        else
            echo " Command not found! "
        fi
    done
    

    您可以通过使用 case 语句而不是大的 if 语句来清除它。您可以为每个选择执行多个命令; ;; 表示每个特定块的结束。

    while true; do
        read -p " Please enter [x ; y ; z; q]: " COMMAND
        case $COMMAND in
            x) echo "This is command X."
               ;;
            y) echo "This is command Y."
               ;;
            z) echo "This is command Z."
               ;;
            q) break ;;
        esac
    done
    

    您还可以包含一个特定的测试来代替true 命令,这样循环本身就可以检查命令的值并终止,而不是等待明确的break 命令。

    while [ "$COMMAND" -ne q ]; do
        read -p " Please enter [x ; y ; z; q]: " COMMAND
        case $COMMAND in
            x) echo "This is command X."
               ;;
            y) echo "This is command Y."
               ;;
            z) echo "This is command Z."
               ;;
        esac
    done
    

    【讨论】:

    • 非常感谢!你的评论对我有帮助。我更喜欢 if 的第一个选项。
    【解决方案2】:

    只需将整个内容包裹在一个永无止境的 while 循环中:

    while true
    do
        [whatever]
    done
    

    【讨论】:

      【解决方案3】:

      递归函数会让工作变得简单

      #!/bin/bash
      readfun(){
      read -p " Please enter [x ; y ; z]: " command  # Use lowercase names
      [[ "$command" =~ ^[xyz]$ ]] && readfun 
      # logical AND ie '&&' terminates the recursion if any character other than x y z is entered
      }
      readfun #starting point for the script
      echo "Command : ${command} not found"
      

      【讨论】:

      • 我不会使用递归来模拟 shell 中的迭代。
      • 我非常怀疑bash 是否针对递归进行了优化;最终,您将用完堆栈上的空间。只需使用循环。
      • @chepner :我怀疑递归调用没有优化,但我想知道文档没有提到这一点。
      • Shell 语言通常假定具有过程语言的背景,其中递归通常仅用于遍历递归数据结构(大多数 Shell 语言缺乏)。对任何类型的重复使用递归是函数式编程语言的标志。
      【解决方案4】:

      whilecase

      #!/bin/bash
      while true
      do
          read -p " Please enter [x ; y ; z]: " COMMAND
          case $COMMAND in
              x) echo " This is command x. "
                  ;;
              y) echo " This is command y. "
                  ;;
              z) echo " This is command z. "
                  ;;
              *) exit 0
                  ;;
          esac
      done
      

      在行动:

      $ bash test.sh
       Please enter [x ; y ; z]: x
       This is command x.
       Please enter [x ; y ; z]: y
       This is command y.
       Please enter [x ; y ; z]: z
       This is command z.
       Please enter [x ; y ; z]: a
      $
      

      【讨论】: