mvdan / sh

A shell parser, formatter, and interpreter with bash support; includes shfmt
https://pkg.go.dev/mvdan.cc/sh/v3
BSD 3-Clause "New" or "Revised" License
7.2k stars 340 forks source link

"}" can only be used to close a block #993

Closed leetrout closed 1 year ago

leetrout commented 1 year ago

Given this code:

function help_msg {
    echo "Wrong arguments" >&2
    echo "Usage:"
    echo "  $0 -s source -d destination"
    echo "Options:"
    echo "  -s  Source vault"
    echo "  -d  Destination vault"
}

I am getting this error:

file.sh:10:1: "}" can only be used to close a block

I am unsure how to fix this

mvdan commented 1 year ago

What did you run exactly?. It's likely that you're trying to parse in POSIX mode when this is bash syntax.

leetrout commented 1 year ago

I just ran shfmt <file>

Will respond with additional details on Monday when I am back at work but I did figure out to change it to not use the function keyword yesterday and it worked.

I am inheriting some shell scripts I didn't write - thank you for the hint to look at the mode.

rgowtham commented 1 year ago

I am seeing a similar behavior with the below function as well,

function prettyTime {
    local _dt=$1
    local _dm
    local _dh
    local _ds
    _dh=$((_dt / 3600))
    _dm=$(((_dt / 60) % 60))
    _ds=$((_dt % 60))
    printf '%d:%02d:%02d' ${_dh} ${_dm} ${_ds}
}
~ shfmt run.sh
run.sh:41:1: "}" can only be used to close a block

I am using shfmt 3.7.0, not sure why shfmt considers this a bug

mvdan commented 1 year ago

@rgowtham as I tried to explain in my previous comment, this is not a bug in shfmt - the parser will work if you properly parse the script as Bash. You can do that explicitly via the -ln=bash flag, or by naming the script foo.bash, or by adding a shebang like #!/usr/bin/bash. Instead of any of those three options, your script probably just has a name like foo.sh, so the parser assumes POSIX shell, where function is not a valid way to declare functions.

mvdan commented 1 year ago

The parser should now give a better error message.