Command line parsing

Specific order in which a command line is parsed and its elements evaluated.


  • History expansion. The various bang, !, references are replaced.
  • History buffer updated. Stored in history buffer. Note all other parsing and evaluations occur later.
  • Alias substitution. Aliases are replaced by their definitions.
  • Command parsing. Recognition of command separators, ;, &, &&, and || occur now. Also, redirection is initialized but only as each individual command is processied. In the following example : set -o noclobber wc a1 > f1 || ls a1* > f1; head f1 The redirection of the 2rd command will occur only occur if the 1st command fails. If a1 exists, f1 will contain it's word count. The second command is not evaluated and the redirection is not done. If a1 does not exist, you will actually get the following errors. wc: al: No such file or directory # this is from ls because a1 doesn't exit. -bash: fn1: cannot overwrite existing file # this is because of noclobber, because bash is creating the 2nd redirection.
    From this point, the following steps are applied to each command when/if it is invoked.
  • File-name Brace expansion. Alternative lists of filenames generated now. Filename wild-cards are NOT evaluated at this point. Variables and variable braces are NOT evaluated at this point.
    > ls {dog,cat}house
    doghouse
    cathouse
    > ls {*}house
    ls: cannot access {*}house: No such file or directory
    
    Braces denature filename wild cards and variable references.
  • Tilde, ~, substitution. The tilde is replaced with directory path. The tilde has 4 forms :
  • ~ - by itself, it is user's home directory.
  • ~user-id - prepended to user-id, gives that user's home directory.
  • ~+ - prepended to plus, gives current directory.
  • ~- - prepended to minus, gives old working directory, where user cd'ed from.
  • Positional parameter and variable substitution. Expands positional variables such as $1 or $*. Expands defined variables. Variable braces handled here.
    >my=dog
    >echo "My house is the ${my}house."
      My house is the doghouse.
    
    The different quotes will limit the amount of expansion occurring. Also, the internal field separator, IFS, can affect how the positional parameters are parsed.
  • Arithmetic expansion, $(( )) This is the built-in equivalent of expr.
    num=1
    
    num=$(( $num + 1 ))
    
    echo $num
    
    echo will display 2
  • Command substitution, ` `, grave quotes and $() Commands inside the graves are run, and the output replaces the graves and command sequence on the command line. If an alias is named inside the graves, it will be processed, possibly because alias recognized the graves. Other expansions are less predictable. Bash also provides $() for the same task.
    > cmd="ls /"
    > echo `$cmd`
    boot cdrom dev etc export home initrd initrd.img lib lib32 lib64 lost+found
    media mnt opt proc root run sbin srv sys tmp usr var vmlinuz`
    >
    > echo $($cmd)
    boot cdrom dev etc export home initrd initrd.img lib lib32 lib64 lost+found
    media mnt opt proc root run sbin srv sys tmp usr var vmlinuz`
    

  • Word spitting Unquoted strings are now parsed into their words. Uses IFS to determine delimiters. i.e If one of the previous evaluations generated new strings, these are parsed.
  • File-name wild-cards or path expansion. Filename wild cards, *, and [...] are expanded. Quotes are still in effect and will suppress expansion.
  • Quote Removal. Any remaining quotes, ', \, or ", are removed, as long as they weren't generated by a previous expansion step.
  • Command[s] executed Commands are executed according to delimiters according to the sequential, background, and conditional delimiters.