================================================================================
Pipelines
================================================================================

whoami | cat
cat foo | grep -v bar

--------------------------------------------------------------------------------

(program
  (pipeline
    (command
      name: (command_name
        (word)))
    (command
      name: (command_name
        (word))))
  (pipeline
    (command
      name: (command_name
        (word))
      argument: (word))
    (command
      name: (command_name
        (word))
      argument: (word)
      argument: (word))))

================================================================================
Lists
================================================================================

a | b && c && d; d e f || e g

--------------------------------------------------------------------------------

(program
  (list
    (list
      (pipeline
        (command
          (command_name
            (word)))
        (command
          (command_name
            (word))))
      (command
        (command_name
          (word))))
    (command
      (command_name
        (word))))
  (list
    (command
      (command_name
        (word))
      (word)
      (word))
    (command
      (command_name
        (word))
      (word))))

================================================================================
While statements
================================================================================

while something happens; do
  echo a
  echo b
done

while local name="$1" val="$2"; shift 2; do
  printf "%s (%s)\n" "$val" "$name"
done

--------------------------------------------------------------------------------

(program
  (while_statement
    condition: (command
      name: (command_name
        (word))
      argument: (word))
    body: (do_group
      (command
        name: (command_name
          (word))
        argument: (word))
      (command
        name: (command_name
          (word))
        argument: (word))))
  (while_statement
    condition: (declaration_command
      (variable_assignment
        name: (variable_name)
        value: (string
          (simple_expansion
            (variable_name))))
      (variable_assignment
        name: (variable_name)
        value: (string
          (simple_expansion
            (variable_name)))))
    condition: (command
      name: (command_name
        (word))
      argument: (number))
    body: (do_group
      (command
        name: (command_name
          (word))
        argument: (string)
        argument: (string
          (simple_expansion
            (variable_name)))
        argument: (string
          (simple_expansion
            (variable_name)))))))

================================================================================
Until statements
================================================================================

until something happens; do
  echo a
  echo b
done

--------------------------------------------------------------------------------

(program
  (while_statement
    condition: (command
      name: (command_name
        (word))
      argument: (word))
    body: (do_group
      (command
        name: (command_name
          (word))
        argument: (word))
      (command
        name: (command_name
          (word))
        argument: (word)))))

================================================================================
While statements with IO redirects
================================================================================

while read line; do
  echo $line
done < <(cat file)

--------------------------------------------------------------------------------

(program
  (redirected_statement
    body: (while_statement
      condition: (command
        name: (command_name
          (word))
        argument: (word))
      body: (do_group
        (command
          name: (command_name
            (word))
          argument: (simple_expansion
            (variable_name)))))
    redirect: (file_redirect
      destination: (process_substitution
        (command
          name: (command_name
            (word))
          argument: (word))))))

================================================================================
For statements
================================================================================

for a in 1 2 $(seq 5 10); do
  echo $a
done

for ARG; do
  echo $ARG
  ARG=''
done

for c in ${=1}; do
	echo c
done

--------------------------------------------------------------------------------

(program
  (for_statement
    variable: (variable_name)
    value: (number)
    value: (number)
    value: (command_substitution
      (command
        name: (command_name
          (word))
        argument: (number)
        argument: (number)))
    body: (do_group
      (command
        name: (command_name
          (word))
        argument: (simple_expansion
          (variable_name)))))
  (for_statement
    variable: (variable_name)
    body: (do_group
      (command
        name: (command_name
          (word))
        argument: (simple_expansion
          (variable_name)))
      (variable_assignment
        name: (variable_name)
        value: (raw_string))))
  (for_statement
    variable: (variable_name)
    value: (expansion
      (variable_name))
    body: (do_group
      (command
        name: (command_name
          (word))
        argument: (word)))))

================================================================================
Select statements
================================================================================

select choice in X Y $(ls); do
  echo $choice
  break
done

select ARG; do
  echo $ARG
  ARG=''
done

--------------------------------------------------------------------------------

(program
  (for_statement
    (variable_name)
    (word)
    (word)
    (command_substitution
      (command
        (command_name
          (word))))
    (do_group
      (command
        (command_name
          (word))
        (simple_expansion
          (variable_name)))
      (command
        (command_name
          (word)))))
  (for_statement
    (variable_name)
    (do_group
      (command
        (command_name
          (word))
        (simple_expansion
          (variable_name)))
      (variable_assignment
        (variable_name)
        (raw_string)))))

================================================================================
C-style for statements
================================================================================

for (( c=1; c<=5; c++ ))
do
  echo $c
done

for (( c=1; c<=5; c++ )) {
	echo $c
}

for (( ; ; ))
do
  echo 'forever'
done

for ((cx = 0; c = $cx / $pf, c < $wc - $k; )); do
		echo "$cx"
done

for (( i = 4;;i--)) ; do echo $i; if (( $i == 0 )); then break; fi; done

# added post-bash-4.2
for (( i = j = k = 1; i % 9 || (j *= -1, $( ((i%9)) || printf " " >&2; echo 0), k++ <= 10); i += j ))
do
printf "$i"
done

echo

( for (( i = j = k = 1; i % 9 || (j *= -1, $( ((i%9)) || printf " " >&2; echo 0), k++ <= 10); i += j ))
do
printf "$i"
done )

--------------------------------------------------------------------------------

(program
  (c_style_for_statement
    (variable_assignment
      (variable_name)
      (number))
    (binary_expression
      (word)
      (number))
    (postfix_expression
      (word))
    (do_group
      (command
        (command_name
          (word))
        (simple_expansion
          (variable_name)))))
  (c_style_for_statement
    (variable_assignment
      (variable_name)
      (number))
    (binary_expression
      (word)
      (number))
    (postfix_expression
      (word))
    (compound_statement
      (command
        (command_name
          (word))
        (simple_expansion
          (variable_name)))))
  (c_style_for_statement
    (do_group
      (command
        (command_name
          (word))
        (raw_string))))
  (c_style_for_statement
    (variable_assignment
      (variable_name)
      (number))
    (variable_assignment
      (variable_name)
      (binary_expression
        (simple_expansion
          (variable_name))
        (simple_expansion
          (variable_name))))
    (binary_expression
      (word)
      (binary_expression
        (simple_expansion
          (variable_name))
        (simple_expansion
          (variable_name))))
    (do_group
      (command
        (command_name
          (word))
        (string
          (simple_expansion
            (variable_name))))))
  (c_style_for_statement
    (variable_assignment
      (variable_name)
      (number))
    (postfix_expression
      (word))
    (do_group
      (command
        (command_name
          (word))
        (simple_expansion
          (variable_name)))
      (if_statement
        (command
          (command_name
            (arithmetic_expansion
              (binary_expression
                (simple_expansion
                  (variable_name))
                (number)))))
        (command
          (command_name
            (word))))))
  (comment)
  (c_style_for_statement
    (variable_assignment
      (variable_name)
      (variable_assignment
        (variable_name)
        (variable_assignment
          (variable_name)
          (number))))
    (binary_expression
      (word)
      (binary_expression
        (number)
        (parenthesized_expression
          (binary_expression
            (word)
            (number))
          (command_substitution
            (redirected_statement
              (list
                (command
                  (command_name
                    (arithmetic_expansion
                      (binary_expression
                        (variable_name)
                        (number)))))
                (command
                  (command_name
                    (word))
                  (string)))
              (file_redirect
                (number)))
            (command
              (command_name
                (word))
              (number)))
          (binary_expression
            (postfix_expression
              (word))
            (number)))))
    (binary_expression
      (word)
      (word))
    (do_group
      (command
        (command_name
          (word))
        (string
          (simple_expansion
            (variable_name))))))
  (command
    (command_name
      (word)))
  (subshell
    (c_style_for_statement
      (variable_assignment
        (variable_name)
        (variable_assignment
          (variable_name)
          (variable_assignment
            (variable_name)
            (number))))
      (binary_expression
        (word)
        (binary_expression
          (number)
          (parenthesized_expression
            (binary_expression
              (word)
              (number))
            (command_substitution
              (redirected_statement
                (list
                  (command
                    (command_name
                      (arithmetic_expansion
                        (binary_expression
                          (variable_name)
                          (number)))))
                  (command
                    (command_name
                      (word))
                    (string)))
                (file_redirect
                  (number)))
              (command
                (command_name
                  (word))
                (number)))
            (binary_expression
              (postfix_expression
                (word))
              (number)))))
      (binary_expression
        (word)
        (word))
      (do_group
        (command
          (command_name
            (word))
          (string
            (simple_expansion
              (variable_name))))))))

================================================================================
If statements
================================================================================

if cat some_file | grep -v ok; then
  echo one
elif cat other_file | grep -v ok; then
  echo two
else
  exit
fi

--------------------------------------------------------------------------------

(program
  (if_statement
    (pipeline
      (command
        (command_name
          (word))
        (word))
      (command
        (command_name
          (word))
        (word)
        (word)))
    (command
      (command_name
        (word))
      (word))
    (elif_clause
      (pipeline
        (command
          (command_name
            (word))
          (word))
        (command
          (command_name
            (word))
          (word)
          (word)))
      (command
        (command_name
          (word))
        (word)))
    (else_clause
      (command
        (command_name
          (word))))))

================================================================================
If statements with conditional expressions
================================================================================

if [ "$(uname)" == 'Darwin' ]; then
  echo one
fi

if [ a = -d ]; then
  echo two
fi

[[ abc == +(a|b|c) ]] && echo 1
[[ abc != +(a|b|c) ]] && echo 2

--------------------------------------------------------------------------------

(program
  (if_statement
    (test_command
      (binary_expression
        (string
          (command_substitution
            (command
              (command_name
                (word)))))
        (raw_string)))
    (command
      (command_name
        (word))
      (word)))
  (if_statement
    (test_command
      (binary_expression
        (word)
        (word)))
    (command
      (command_name
        (word))
      (word)))
  (list
    (test_command
      (binary_expression
        (word)
        (regex)))
    (command
      (command_name
        (word))
      (number)))
  (list
    (test_command
      (binary_expression
        (word)
        (regex)))
    (command
      (command_name
        (word))
      (number))))

================================================================================
If statements with negated command
================================================================================

if ! command -v echo; then
  echo 'hello'
fi

--------------------------------------------------------------------------------

(program
  (if_statement
    condition: (negated_command
      (command
        name: (command_name
          (word))
        argument: (word)
        argument: (word)))
    (command
      name: (command_name
        (word))
      argument: (raw_string))))

================================================================================
If statements with command
================================================================================

if command -v echo; then
  echo 'hello'
fi

--------------------------------------------------------------------------------

(program
  (if_statement
    condition: (command
      name: (command_name
        (word))
      argument: (word)
      argument: (word))
    (command
      name: (command_name
        (word))
      argument: (raw_string))))

================================================================================
If statements with variable assignment by command substitution
================================================================================

if result=$(echo 'hello'); then
  echo 'hello'
fi

--------------------------------------------------------------------------------

(program
  (if_statement
    condition: (variable_assignment
      name: (variable_name)
      value: (command_substitution
        (command
          name: (command_name
            (word))
          argument: (raw_string))))
    (command
      name: (command_name
        (word))
      argument: (raw_string))))

================================================================================
If statements with negated variable assignment by command substitution
================================================================================

if ! result=$(echo 'hello'); then
  echo 'hello'
fi

--------------------------------------------------------------------------------

(program
  (if_statement
    condition: (negated_command
      (variable_assignment
        name: (variable_name)
        value: (command_substitution
          (command
            name: (command_name
              (word))
            argument: (raw_string)))))
    (command
      name: (command_name
        (word))
      argument: (raw_string))))

================================================================================
If statements with variable assignment
================================================================================

if foo=1; then
  echo 'hello'
fi

--------------------------------------------------------------------------------

(program
  (if_statement
    condition: (variable_assignment
      name: (variable_name)
      value: (number))
    (command
      name: (command_name
        (word))
      argument: (raw_string))))

================================================================================
If statements with negated variable assignment
================================================================================

if ! foo=1; then
  echo 'hello'
fi

--------------------------------------------------------------------------------

(program
  (if_statement
    condition: (negated_command
      (variable_assignment
        name: (variable_name)
        value: (number)))
    (command
      name: (command_name
        (word))
      argument: (raw_string))))

================================================================================
Case statements
================================================================================

case "opt" in
  a)
    echo a
    ;;

  b)
    echo b
    ;&

  c)
    echo c;;
esac

case "opt" in
  (a)
    echo a
    ;;

  (b)
    echo b
    ;&

  (c)
    echo c;;
esac

case "$Z" in
  ab*|cd*) ef
esac

case $dest in
  *.[1357])
    exit $?
    ;;
esac

case x in x) echo meow ;; esac

case foo in
  bar\ baz) : ;;
esac

case "$arg" in
  *([0-9])([0-9])) echo "$arg"
esac

--------------------------------------------------------------------------------

(program
  (case_statement
    (string)
    (case_item
      (word)
      (command
        (command_name
          (word))
        (word)))
    (case_item
      (word)
      (command
        (command_name
          (word))
        (word)))
    (case_item
      (word)
      (command
        (command_name
          (word))
        (word))))
  (case_statement
    (string)
    (case_item
      (word)
      (command
        (command_name
          (word))
        (word)))
    (case_item
      (word)
      (command
        (command_name
          (word))
        (word)))
    (case_item
      (word)
      (command
        (command_name
          (word))
        (word))))
  (case_statement
    (string
      (simple_expansion
        (variable_name)))
    (case_item
      (word)
      (word)
      (command
        (command_name
          (word)))))
  (case_statement
    (simple_expansion
      (variable_name))
    (case_item
      (concatenation
        (word)
        (word)
        (number)
        (word))
      (command
        (command_name
          (word))
        (simple_expansion
          (special_variable_name)))))
  (case_statement
    (word)
    (case_item
      (word)
      (command
        (command_name
          (word))
        (word))))
  (case_statement
    (word)
    (case_item
      (word)
      (command
        (command_name
          (word)))))
  (case_statement
    (string
      (simple_expansion
        (variable_name)))
    (case_item
      (extglob_pattern)
      (command
        (command_name
          (word))
        (string
          (simple_expansion
            (variable_name)))))))

================================================================================
Test commands
================================================================================

if [[ "$lsb_dist" != 'Ubuntu' || $(ver_to_int "$lsb_release") < $(ver_to_int '14.04') ]]; then
	return 1
fi

--------------------------------------------------------------------------------

(program
  (if_statement
    (test_command
      (binary_expression
        (binary_expression
          (binary_expression
            (string
              (simple_expansion
                (variable_name)))
            (raw_string))
          (command_substitution
            (command
              (command_name
                (word))
              (string
                (simple_expansion
                  (variable_name))))))
        (command_substitution
          (command
            (command_name
              (word))
            (raw_string)))))
    (command
      (command_name
        (word))
      (number))))

================================================================================
Test commands with ternary
================================================================================

if (( 1 < 2 ? 1 : 2 )); then
	return 1
fi

--------------------------------------------------------------------------------

(program
  (if_statement
    (command
      (command_name
        (arithmetic_expansion
          (ternary_expression
            (binary_expression
              (number)
              (number))
            (number)
            (number)))))
    (command
      (command_name
        (word))
      (number))))

================================================================================
Ternary expressions
================================================================================

$((n < 10 ? n : 10))
$(($n < 10 ? $n : 10))
$((${n} < 10 ? ${n} : 10))

--------------------------------------------------------------------------------

(program
  (command
    (command_name
      (arithmetic_expansion
        (ternary_expression
          (binary_expression
            (variable_name)
            (number))
          (variable_name)
          (number)))))
  (command
    (command_name
      (arithmetic_expansion
        (ternary_expression
          (binary_expression
            (simple_expansion
              (variable_name))
            (number))
          (simple_expansion
            (variable_name))
          (number)))))
  (command
    (command_name
      (arithmetic_expansion
        (ternary_expression
          (binary_expression
            (expansion
              (variable_name))
            (number))
          (expansion
            (variable_name))
          (number))))))

================================================================================
Test commands with regexes
================================================================================

[[ "35d8b" =~ ^[0-9a-fA-F] ]]
[[ $CMD =~ (^|;)update_terminal_cwd($|;) ]]
[[ ! " ${completions[*]} " =~ " $alias_cmd " ]]
! [[ "$a" =~ ^a|b\ *c|d$ ]]
[[ "$1" =~ ^${var}${var}*=..* ]]
[[ "$1" =~ ^\-${var}+ ]]
[[ ${var1} == *${var2}* ]]
[[ "$server" =~ [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} ]]
[[ "$primary_wins" =~ ([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}) ]]

--------------------------------------------------------------------------------

(program
  (test_command
    (binary_expression
      (string)
      (regex)))
  (test_command
    (binary_expression
      (simple_expansion
        (variable_name))
      (regex)))
  (test_command
    (unary_expression
      (binary_expression
        (string
          (expansion
            (subscript
              (variable_name)
              (word))))
        (string
          (simple_expansion
            (variable_name))))))
  (negated_command
    (test_command
      (binary_expression
        (string
          (simple_expansion
            (variable_name)))
        (regex))))
  (test_command
    (binary_expression
      (string
        (simple_expansion
          (variable_name)))
      (regex)))
  (test_command
    (binary_expression
      (string
        (simple_expansion
          (variable_name)))
      (regex)))
  (test_command
    (binary_expression
      (expansion
        (variable_name))
      (regex)))
  (test_command
    (binary_expression
      (string
        (simple_expansion
          (variable_name)))
      (regex)))
  (test_command
    (binary_expression
      (string
        (simple_expansion
          (variable_name)))
      (regex))))

================================================================================
Subshells
================================================================================

(
  ./start-server --port=80
) &

--------------------------------------------------------------------------------

(program
  (subshell
    (command
      (command_name
        (word))
      (word))))

================================================================================
Function definitions
================================================================================

do_something() {
  echo ok
}

run_subshell_command() (
  true
)

run_test_command() [[ -e foo ]]

function do_something_else() {
  a | xargs -I{} find xml/{} -type f
}

function do_yet_another_thing {
  echo ok
} 2>&1

do_nothing() { return 0; }

--------------------------------------------------------------------------------

(program
  (function_definition
    (word)
    (compound_statement
      (command
        (command_name
          (word))
        (word))))
  (function_definition
    (word)
    (subshell
      (command
        (command_name
          (word)))))
  (function_definition
    (word)
    (test_command
      (unary_expression
        (test_operator)
        (word))))
  (function_definition
    (word)
    (compound_statement
      (pipeline
        (command
          (command_name
            (word)))
        (command
          (command_name
            (word))
          (concatenation
            (word)
            (word)
            (word))
          (word)
          (concatenation
            (word)
            (word)
            (word))
          (word)
          (word)))))
  (function_definition
    (word)
    (compound_statement
      (command
        (command_name
          (word))
        (word)))
    (file_redirect
      (file_descriptor)
      (number)))
  (function_definition
    (word)
    (compound_statement
      (command
        (command_name
          (word))
        (number)))))

================================================================================
Variable declaration: declare & typeset
================================================================================

declare var1
typeset -i -r var2=42 var3=10

--------------------------------------------------------------------------------

(program
  (declaration_command
    (variable_name))
  (declaration_command
    (word)
    (word)
    (variable_assignment
      (variable_name)
      (number))
    (variable_assignment
      (variable_name)
      (number))))

================================================================================
Variable declaration: readonly
================================================================================

readonly var1
readonly var2=42

--------------------------------------------------------------------------------

(program
  (declaration_command
    (variable_name))
  (declaration_command
    (variable_assignment
      (variable_name)
      (number))))

================================================================================
Variable declaration: local
================================================================================

local a=42 b
local -r c
local var=word1\ word2

--------------------------------------------------------------------------------

(program
  (declaration_command
    (variable_assignment
      (variable_name)
      (number))
    (variable_name))
  (declaration_command
    (word)
    (variable_name))
  (declaration_command
    (variable_assignment
      (variable_name)
      (word))))

================================================================================
Variable declaration: export
================================================================================

export PATH
export FOOBAR PATH="$PATH:/usr/foobar/bin"

--------------------------------------------------------------------------------

(program
  (declaration_command
    (variable_name))
  (declaration_command
    (variable_name)
    (variable_assignment
      (variable_name)
      (string
        (simple_expansion
          (variable_name))))))

================================================================================
Variable declaration: command substitution with semi-colon
================================================================================

_path=$(
  while statement; do
    cd ".."
  done;
  echo $PWD
)

--------------------------------------------------------------------------------

(program
  (variable_assignment
    (variable_name)
    (command_substitution
      (while_statement
        (command
          (command_name
            (word)))
        (do_group
          (command
            (command_name
              (word))
            (string))))
      (command
        (command_name
          (word))
        (simple_expansion
          (variable_name))))))

===========================================================
Command substution with $ and backticks
===========================================================

$(eval echo $`echo ${foo}`)

---

(program
  (command
    (command_name
      (command_substitution
        (command
          (command_name
            (word))
          (word)
          (command_substitution
            (command
              (command_name
                (word))
              (expansion
                (variable_name)))))))))

================================================================================
Expressions passed to declaration commands
================================================================================

export "$(echo ${key} | tr [:lower:] [:upper:])=${p_key#*=}"

--------------------------------------------------------------------------------

(program
  (declaration_command
    (string
      (command_substitution
        (pipeline
          (command
            (command_name
              (word))
            (expansion
              (variable_name)))
          (command
            (command_name
              (word))
            (concatenation
              (word)
              (word)
              (word))
            (concatenation
              (word)
              (word)
              (word)))))
      (expansion
        (variable_name)
        (regex)))))

================================================================================
Unset commands
================================================================================

unset A
unset "$variable_name"
unsetenv -f ONE TWO

--------------------------------------------------------------------------------

(program
  (unset_command
    (variable_name))
  (unset_command
    (string
      (simple_expansion
        (variable_name))))
  (unset_command
    (word)
    (variable_name)
    (variable_name)))

================================================================================
Compound statements
================================================================================

a () {
    ls || { echo "b"; return 0; }
    echo c
}

{ echo "a"
  echo "b"
} >&2

--------------------------------------------------------------------------------

(program
  (function_definition
    (word)
    (compound_statement
      (list
        (command
          (command_name
            (word)))
        (compound_statement
          (command
            (command_name
              (word))
            (string))
          (command
            (command_name
              (word))
            (number))))
      (command
        (command_name
          (word))
        (word))))
  (redirected_statement
    (compound_statement
      (command
        (command_name
          (word))
        (string))
      (command
        (command_name
          (word))
        (string)))
    (file_redirect
      (number))))
