/// /// Runtime errors - Unquoted test functions /// ===== TEST function: unquoted-ambiguous_redirect ===== echo foo > "$@" ^ test/runtime-errors.sh:543: Can't redirect to zero files ambiguous redirect not fatal unless errexit echo foo > "$@" ^ test/runtime-errors.sh:547: Can't redirect to zero files ----- STATUS: 0 ===== TEST function: unquoted-ambiguous_redirect_context ===== echo $(echo hi > "$@") ^ test/runtime-errors.sh:560: Can't redirect to zero files ambiguous is NOT FATAL in command sub foo=$(echo hi > "$@") ^ test/runtime-errors.sh:564: Can't redirect to zero files ambiguous is NOT FATAL in assignment in command sub echo $(echo hi > "$@") ^ test/runtime-errors.sh:572: Can't redirect to zero files ambiguous is NOT FATAL in command sub, even if errexit But when the command sub is in an assignment, it is fatal foo=$(echo hi > "$@") ^ test/runtime-errors.sh:579: Can't redirect to zero files ----- STATUS: 0 ===== TEST function: unquoted-array_arith ===== 2 2 ----- STATUS: 0 ===== TEST function: unquoted-array_assign_1 ===== s[0]=x # can't assign value ^~ test/runtime-errors.sh:861: fatal: Can't assign to items in a string ----- STATUS: 0 ===== TEST function: unquoted-array_assign_2 ===== ===== CASE: -c readonly -a array=(1 2 3); array[0]=x ===== readonly -a array=(1 2 3); array[0]=x ^~~~~~ [ -c flag ]:1: fatal: Can't assign to readonly array ===== CASE: -c readonly -a array=(1 2 3); export array ===== test/runtime-errors.sh: fatal: Should FAIL under bin/osh: expected status 1, got 0 ----- STATUS: 0 ===== TEST function: unquoted-bad_file_descriptor ===== F_GETFD fd 7: Bad file descriptor test/runtime-errors.sh:585: I/O error applying redirect: Bad file descriptor ----- STATUS: 0 ===== TEST function: unquoted-bad_var_ref ===== bad var name ^ [ contents of var 'name' at line 646 of test/runtime-errors.sh ]:1: Expected end of var ref expression echo ${!name} ^~~~ test/runtime-errors.sh:646: fatal: Invalid var ref expression ----- STATUS: 0 ===== TEST function: unquoted-bool_status ===== if try --allow-status-01 -- myproc; then ^~~~~~~~~~~~~~~~~ test/runtime-errors.sh:616: 'try' got invalid flag '--allow-status-01' no match ----- STATUS: 0 ===== TEST function: unquoted-bool_status_simple ===== if try --allow-status-01 -- grep pat BAD; then ^~~~~~~~~~~~~~~~~ test/runtime-errors.sh:626: 'try' got invalid flag '--allow-status-01' no match ----- STATUS: 0 ===== TEST function: unquoted-builtin_alias_unalias ===== alias zzz ^~~~~ test/runtime-errors.sh:972: No alias named 'zzz' unalias zzz ^~~~~~~ test/runtime-errors.sh:973: No alias named 'zzz' ----- STATUS: 0 ===== TEST function: unquoted-builtin_bracket ===== [ -t xxx ] ^~~ test/runtime-errors.sh:905: (test) Invalid file descriptor 'xxx' [ -t '' ] ^ test/runtime-errors.sh:906: (test) Invalid file descriptor '' [ zz -eq 0 ] ^~ test/runtime-errors.sh:908: (test) Invalid integer constant 'zz' ----- STATUS: 0 ===== TEST function: unquoted-builtin_builtin ===== builtin ls ^~ test/runtime-errors.sh:916: 'ls' isn't a shell builtin ----- STATUS: 0 ===== TEST function: unquoted-builtin_cd ===== cd ^~ test/runtime-errors.sh:928: $HOME isn't defined cd ^~ test/runtime-errors.sh:934: $HOME should be a string cd - ^~ test/runtime-errors.sh:939: $OLDPWD isn't defined ( cd /nonexistent ^ test/runtime-errors.sh:942: cd '/nonexistent': No such file or directory ----- STATUS: 0 ===== TEST function: unquoted-builtin_exec ===== exec nonexistent-command 1 2 3 ^~~~~~~~~~~~~~~~~~~ test/runtime-errors.sh:1035: fatal: exec: 'nonexistent-command' not found ----- STATUS: 0 ===== TEST function: unquoted-builtin_getopts ===== getopts ^~~~~~~ test/runtime-errors.sh:988: 'getopts' requires an argspec getopts 'a:' ^~~~~~~ test/runtime-errors.sh:989: 'getopts' requires the name of a variable to set getopts 'a:' varname ^~~~~~~ test/runtime-errors.sh:993: getopts: option '-a' requires an argument. (getopts argv: -a) ----- STATUS: 0 ===== TEST function: unquoted-builtin_help ===== help zzz ^~~ test/runtime-errors.sh:977: no help topics match 'zzz' ----- STATUS: 0 ===== TEST function: unquoted-builtin_popd ===== popd # empty dir stack ^~~~ test/runtime-errors.sh:951: popd: directory stack is empty ~/oil/_tmp/runtime-error-popd ~/oil / ~/oil/_tmp/runtime-error-popd ~/oil popd ^~~~ test/runtime-errors.sh:959: popd: '/home/uke/oil/_tmp/runtime-error-popd': No such file or directory ----- STATUS: 0 ===== TEST function: unquoted-builtin_pushd ===== pushd /nonexistent ^ test/runtime-errors.sh:947: pushd: '/nonexistent': No such file or directory ----- STATUS: 0 ===== TEST function: unquoted-builtin_source ===== source ^~~~~~ test/runtime-errors.sh:920: 'source' requires a file path source $bad ^~~~ test/runtime-errors.sh:923: source '/nonexistent/path' failed: No such file or directory ----- STATUS: 0 ===== TEST function: unquoted-builtin_trap ===== trap ^~~~ test/runtime-errors.sh:981: 'trap' requires a code string trap EXIT ^~~~ test/runtime-errors.sh:982: 'trap' requires a signal or hook name trap zzz yyy ^~~ test/runtime-errors.sh:984: Invalid signal or hook 'yyy' ----- STATUS: 0 ===== TEST function: unquoted-builtin_unset ===== unset x a ^ test/runtime-errors.sh:967: Can't unset readonly variable 'a' unset -v x a ^ test/runtime-errors.sh:968: Can't unset readonly variable 'a' ----- STATUS: 0 ===== TEST function: unquoted-builtin_wait ===== wait 1234578 ^~~~~~~ test/runtime-errors.sh:1031: 1234578 isn't a child of this shell ----- STATUS: 0 ===== TEST function: unquoted-command_sub_errexit ===== ----- STATUS: 0 ===== TEST function: unquoted-multiple_assign ===== a=1 b=2 x=42 ^~ test/runtime-errors.sh:882: fatal: Can't assign to readonly value 'x' ----- STATUS: 0 ===== TEST function: unquoted-multiple_assign_2 ===== 0 ----- STATUS: 0 ===== TEST function: unquoted-no_such_command_heredoc ===== $(ZZZZZ) ^~~~~ test/runtime-errors.sh:101: 'ZZZZZ' not found (OILS-ERR-100) one three SHOULD NOT GET HERE ----- STATUS: 0 ===== TEST function: unquoted-nounset ===== echo $x ^~ test/runtime-errors.sh:639: fatal: Undefined variable 'x' ----- STATUS: 0 ===== TEST function: unquoted-nounset_arith ===== echo $(( x )) ^ test/runtime-errors.sh:655: fatal: Undefined variable 'x' ----- STATUS: 0 ===== TEST function: unquoted-patsub_bad_glob ===== echo ${x//[^]} ^ test/runtime-errors.sh:811: fatal: Error matching regex '([^])': Unmatched [, [^, [:, [., or [= ----- STATUS: 0 ===== TEST function: unquoted-pipefail ===== 0 0 ----- STATUS: 0 ===== TEST function: unquoted-pipefail_func ===== 1 1 3 ----- STATUS: 0 ===== TEST function: unquoted-pipefail_group ===== 1 1 3 ----- STATUS: 0 ===== TEST function: unquoted-pipefail_multiple ===== six ----- STATUS: 0 ===== TEST function: unquoted-pipefail_no_words ===== seq 3 | wc -l | > /nonexistent ^ test/runtime-errors.sh:444: Can't open '/nonexistent': Permission denied test/runtime-errors.sh:444: I/O error applying redirect: Permission denied ----- STATUS: 0 ===== TEST function: unquoted-pipefail_subshell ===== 1 1 3 ----- STATUS: 0 ===== TEST function: unquoted-pipefail_while ===== 2 6 12 ----- STATUS: 0 ===== TEST function: unquoted-process_sub_fail ===== a b ----- STATUS: 0 ===== TEST function: unquoted-readonly_assign ===== ===== CASE: -c readonly x=1; x=2 ===== readonly x=1; x=2 ^~ [ -c flag ]:1: fatal: Can't assign to readonly value 'x' ===== CASE: -c readonly x=2; y=3 x=99 ===== readonly x=2; y=3 x=99 ^~ [ -c flag ]:1: fatal: Can't assign to readonly value 'x' ===== CASE: -c readonly x=2; declare x=99 ===== readonly x=2; declare x=99 ^~ [ -c flag ]:1: fatal: Can't assign to readonly value 'x' ===== CASE: -c readonly x=2; export x=99 ===== readonly x=2; export x=99 ^~ [ -c flag ]:1: fatal: Can't assign to readonly value 'x' ----- STATUS: 0 ===== TEST function: unquoted-strict_arith_warnings ===== 1 -yy- ^ test/runtime-errors.sh:1: Unexpected end of input -yy- ^ test/runtime-errors.sh:1: fatal: Parse error in recursive arithmetic ----- STATUS: 0 ===== TEST function: unquoted-strict_array ===== echo foo > _tmp/"$@" ^~~~ test/runtime-errors.sh:831: Can't redirect to more than one file echo foo > _tmp/"$@" ^~~~ test/runtime-errors.sh:833: Can't redirect to more than one file ----- STATUS: 0 ===== TEST function: unquoted-strict_array_2 ===== local foo="$@" ^ test/runtime-errors.sh:839: fatal: This word should yield a string, but it contains an array ----- STATUS: 0 ===== TEST function: unquoted-strict_array_3 ===== local foo=${1:- "[$@]" } ^~ test/runtime-errors.sh:845: fatal: This word should yield a string, but it contains an array ----- STATUS: 0 ===== TEST function: unquoted-strict_array_4 ===== x[42] = 99 ----- STATUS: 0 ===== TEST function: unquoted-strict_word_eval_warnings ===== slice start negative -bc- slice length negative -- slice bad utf-8 [??? no location ???] warning: UTF-8 decode: Bad encoding at offset 0 in string of 6 bytes -- length bad utf-8 echo ${#s} ^ test/runtime-errors.sh:1062: warning: UTF-8 decode: Bad encoding at offset 0 in string of 6 bytes -1 ----- STATUS: 0 ===== TEST function: unquoted-string_as_array ===== foo foo ----- STATUS: 0 ===== TEST function: unquoted-string_to_hex ===== echo $(( 0xGG + 1 )) ^ test/runtime-errors.sh:710: fatal: Invalid integer constant '0xGG' ----- STATUS: 0 ===== TEST function: unquoted-string_to_int_arith ===== 5 ZZZ ^~~ test/runtime-errors.sh:1: fatal: Undefined value in arithmetic context ----- STATUS: 0 ===== TEST function: unquoted-string_to_int_bool ===== a ^ test/runtime-errors.sh:1: fatal: Undefined value in arithmetic context ----- STATUS: 0 ===== TEST function: unquoted-string_to_intbase ===== 0 SHOULD NOT GET HERE ----- STATUS: 0 ===== TEST function: unquoted-string_to_octal ===== echo $(( 018 + 1 )) ^~~ test/runtime-errors.sh:717: fatal: Invalid integer constant '018' ----- STATUS: 0 ===== TEST function: unquoted-undef-assoc-array ===== bar ['bar', '11'] ['bar', '16'] ----- STATUS: 0 ===== TEST function: unquoted-undef_arith ===== (( undef[42]++ )) ^~ test/runtime-errors.sh:733: fatal: Can't use [] on value of type Str ----- STATUS: 0 ===== TEST function: unquoted-undef_arith2 ===== ['2'] ----- STATUS: 0 test/runtime-errors.sh: 53 unquoted functions run. TODO: migrate to test-* to assert status /// /// Runtime errors - test functions /// *** Running test-FAIL ===== CASE: -c echo hi > /zzz ===== echo hi > /zzz ^ [ -c flag ]:1: Can't open '/zzz': Permission denied [ -c flag ]:1: I/O error applying redirect: Permission denied OK test-FAIL *** Running test-arith_ops_str ===== CASE: -c = "100" + "10a" ===== = "100" + "10a" ^ [ -c flag ]:1: fatal: Binary operator expected numbers, got Str and Str (OILS-ERR-201) ===== CASE: -c = "100" - "10a" ===== = "100" - "10a" ^ [ -c flag ]:1: fatal: Binary operator expected numbers, got Str and Str (OILS-ERR-201) ===== CASE: -c = "100" * "10a" ===== = "100" * "10a" ^ [ -c flag ]:1: fatal: Binary operator expected numbers, got Str and Str (OILS-ERR-201) ===== CASE: -c = "100" / "10a" ===== = "100" / "10a" ^ [ -c flag ]:1: fatal: Binary operator expected numbers, got Str and Str (OILS-ERR-201) ===== CASE: -c var a = "100"; setvar a += "10a" ===== var a = "100"; setvar a += "10a" ^~ [ -c flag ]:1: fatal: Binary operator expected numbers, got Str and Str (OILS-ERR-201) ===== CASE: -c var a = "100"; setvar a -= "10a" ===== var a = "100"; setvar a -= "10a" ^~ [ -c flag ]:1: fatal: Binary operator expected numbers, got Str and Str (OILS-ERR-201) ===== CASE: -c var a = "100"; setvar a *= "10a" ===== var a = "100"; setvar a *= "10a" ^~ [ -c flag ]:1: fatal: Binary operator expected numbers, got Str and Str (OILS-ERR-201) ===== CASE: -c var a = "100"; setvar a /= "10a" ===== var a = "100"; setvar a /= "10a" ^~ [ -c flag ]:1: fatal: Binary operator expected numbers, got Str and Str (OILS-ERR-201) ===== CASE: -c = "age: " + "100" ===== = "age: " + "100" ^ [ -c flag ]:1: fatal: Binary operator expected numbers, got Str and Str (OILS-ERR-201) ===== CASE: -c var myvar = "a string" = 100 + myvar ===== = 100 + myvar ^ [ -c flag ]:2: fatal: Binary operator expected numbers, got Int and Str (OILS-ERR-201) OK test-arith_ops_str *** Running test-assoc-array ===== CASE: -c declare -A assoc; assoc[x]=1 ===== declare -A assoc; assoc[x]=1 ^~~~~~ [ -c flag ]:1: fatal: Assoc array keys must be strings: $x 'x' "$x" etc. (OILS-ERR-101) ===== CASE: -c declare -A assoc; assoc[$key]=1 ===== ===== CASE: -c declare -A assoc; assoc["x"]=1 ===== ===== CASE: -c declare -A assoc; assoc['x']=1 ===== ===== CASE: -c declare -A assoc; echo ${assoc[x]} ===== declare -A assoc; echo ${assoc[x]} ^ [ -c flag ]:1: fatal: Assoc array keys must be strings: $x 'x' "$x" etc. (OILS-ERR-101) ===== CASE: -c declare -A assoc; echo ${assoc["x"]} ===== ===== CASE: -c declare -A assoc; echo ${assoc[$key]} ===== ===== CASE: -c declare -A assoc; key=k; unset assoc[$key] ===== assoc[k] ^ [ dynamic LHS at line 1 of [ -c flag ] ]:1 declare -A assoc; key=k; unset assoc[$key] ^~~~~~ [ -c flag ]:1: fatal: Assoc array keys must be strings: $x 'x' "$x" etc. (OILS-ERR-101) ===== CASE: -c declare -A assoc; key=k; unset "assoc[$key]" ===== assoc[k] ^ [ dynamic LHS at line 1 of [ -c flag ] ]:1 declare -A assoc; key=k; unset "assoc[$key]" ^ [ -c flag ]:1: fatal: Assoc array keys must be strings: $x 'x' "$x" etc. (OILS-ERR-101) ===== CASE: -c declare -A assoc; key=k; unset "assoc[$key]" ===== assoc[k] ^ [ dynamic LHS at line 1 of [ -c flag ] ]:1 declare -A assoc; key=k; unset "assoc[$key]" ^ [ -c flag ]:1: fatal: Assoc array keys must be strings: $x 'x' "$x" etc. (OILS-ERR-101) ===== CASE: -c declare -A assoc; key=k; unset 'assoc[$key]' ===== ===== CASE: -c eval 'declare -A assoc; assoc[x]=1' ===== declare -A assoc; assoc[x]=1 ^~~~~~ [ eval arg at line 1 of [ -c flag ] ]:1 eval 'declare -A assoc; assoc[x]=1' ^~~~ [ -c flag ]:1: fatal: Assoc array keys must be strings: $x 'x' "$x" etc. (OILS-ERR-101) ===== CASE: -c eval 'declare -A assoc; unset "assoc[x]"' ===== assoc[x] ^ [ dynamic LHS at line 1 of [ eval arg at line 1 of [ -c flag ] ] ]:1 declare -A assoc; unset "assoc[x]" ^ [ eval arg at line 1 of [ -c flag ] ]:1 eval 'declare -A assoc; unset "assoc[x]"' ^~~~ [ -c flag ]:1: fatal: Assoc array keys must be strings: $x 'x' "$x" etc. (OILS-ERR-101) OK test-assoc-array *** Running test-command-not-found ===== CASE: -c findz ===== findz ^~~~~ [ -c flag ]:1: 'findz' not found (OILS-ERR-100) OK test-command-not-found *** Running test-control_flow ===== CASE: -c break continue echo UNREACHABLE ===== break ^~~~~ [ -c flag ]:2: warning: Invalid control flow at top level continue ^~~~~~~~ [ -c flag ]:3: warning: Invalid control flow at top level UNREACHABLE ===== CASE: -c shopt -s strict_control_flow break continue echo UNREACHABLE ===== break ^~~~~ [ -c flag ]:3: fatal: Invalid control flow at top level OK test-control_flow *** Running test-control_flow_subshell ===== CASE: -c set -o errexit for i in $(seq 2); do echo $i ( break; echo oops) done ===== 1 ( break; echo oops) ^~~~~ [ -c flag ]:5: Loop and control flow can't be in different processes OK test-control_flow_subshell *** Running test-core-state ===== CASE: -c HOME=(a b) ===== ===== CASE: -c shopt --set strict_array; HOME=(a b) ===== shopt --set strict_array; HOME=(a b) ^~~~~ [ -c flag ]:1: fatal: Only strings can be exported (strict_array) OK test-core-state *** Running test-core_process ===== CASE: -c echo foo > not/a/file echo foo > /etc/no-perms-for-this ===== echo foo > not/a/file ^ [ -c flag ]:2: Can't open 'not/a/file': No such file or directory [ -c flag ]:2: I/O error applying redirect: No such file or directory echo foo > /etc/no-perms-for-this ^ [ -c flag ]:3: Can't open '/etc/no-perms-for-this': Permission denied [ -c flag ]:3: I/O error applying redirect: Permission denied OK test-core_process *** Running test-divzero ===== CASE: -c echo $(( 1 / 0 )) ===== echo $(( 1 / 0 )) ^ [ -c flag ]:1: fatal: Divide by zero ===== CASE: -c echo $(( 1 / (3 -3 ) )) ===== echo $(( 1 / (3 -3 ) )) ^ [ -c flag ]:1: fatal: Divide by zero ===== CASE: -c echo $(( 1 % 0 )) ===== echo $(( 1 % 0 )) ^ [ -c flag ]:1: fatal: Divide by zero ===== CASE: -c zero=0; echo $(( 1 / zero )) ===== zero=0; echo $(( 1 / zero )) ^ [ -c flag ]:1: fatal: Divide by zero ===== CASE: -c zero=0; echo $(( 1 % zero )) ===== zero=0; echo $(( 1 % zero )) ^ [ -c flag ]:1: fatal: Divide by zero ===== CASE: -c (( a = 1 / 0 )); echo non-fatal; exit 1 ===== (( a = 1 / 0 )); echo non-fatal; exit 1 ^ [ -c flag ]:1: fatal: Divide by zero ===== CASE: -c (( a = 1 % 0 )); echo non-fatal; exit 1 ===== (( a = 1 % 0 )); echo non-fatal; exit 1 ^ [ -c flag ]:1: fatal: Divide by zero ===== CASE: -c set -e; (( a = 1 / 0 )); ===== set -e; (( a = 1 / 0 )); ^ [ -c flag ]:1: fatal: Divide by zero ===== CASE: -c set -e; (( a = 1 % 0 )); ===== set -e; (( a = 1 % 0 )); ^ [ -c flag ]:1: fatal: Divide by zero OK test-divzero *** Running test-errexit-multiple-processes ===== CASE: -c echo t=$(true) f=$(false; true) ===== echo t=$(true) f=$(false; true) ^~~~~ [ -c flag ]:1: errexit PID 5630: command.Simple failed with status 1 [ -c flag ]:1: errexit PID 5626: Command Sub exited with status 1 --------------------------- ===== CASE: -c ls | false | wc -l ===== ls | false | wc -l ^~~~~ [ -c flag ]:1: errexit PID 5635: command.Simple failed with status 1 0 ls | false | wc -l ^~~~~ [ -c flag ]:1: errexit PID 5631: command.Pipeline failed with status 1 --------------------------- ===== CASE: -c ls | { echo hi; ( exit 42 ); } | wc -l; echo ===== 1 ls | { echo hi; ( exit 42 ); } | wc -l; echo ^ [ -c flag ]:1: errexit PID 5637: command.Pipeline failed with status 42 --------------------------- ===== CASE: -c { echo one; ( exit 42 ); } |\ { false; wc -l; } ===== { false; wc -l; } ^~~~~ [ -c flag ]:2: errexit PID 5643: command.Simple failed with status 1 { false; wc -l; } ^ [ -c flag ]:2: errexit PID 5643: command.Pipeline failed with status 1 --------------------------- ===== CASE: -c { ls; false; } \ | wc -l ===== { ls; false; } \ ^~~~~ [ -c flag ]:1: errexit PID 5650: command.Simple failed with status 1 63 { ls; false; } \ ^ [ -c flag ]:1: errexit PID 5647: command.Pipeline failed with status 1 --------------------------- ===== CASE: -c { ls; ( false; true ); } | wc -l; echo hi ===== { ls; ( false; true ); } | wc -l; echo hi ^~~~~ [ -c flag ]:1: errexit PID 5656: command.Simple failed with status 1 63 { ls; ( false; true ); } | wc -l; echo hi ^ [ -c flag ]:1: errexit PID 5653: command.Pipeline failed with status 1 --------------------------- ===== CASE: -c ls <(sort YY) <(zz); echo hi ===== sort: cannot read: YY: No such file or directory ls <(sort YY) <(zz); echo hi ^~ [ -c flag ]:1: 'zz' not found (OILS-ERR-100) [ -c flag ]:1: errexit PID 5663: command.Simple failed with status 127 /dev/fd/4 /dev/fd/5 ls <(sort YY) <(zz); echo hi ^~ [ -c flag ]:1: errexit PID 5659: command.Simple failed with status 127 --------------------------- ===== CASE: -c zz <(sort YY) <(sort ZZ); echo hi ===== zz <(sort YY) <(sort ZZ); echo hi ^~ [ -c flag ]:1: 'zz' not found (OILS-ERR-100) sort: cannot read: YY: No such file or directory sort: cannot read: ZZ: No such file or directory [ -c flag ]:1: errexit PID 5665: command.Simple failed with status 127 --------------------------- ===== CASE: -c yy | zz ===== yy | zz ^~ [ -c flag ]:1: 'zz' not found (OILS-ERR-100) yy | zz ^~ [ -c flag ]:1: 'yy' not found (OILS-ERR-100) [ -c flag ]:1: errexit PID 5670: command.Simple failed with status 127 [ -c flag ]:1: errexit PID 5673: command.Simple failed with status 127 yy | zz ^~ [ -c flag ]:1: errexit PID 5670: command.Pipeline failed with status 127 --------------------------- ===== CASE: -c shopt -s ysh:upgrade; echo $([[ 0 -eq 1 ]]) ===== shopt -s ysh:upgrade; echo $([[ 0 -eq 1 ]]) ^~ [ -c flag ]:1: errexit PID 5677: command.DBracket failed with status 1 [ -c flag ]:1: errexit PID 5674: Command Sub exited with status 1 --------------------------- ===== CASE: -c shopt -s ysh:upgrade; var y = $([[ 0 -eq 1 ]]) ===== shopt -s ysh:upgrade; var y = $([[ 0 -eq 1 ]]) ^~ [ -c flag ]:1: errexit PID 5681: command.DBracket failed with status 1 [ -c flag ]:1: errexit PID 5678: Command Sub exited with status 1 OK test-errexit-multiple-processes *** Running test-errexit-one-process ===== CASE: -c zz ===== zz ^~ [ -c flag ]:1: 'zz' not found (OILS-ERR-100) [ -c flag ]:1: errexit PID 5685: command.Simple failed with status 127 --------------------------- ===== CASE: -c echo hi > "" ===== echo hi > "" ^ [ -c flag ]:1: Can't open '': No such file or directory [ -c flag ]:1: I/O error applying redirect: No such file or directory [ -c flag ]:1: errexit PID 5688: command.Redirect failed with status 1 --------------------------- ===== CASE: -c shopt -s failglob; echo *.ZZZZ ===== shopt -s failglob; echo *.ZZZZ ^ [ -c flag ]:1: failglob: Pattern '*.ZZZZ' matched no files [ -c flag ]:1: errexit PID 5691: command.Simple failed with status 1 --------------------------- ===== CASE: -c cd /x ===== cd /x ^ [ -c flag ]:1: cd '/x': No such file or directory cd /x ^~ [ -c flag ]:1: errexit PID 5694: command.Simple failed with status 1 --------------------------- ===== CASE: -c ./README.md; echo hi ===== ./README.md; echo hi ^ [ -c flag ]:1: Can't execute './README.md': Permission denied ./README.md; echo hi ^ [ -c flag ]:1: errexit PID 5697: command.Simple failed with status 126 ===== CASE: -c ls /x; echo $? ===== ls: cannot access '/x': No such file or directory ls /x; echo $? ^~ [ -c flag ]:1: errexit PID 5701: command.Simple failed with status 2 --------------------------- ===== CASE: -c declare cmd=ls; $cmd /x; echo $? ===== ls: cannot access '/x': No such file or directory declare cmd=ls; $cmd /x; echo $? ^~~~ [ -c flag ]:1: errexit PID 5705: command.Simple failed with status 2 --------------------------- ===== CASE: -c echo $undef ===== echo $undef ^~~~~~ [ -c flag ]:1: fatal: Undefined variable 'undef' --------------------------- ===== CASE: -c eval "(" echo status=$? eval ")" echo status=$? set -e; shopt -s verbose_errexit false echo DONE ===== ( ^ [ eval arg at line 2 of [ -c flag ] ]:1 eval "(" ^~~~ [ -c flag ]:2: Unexpected EOF while parsing command status=2 ) ^ [ eval arg at line 5 of [ -c flag ] ]:1 eval ")" ^~~~ [ -c flag ]:5: Invalid word while parsing command status=2 false ^~~~~ [ -c flag ]:9: errexit PID 5712: command.Simple failed with status 1 --------------------------- ===== CASE: -c shopt --set ysh:upgrade; [[ 0 -eq 1 ]] ===== shopt --set ysh:upgrade; [[ 0 -eq 1 ]] ^~ [ -c flag ]:1: errexit PID 5715: command.DBracket failed with status 1 ===== CASE: -c [[ 0 -eq 1 ]] ===== [[ 0 -eq 1 ]] ^~ [ -c flag ]:1: Bash [[ not allowed in YSH (parse_dbracket) --------------------------- ===== CASE: -c shopt --set ysh:upgrade; (( 0 )) ===== shopt --set ysh:upgrade; (( 0 )) ^~ [ -c flag ]:1: errexit PID 5721: command.DParen failed with status 1 ===== CASE: -c (( 0 )) ===== (( 0 )) ^~ [ -c flag ]:1: Bash (( not allowed in YSH (parse_dparen, see OILS-ERR-14 for wart) OK test-errexit-one-process *** Running test-errexit_alias ===== CASE: -c set -o errexit; type foo; foo /nonexistent ===== foo: not found OK test-errexit_alias *** Running test-errexit_dbracket ===== CASE: -c set -o errexit; [[ -n "" ]]; echo UNREACHABLE ===== OK test-errexit_dbracket *** Running test-errexit_subshell ===== CASE: -c set -o errexit; ( echo subshell; exit 42; ) ===== subshell OK test-errexit_subshell *** Running test-errexit_usage_error ===== CASE: -c set -o errexit; type -z ===== set -o errexit; type -z ^~ [ -c flag ]:1: 'type' doesn't accept flag -z OK test-errexit_usage_error *** Running test-eval_bad_syntax ===== CASE: -c code="if foo; echo ls; fi" eval "echo -- $code" ===== -- if foo; echo ls; fi ^~ [ eval arg at line 3 of [ -c flag ] ]:2 eval "echo -- ^~~~ [ -c flag ]:3: Expected word type Id.KW_Then, got Id.KW_Fi OK test-eval_bad_syntax *** Running test-external_cmd_typed_args ===== CASE: -c cat ("myfile") ===== cat ("myfile") ^ [ -c flag ]:1: fatal: 'cat' appears to be external. External commands don't accept typed args (OILS-ERR-200) OK test-external_cmd_typed_args *** Running test-failed_command ===== CASE: -c set -o errexit; false; echo UNREACHABLE ===== OK test-failed_command *** Running test-fallback-locations ===== CASE: -c echo hi > / ===== echo hi > / ^ [ -c flag ]:1: Can't open '/': Is a directory [ -c flag ]:1: I/O error applying redirect: Is a directory ===== CASE: -c s=x; (( s[0] )) ===== ===== CASE: -c s=x; (( s[0] = 42 )) ===== s=x; (( s[0] = 42 )) ^ [ -c flag ]:1: fatal: Can't assign to items in a string ===== CASE: -c set -u; (( undef )) ===== set -u; (( undef )) ^~~~~ [ -c flag ]:1: fatal: Undefined variable 'undef' ===== CASE: -c (( 3 ** -2 )) ===== (( 3 ** -2 )) ^ [ -c flag ]:1: fatal: Exponent can't be a negative number ===== CASE: -c set -u; [[ $undef =~ . ]] ===== set -u; [[ $undef =~ . ]] ^~~~~~ [ -c flag ]:1: fatal: Undefined variable 'undef' ===== CASE: -c [[ $x =~ $(( 3 ** -2 )) ]] ===== [[ $x =~ $(( 3 ** -2 )) ]] ^ [ -c flag ]:1: fatal: Exponent can't be a negative number ===== CASE: -c type -x ===== type -x ^~ [ -c flag ]:1: 'type' doesn't accept flag -x ===== CASE: -c use ===== use ^~~ [ -c flag ]:1: 'use' requires a module path ===== CASE: -c export -f ===== export -f ^~~~~~ [ -c flag ]:1: 'export' doesn't accept -f because it's dangerous. (The code can usually be restructured with 'source') ===== CASE: -c s=$(true) y=$(( 3 ** -2 )) ===== s=$(true) y=$(( 3 ** -2 )) ^ [ -c flag ]:1: fatal: Exponent can't be a negative number ===== CASE: -c if s=$(true) y=$(( 3 ** -2 )); then echo hi; fi ===== if s=$(true) y=$(( 3 ** -2 )); then echo hi; fi ^ [ -c flag ]:1: fatal: Exponent can't be a negative number ===== CASE: -c shopt -s strict_arith; x=a; echo $(( x )) ===== a ^ [ -c flag ]:1: fatal: Undefined value in arithmetic context ===== CASE: -c shopt -s strict_arith; x=a; echo $(( $x )) ===== a ^ [ -c flag ]:1: fatal: Undefined value in arithmetic context ===== CASE: -c shopt -s strict_arith; x=a; [[ $x -gt 3 ]] ===== a ^ [ -c flag ]:1: fatal: Undefined value in arithmetic context ===== CASE: -c shopt -s strict_arith; shopt -u eval_unsafe_arith; x=a; [[ $x -gt 3 ]] ===== a ^ [ -c flag ]:1: fatal: Undefined value in arithmetic context ===== CASE: -c shopt -s strict_arith; x=0xgg; echo $(( x )) ===== shopt -s strict_arith; x=0xgg; echo $(( x )) ^ [ -c flag ]:1: fatal: Invalid integer constant '0xgg' done OK test-fallback-locations *** Running test-long-shell-line ===== CASE: -c myvar=$(printf "what a very long string that we have here, which forces the command line to wrap around the terminal width. long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long") && echo $myvar ===== myvar=$(printf "what a very long string that we have here, which forces the command line to wrap around the terminal width. long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long long") && echo $myvar ^~~~~~ [ -c flag ]:1: fatal: strict_errexit only allows simple commands in conditionals (got command.ShAssignment). OK test-long-shell-line *** Running test-no_such_command ===== CASE: -c set -o errexit; ZZZZZ; echo UNREACHABLE ===== set -o errexit; ZZZZZ; echo UNREACHABLE ^~~~~ [ -c flag ]:1: 'ZZZZZ' not found (OILS-ERR-100) OK test-no_such_command *** Running test-no_such_command_commandsub ===== CASE: -c set -o errexit; echo $(ZZZZZ); echo UNREACHABLE ===== set -o errexit; echo $(ZZZZZ); echo UNREACHABLE ^~~~~ [ -c flag ]:1: 'ZZZZZ' not found (OILS-ERR-100) UNREACHABLE ===== CASE: -c set -o errexit; shopt -s command_sub_errexit; echo $(ZZZZZ); echo UNREACHABLE ===== set -o errexit; shopt -s command_sub_errexit; echo $(ZZZZZ); echo UNREACHABLE ^~~~~ [ -c flag ]:1: 'ZZZZZ' not found (OILS-ERR-100) OK test-no_such_command_commandsub *** Running test-source_bad_syntax ===== CASE: -c . _tmp/bad-syntax.sh ===== if foo; echo ls; fi ^~ _tmp/bad-syntax.sh:1: Expected word type Id.KW_Then, got Id.KW_Fi OK test-source_bad_syntax *** Running test-strict-arith ===== CASE: -c shopt -s strict_arith; echo $(( undef[0] )) ===== shopt -s strict_arith; echo $(( undef[0] )) ^ [ -c flag ]:1: fatal: Value of type Undef can't be indexed (strict_arith) ===== CASE: -c shopt -s strict_arith; s=abc; echo $(( s[0] )) ===== shopt -s strict_arith; s=abc; echo $(( s[0] )) ^ [ -c flag ]:1: fatal: Value of type Str can't be indexed (strict_arith) ===== CASE: -c shopt -s strict_arith; var i = 42; echo $(( i[0] )) ===== shopt -s strict_arith; var i = 42; echo $(( i[0] )) ^ [ -c flag ]:1: fatal: Value of type Int can't be indexed OK test-strict-arith *** Running test-strict-errexit-old ===== CASE: [strict_errexit] if ls | wc -l; then echo Pipeline; fi ===== ===== CASE: -c set -o errexit; shopt -s strict_errexit; if ls | wc -l; then echo Pipeline; fi ===== set -o errexit; shopt -s strict_errexit; if ls | wc -l; then echo Pipeline; fi ^ [ -c flag ]:1: fatal: strict_errexit only allows simple commands in conditionals (got command.Sentence). ===== CASE: [strict_errexit] if ! ls | wc -l; then echo Pipeline; fi ===== ===== CASE: -c set -o errexit; shopt -s strict_errexit; if ! ls | wc -l; then echo Pipeline; fi ===== set -o errexit; shopt -s strict_errexit; if ! ls | wc -l; then echo Pipeline; fi ^ [ -c flag ]:1: fatal: strict_errexit only allows simple commands in conditionals (got command.Sentence). ===== CASE: [strict_errexit] ! for x in a; do echo $x; done ===== ===== CASE: -c set -o errexit; shopt -s strict_errexit; ! for x in a; do echo $x; done ===== set -o errexit; shopt -s strict_errexit; ! for x in a; do echo $x; done ^ [ -c flag ]:1: fatal: strict_errexit only allows simple commands in conditionals (got command.Pipeline). ===== CASE: [strict_errexit] _func() { echo; }; ! _func ===== ===== CASE: -c set -o errexit; shopt -s strict_errexit; _func() { echo; }; ! _func ===== set -o errexit; shopt -s strict_errexit; _func() { echo; }; ! _func ^ [ -c flag ]:1: errexit was disabled for this construct set -o errexit; shopt -s strict_errexit; _func() { echo; }; ! _func ^~~~~ [ -c flag ]:1: fatal: Can't run a proc while errexit is disabled. Use 'try' or wrap it in a process with $0 myproc ===== CASE: [strict_errexit] ! { echo brace; }; echo "should not get here" ===== ===== CASE: -c set -o errexit; shopt -s strict_errexit; ! { echo brace; }; echo "should not get here" ===== set -o errexit; shopt -s strict_errexit; ! { echo brace; }; echo "should not get here" ^ [ -c flag ]:1: fatal: strict_errexit only allows simple commands in conditionals (got command.Pipeline). ===== CASE: [strict_errexit] ! ( echo subshell ); echo "should not get here" ===== ===== CASE: -c set -o errexit; shopt -s strict_errexit; ! ( echo subshell ); echo "should not get here" ===== set -o errexit; shopt -s strict_errexit; ! ( echo subshell ); echo "should not get here" ^ [ -c flag ]:1: fatal: strict_errexit only allows simple commands in conditionals (got command.Pipeline). ===== CASE: [strict_errexit] ! while false; do echo while; done; echo "should not get here" ===== ===== CASE: -c set -o errexit; shopt -s strict_errexit; ! while false; do echo while; done; echo "should not get here" ===== set -o errexit; shopt -s strict_errexit; ! while false; do echo while; done; echo "should not get here" ^ [ -c flag ]:1: fatal: strict_errexit only allows simple commands in conditionals (got command.Pipeline). ===== CASE: [strict_errexit] ! if true; then false; fi; echo "should not get here" ===== ===== CASE: -c set -o errexit; shopt -s strict_errexit; ! if true; then false; fi; echo "should not get here" ===== set -o errexit; shopt -s strict_errexit; ! if true; then false; fi; echo "should not get here" ^ [ -c flag ]:1: fatal: strict_errexit only allows simple commands in conditionals (got command.Pipeline). ===== CASE: [strict_errexit] ! case x in x) echo x;; esac; echo "should not get here" ===== ===== CASE: -c set -o errexit; shopt -s strict_errexit; ! case x in x) echo x;; esac; echo "should not get here" ===== set -o errexit; shopt -s strict_errexit; ! case x in x) echo x;; esac; echo "should not get here" ^ [ -c flag ]:1: fatal: strict_errexit only allows simple commands in conditionals (got command.Pipeline). ===== CASE: [strict_errexit] ! time echo hi; echo "should not get here" ===== ===== CASE: -c set -o errexit; shopt -s strict_errexit; ! time echo hi; echo "should not get here" ===== set -o errexit; shopt -s strict_errexit; ! time echo hi; echo "should not get here" ^ [ -c flag ]:1: fatal: strict_errexit only allows simple commands in conditionals (got command.Pipeline). ===== CASE: [strict_errexit] ! echo $(echo hi); echo "should not get here" ===== ===== CASE: -c set -o errexit; shopt -s strict_errexit; ! echo $(echo hi); echo "should not get here" ===== set -o errexit; shopt -s strict_errexit; ! echo $(echo hi); echo "should not get here" ^~ [ -c flag ]:1: fatal: Command subs not allowed here because status wouldn't be checked (strict_errexit) OK test-strict-errexit-old *** Running test-strict_errexit_1 ===== CASE: [strict_errexit] ! { echo 1; echo 2; } ===== ===== CASE: -c set -o errexit; shopt -s strict_errexit; ! { echo 1; echo 2; } ===== set -o errexit; shopt -s strict_errexit; ! { echo 1; echo 2; } ^ [ -c flag ]:1: fatal: strict_errexit only allows simple commands in conditionals (got command.Pipeline). ===== CASE: [strict_errexit] { echo 1; echo 2; } && true ===== ===== CASE: -c set -o errexit; shopt -s strict_errexit; { echo 1; echo 2; } && true ===== set -o errexit; shopt -s strict_errexit; { echo 1; echo 2; } && true ^ [ -c flag ]:1: fatal: strict_errexit only allows simple commands in conditionals (got command.BraceGroup). ===== CASE: [strict_errexit] { echo 1; echo 2; } || true ===== ===== CASE: -c set -o errexit; shopt -s strict_errexit; { echo 1; echo 2; } || true ===== set -o errexit; shopt -s strict_errexit; { echo 1; echo 2; } || true ^ [ -c flag ]:1: fatal: strict_errexit only allows simple commands in conditionals (got command.BraceGroup). ===== CASE: [strict_errexit] { echo 1; echo 2; } && true && true ===== ===== CASE: -c set -o errexit; shopt -s strict_errexit; { echo 1; echo 2; } && true && true ===== set -o errexit; shopt -s strict_errexit; { echo 1; echo 2; } && true && true ^ [ -c flag ]:1: fatal: strict_errexit only allows simple commands in conditionals (got command.BraceGroup). ===== CASE: [strict_errexit] true && { echo 1; echo 2; } || true || true ===== ===== CASE: -c set -o errexit; shopt -s strict_errexit; true && { echo 1; echo 2; } || true || true ===== set -o errexit; shopt -s strict_errexit; true && { echo 1; echo 2; } || true || true ^ [ -c flag ]:1: fatal: strict_errexit only allows simple commands in conditionals (got command.BraceGroup). ===== CASE: [strict_errexit] true && true && { echo 1; echo 2; } || true || true ===== ===== CASE: -c set -o errexit; shopt -s strict_errexit; true && true && { echo 1; echo 2; } || true || true ===== set -o errexit; shopt -s strict_errexit; true && true && { echo 1; echo 2; } || true || true ^ [ -c flag ]:1: fatal: strict_errexit only allows simple commands in conditionals (got command.BraceGroup). ===== CASE: [strict_errexit] if { echo 1; echo 2; }; then echo IF; fi ===== ===== CASE: -c set -o errexit; shopt -s strict_errexit; if { echo 1; echo 2; }; then echo IF; fi ===== set -o errexit; shopt -s strict_errexit; if { echo 1; echo 2; }; then echo IF; fi ^ [ -c flag ]:1: fatal: strict_errexit only allows simple commands in conditionals (got command.Sentence). ===== CASE: [strict_errexit] while { echo 1; echo 2; }; do echo WHILE; done ===== ===== CASE: -c set -o errexit; shopt -s strict_errexit; while { echo 1; echo 2; }; do echo WHILE; done ===== set -o errexit; shopt -s strict_errexit; while { echo 1; echo 2; }; do echo WHILE; done ^ [ -c flag ]:1: fatal: strict_errexit only allows simple commands in conditionals (got command.Sentence). ===== CASE: [strict_errexit] until { echo 1; echo 2; }; do echo UNTIL; done ===== ===== CASE: -c set -o errexit; shopt -s strict_errexit; until { echo 1; echo 2; }; do echo UNTIL; done ===== set -o errexit; shopt -s strict_errexit; until { echo 1; echo 2; }; do echo UNTIL; done ^ [ -c flag ]:1: fatal: strict_errexit only allows simple commands in conditionals (got command.Sentence). ===== CASE: [strict_errexit] shopt -s ysh:upgrade proc p { echo p } if p { echo hi } ===== ===== CASE: -c set -o errexit; shopt -s strict_errexit; shopt -s ysh:upgrade proc p { echo p } if p { echo hi } ===== if p { echo hi } ^~ [ -c flag ]:3: errexit was disabled for this construct if p { echo hi } ^ [ -c flag ]:3: fatal: Can't run a proc while errexit is disabled. Use 'try' or wrap it in a process with $0 myproc OK test-strict_errexit_1 *** Running test-strict_errexit_conditionals ===== CASE: [strict_errexit] myfunc() { return 1; } while ( myfunc ) do echo yes done ===== ===== CASE: -c set -o errexit; shopt -s strict_errexit; myfunc() { return 1; } while ( myfunc ) do echo yes done ===== while ( myfunc ) ^ [ -c flag ]:4: fatal: strict_errexit only allows simple commands in conditionals (got command.Subshell). ===== CASE: [strict_errexit] myfunc() { return 1; } while test "$(myfunc)" != "" do echo yes done ===== ===== CASE: -c set -o errexit; shopt -s strict_errexit; myfunc() { return 1; } while test "$(myfunc)" != "" do echo yes done ===== while test "$(myfunc)" != "" ^~ [ -c flag ]:4: fatal: Command subs not allowed here because status wouldn't be checked (strict_errexit) ===== CASE: [strict_errexit] myfunc() { return 1; } if cat <(ls) then echo yes fi ===== ===== CASE: -c set -o errexit; shopt -s strict_errexit; myfunc() { return 1; } if cat <(ls) then echo yes fi ===== if cat <(ls) ^~ [ -c flag ]:4: fatal: Process subs not allowed here because status wouldn't be checked (strict_errexit) ===== CASE: [strict_errexit] myfunc() { return 1 } set -o pipefail while myfunc | cat do echo yes done ===== ===== CASE: -c set -o errexit; shopt -s strict_errexit; myfunc() { return 1 } set -o pipefail while myfunc | cat do echo yes done ===== while myfunc | cat ^ [ -c flag ]:7: fatal: strict_errexit only allows simple commands in conditionals (got command.Pipeline). ===== CASE: [strict_errexit] myfunc() { return 1 } foo=$(true) # test assignment without proc while bar=$(false) do echo yes done # issue 1007 was caused using command.ShAssignment, rather than the more common # command.Sentence with ; while spam=$(myfunc) do echo yes done ===== ===== CASE: -c set -o errexit; shopt -s strict_errexit; myfunc() { return 1 } foo=$(true) # test assignment without proc while bar=$(false) do echo yes done # issue 1007 was caused using command.ShAssignment, rather than the more common # command.Sentence with ; while spam=$(myfunc) do echo yes done ===== while bar=$(false) ^~~~ [ -c flag ]:9: fatal: strict_errexit only allows simple commands in conditionals (got command.ShAssignment). OK test-strict_errexit_conditionals *** Running test-test-v-expr ===== CASE: -c shopt -s strict_word_eval; a=(1 2 3); test -v "" ===== shopt -s strict_word_eval; a=(1 2 3); test -v "" ^ [ -c flag ]:1: (test) -v expected name or name[index] ===== CASE: -c shopt -s strict_word_eval; a=(1 2 3); test -v "a[foo" ===== shopt -s strict_word_eval; a=(1 2 3); test -v "a[foo" ^ [ -c flag ]:1: (test) -v expected name or name[index] ===== CASE: -c shopt -s strict_word_eval; a=(1 2 3); test -v "a[not-int]" ===== shopt -s strict_word_eval; a=(1 2 3); test -v "a[not-int]" ^ [ -c flag ]:1: (test) -v got BashArray and invalid index 'not-int' ===== CASE: -c shopt -s strict_word_eval; a=(1 2 3); test -v "a[-42]" ===== shopt -s strict_word_eval; a=(1 2 3); test -v "a[-42]" ^ [ -c flag ]:1: (test) -v got invalid negative index -42 ===== CASE: -c shopt -s strict_word_eval; s=""; test -v s[0] ===== shopt -s strict_word_eval; s=""; test -v s[0] ^~ [ -c flag ]:1: (test) Expected BashArray or BashAssoc, got Str OK test-test-v-expr *** Running test-unsafe_arith_eval ===== CASE: -c local e1=1+ local e2="e1 + 5" echo $(( e2 )) # recursively references e1 ===== 1+ ^ [ -c flag ]:1: Unexpected end of input 1+ ^ [ -c flag ]:1: fatal: Parse error in recursive arithmetic OK test-unsafe_arith_eval *** Running test-unset_expr ===== CASE: -c unset -v 1[1] ===== 1[1] ^ [ dynamic LHS at line 1 of [ -c flag ] ]:1 unset -v 1[1] ^ [ -c flag ]:1: fatal: Invalid variable name '1' ===== CASE: -c unset -v 1+2 ===== unset -v 1+2 ^~~~~ [ -c flag ]:1: fatal: Invalid LHS to modify OK test-unset_expr *** Running test-var-op-qmark ===== CASE: -c echo ${zz?} ===== echo ${zz?} ^~ [ -c flag ]:1: fatal: Var zz is unset ===== CASE: -c echo ${zz:?} ===== echo ${zz:?} ^~ [ -c flag ]:1: fatal: Var zz is unset ===== CASE: -c zz=""; echo ${zz?} ===== ===== CASE: -c zz=""; echo ${zz:?} ===== zz=""; echo ${zz:?} ^~ [ -c flag ]:1: fatal: Var zz is empty ===== CASE: -c echo ${zz?Required} ===== echo ${zz?Required} ^~ [ -c flag ]:1: fatal: Var zz is unset: 'Required' ===== CASE: -c echo ${zz:?Required} ===== echo ${zz:?Required} ^~ [ -c flag ]:1: fatal: Var zz is unset: 'Required' OK test-var-op-qmark test/runtime-errors.sh: 31 tests passed.