【问题标题】:How to use goto statement in shell script [duplicate]如何在shell脚本中使用goto语句[重复]
【发布时间】:2026-01-12 00:15:02
【问题描述】:

我是 shell 脚本的初学者。我不知道如何使用 goto 语句。我正在使用以下代码。

start:
echo "Main Menu"
echo "1 for Copy"
echo "2 for exit"
read NUM
case $NUM in
"1")
echo "CopyNUM"
goto start:;
"2")         
echo "Haiiii";
goto start:
*)
echo "ssss";
esac

【问题讨论】:

  • 请勿将 shell 用于此类目的。
  • 如果你检查man bash,你将找不到goto——这是有原因的。 bash 中没有 goto。如果你想要分支控制,你有loopsselectcasefunctionsif then else。这些将满足您的需要是一种更优雅的方式。在上述情况下,selectwhile 循环就是您想要的。
  • C shell 有一个转到:linux.die.net/man/1/csh

标签: bash shell


【解决方案1】:

正如其他人所指出的,bash(或其他类似 POSIX 的 shell)中没有 goto - 其他更灵活的流控制结构取而代之。
man bash 中查找标题Compound Commands

在您的情况下,select 命令是正确的选择。 由于如何使用它可能并不明显,这里有一些东西可以帮助您入门:

#!/usr/bin/env bash

echo "Main Menu"

# Define the choices to present to the user, which will be
# presented line by line, prefixed by a sequential number
# (E.g., '1) copy', ...)
choices=( 'copy' 'exit' )

# Present the choices.
# The user chooses by entering the *number* before the desired choice.
select choice in "${choices[@]}"; do

  # If an invalid number was chosen, $choice will be empty.
  # Report an error and prompt again.
  [[ -n $choice ]] || { echo "Invalid choice." >&2; continue; }

  # Examine the choice.
  # Note that it is the choice string itself, not its number
  # that is reported in $choice.
  case $choice in
    copy)
      echo "Copying..."
      # Set flag here, or call function, ...
      ;;
    exit)
      echo "Exiting. "
      exit 0
  esac

  # Getting here means that a valid choice was made,
  # so break out of the select statement and continue below,
  # if desired.
  # Note that without an explicit break (or exit) statement, 
  # bash will continue to prompt.
  break

done

【讨论】:

    【解决方案2】:

    这是一个使用select 循环来实现目标的简短示例。如果您想要自定义格式,您可以使用带有自定义菜单的 while 循环,但基本菜单是 select 的设计目的:

    #!/bin/bash
    
    ## array of menu entries
    entries=( "for Copy"
              "for exit" )
    
    ## set prompt for select menu
    PS3='Selection: '
    
    while [ "$menu" != 1 ]; do                ## outer loop redraws menu each time
        printf "\nMain Menu:\n\n"             ## heading for menu
        select choice in "${entries[@]}"; do  ## select displays choices in array
            case "$choice" in                 ## case responds to choice
                "for Copy" )
                    echo "CopyNUM"
                    break                     ## break returns control to outer loop
                    ;;
                "for exit" )         
                    echo "Haiiii, exiting"
                    menu=1                    ## variable setting exit condition
                    break
                    ;;
                * )
                    echo "ssss"
                    break
                    ;;
            esac
        done
    done
    
    exit 0
    

    使用/输出

    $ bash select_menu.sh
    
    Main Menu:
    
    1) for Copy
    2) for exit
    Selection: 1
    CopyNUM
    
    Main Menu:
    
    1) for Copy
    2) for exit
    Selection: 3
    ssss
    
    Main Menu:
    
    1) for Copy
    2) for exit
    Selection: 2
    Haiiii, exiting
    

    【讨论】: