0

I'm trying to write a case/switch statement in my bash script as follows:

case "$REPLY" in
        E*|e*) $EDITOR "$COMMIT_MSG_FILE" < $TTY; continue ;;
        Y*|y*) exit 0 ;;
        N*|n*) exit 1 ;;
        *)     SKIP_DISPLAY_WARNINGS=1; create_prompt; continue ;;
esac

However, I keep getting

syntax error near unexpected token ';;'
          E*|e*) $EDITOR "$COMMIT_MSG_FILE" < $TTY; continue ;;'

From reading around, I know that ;; is the equivalent of a break statement in a traditional switch statement, but I'm not sure why I'm getting a syntax error here. All of the functions and variables are defined above, so I can't see that being an issue. Any advice?

EDIT: Entirety of the loop:

while true; do

    read_commit_message

    check_commit_valid

    # if there are no warnings, then the commit is good and we can exit!
    test ${#WARNINGS[@]} -eq 0 && exit 0;

    # if we're still here, there are warnings we need to display
    show_warnings

    # if non-interactive don't prompt and exit with an error
    # need interactivity for the prompt to show and get response
    if [ ! -t 1 ] && [ -z ${FAKE_TTY+x} ]; then
        exit 1
    fi

    # show message asking for proceed, etc
    echo -en "${BLUE}Proceed with commit? [e/y/n/?] ${NO_COLOR}"

    # read the response 
    read REPLY < "$TTY"

  # Check if the reply is valid
    case "$REPLY" in
        E*|e*) $EDITOR "$COMMIT_MSG_FILE" < $TTY; continue ;;
        Y*|y*) exit 0 ;;
        N*|n*) exit 1 ;;
        *)     SKIP_DISPLAY_WARNINGS=1; create_prompt; continue ;;
    esac

done
Alex Queen
  • 37
  • 4
  • 2
    Either you aren't using `bash`, or the source of the error is in the code that comes prior to the `case` statement (which must exist, because `continue` isn't valid outside of a loop). – chepner Oct 29 '19 at 14:47
  • I don't see anything wrong here. Is there more to the script you could post? Try adding `#!/bin/bash` at the top? – Jason Oct 29 '19 at 14:47
  • What is the value of EDITOR? I can see this error if EDITOR is something like "case", but I imagine it's not. – William Pursell Oct 29 '19 at 14:54
  • 3
    Double quote EDITOR and TTY to make sure they aren't empty. If TTY is empty, there is certainly a syntax error, but I would expect the error message to reference a single semi-colon. – William Pursell Oct 29 '19 at 14:56
  • `if EDITOR is something like "case"` - I strangely get `bash: case: command not found` on `EDITOR=case REPLY=E` – KamilCuk Oct 29 '19 at 14:57
  • 1
    @KamilCuk That actually makes sense. Since a variable was expanded, 'case' is looked for as a command but not evaluated as a keyword. – William Pursell Oct 29 '19 at 15:02
  • 1
    A syntax error would be raised during parsing, before any of the parameters are expanded. The source of the error is earlier in the code. – chepner Oct 29 '19 at 15:04
  • @Jason I added the rest of the loop as an edit. I have #!/bin/bash at the top of the file. – Alex Queen Oct 29 '19 at 15:13
  • @WilliamPursell EDITOR is by default set to emacs, but it will change depending on the user's git-editor config. – Alex Queen Oct 29 '19 at 15:14
  • @chepner As far as I'm aware, I am using `bash` (declared at top using `#!/bin/bash`, but I've posted the rest of the loop. – Alex Queen Oct 29 '19 at 15:17
  • 2
    If you run the script with something like `sh script.sh`, the shebang is ignored. – chepner Oct 29 '19 at 15:24
  • Is there anything before the loop? Run your script through http://shellcheck.net and fix any warnings or errors that it reports. – chepner Oct 29 '19 at 15:26
  • 1
    @chepner's response is about the only thing left I can think of. Is it possible there are some control characters (like a carriage return) in there somewhere. The code you posted works. You could try pasting that back into your script. – Jason Oct 29 '19 at 15:28
  • 1
    I believe you have dos line endings. Remove them with `dos2unix`. Bash parses `;;\r` and doesn't recognize the `;;` case ending and spits out a syntax error. – KamilCuk Oct 29 '19 at 15:30
  • 1
    @KamilCuk If that were the (only) problem, the parser would complain about the unexpected token `in\r` first. (The error message would also either be garbled due to the carriage return or explicitly mention `$';;\r'` as the unexpected token, depending on the version of `bash` involved.) – chepner Oct 29 '19 at 15:33
  • 1
    @chepner Och, you are right. And also complain about empty newlines trying to execute `$'\r'` command. Hm. But there is the `'` in the `;;'` in error message posted by OP - no, that `'` comes from quoting the line by bash. So either there is something after `;` that is unreadable or this is not ascii `;` but ex. that utf-8 [greek question mark](https://www.compart.com/en/unicode/U+037E). @AlexQueen Inspect the file under `hexdump -C` or `cat -v` and see if there is anything stange. – KamilCuk Oct 29 '19 at 15:36
  • 1
    `;;` isn't exactly an equivalent of 'break', as it is an unriddable (irreplaceable for a `break` or `continue` keyword, these do not act on `case`) element of 'case' syntax. [_BTW, recent `bash` versions reportedly introduce fallthru `;&` and resume `;;&` alternatives:_ https://stackoverflow.com/a/24544780/4240261](https://stackoverflow.com/a/24544780/4240261) – Mika Feiler Oct 29 '19 at 16:13
  • What's output of `grep -F 'E*|e*' yourscript | hd` ? – jhnc Oct 30 '19 at 03:10

0 Answers0