shellcheck icon indicating copy to clipboard operation
shellcheck copied to clipboard

options that change the parser's behaviour in a shell

Open izabera opened this issue 9 years ago • 7 comments

I don't know if shellcheck understands how blocks are parsed... Can it suggest that these don't work as expected?

alias a=b; shopt -s extglob; a +(x)

{
  alias c=d
  shopt -s extglob
  c +(x)
}

func () {
  alias e=f
  shopt -s extglob
  f +(x)
}

extglob is bash specific but aliases are not.

To complicate everything, these work:

shopt -s extglob; echo "${var#+(x)}"
shopt -s extglob; echo "$( echo +(x) )"
alias a=b; c $( a )

izabera avatar Aug 13 '15 02:08 izabera

How do you even come across these things O___o

koalaman avatar Aug 13 '15 02:08 koalaman

I use bash pretty often

izabera avatar Aug 13 '15 03:08 izabera

On a more serious note, these things have been mentioned in #bash several times, but I only figured out recently that $( ) causes a new parsing block in bash/ksh/mksh/zsh (it doesn't in busybox/dash/yash). It's probably worth mentioning (or maybe recommend against it) because it can be tricky...

izabera avatar Aug 13 '15 03:08 izabera

i have a better example of a real usecase:

#!/bin/sh
alias explode='set -f --;set +f'

x()
{
  explode A * C
  echo "$3"
}

x

shellsheck must internally replace/evaluate the alias.

bittorf avatar Nov 04 '15 20:11 bittorf

move -- in the other set...

izabera avatar Nov 04 '15 21:11 izabera

@izabera you are right, thank you. but the main problem keeps, sc is complaining:

SC2120 x references arguments, but none are ever passed. SC2119 Use x "$@" if function's $1 should mean script's $1.

bittorf avatar Nov 05 '15 05:11 bittorf

Aliases are tricky to use in scripts.

Your first line defines an alias and uses it within the same line. This may not do what you expect. Bash parses the whole line and doesn't immediately apply any aliases defined therein. Same goes for aliases within blocks and function definitions. As @temporaryrespite mentioned.

Example:

unalias lls
alias lls='ls -l'; lls   ## lls : command not found
lls ## only on the next line, the alias is recognized

unalias lls
{
  alias lls='ls -l'; lls   ## lls : command not found
  lls ## lls: command not found
}
lls ## uses the alias

mmjo avatar May 12 '22 07:05 mmjo