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
6.97k stars 332 forks source link

syntax: [ / test do not support expressions specified with escaped parentheses #1036

Closed dtrudg closed 8 months ago

dtrudg commented 8 months ago

Version 3.7.0

Running the following excerpt, taken from the start of a script that NVIDIA inserts into their container images, through gosh results in the error 13:4: not a valid test operator: (

#!/bin/sh

set -x 

NV_DRIVER_VERS=$(sed -n 's/^NVRM.*Kernel Module *\([^() ]*\).*$/\1/p' /proc/driver/nvidia/version 2>/dev/null | sed 's/^$/unknown/')

export _CUDA_COMPAT_PATH=${_CUDA_COMPAT_PATH:-/usr/local/cuda/compat}

# Set paths to use
_CUDA_COMPAT_CHECKFILE="${_CUDA_COMPAT_PATH}/.${NV_DRIVER_VERS}.$(hostname).checked"

# If the CUDA driver was detected and the compat check hasn't been flagged as done yet, proceed
if [ \( \( -n "${NV_DRIVER_VERS}" -a -e /dev/nvidiactl \) -o -e /dev/nvgpu \) -a ! -e "${_CUDA_COMPAT_CHECKFILE}" ]; then
  echo
fi

It appears from a simpler example, that mvdan.cc/sh / gosh doesn't support parentheses in test / [ expressions, as below... where they are written \( to avoid subshell evaluation.

$ cat paren-test.sh 
#!/bin/sh

if [ \( "bob" == "bob" \) ]; then
  echo "hello ["
fi

if test \( "bob" == "bob" \); then
  echo "hello test"
fi

$ /bin/sh paren-test.sh 
hello [
hello test

$ gosh paren-test.sh 
3:4: not a valid test operator: bob
3:4: not a valid test operator: bob
7:4: not a valid test operator: bob
7:4: not a valid test operator: bob

Is support for parentheses in test / [ expressions something that would be in scope for this package, or does it fall under the other caveats around ambiguity etc?

mvdan commented 8 months ago

Thanks for spotting this and filing an issue. We have supported parentheses in the [[ bash test syntax for years, but we didn't yet support them with classic test commands, surprisingly enough!