1# 2# This file contains tests corresponding to the `Shell Grammar' texinfo node. 3# 4 5%prep 6 7 mkdir basic.tmp && cd basic.tmp 8 9 touch foo bar 10 echo "'" >unmatched_quote.txt 11 12%test 13# 14# Tests for `Simple Commands and Pipelines' 15# 16 echo foo | cat | sed 's/foo/bar/' 170:Basic pipeline handling 18>bar 19 20 false | true 210:Exit status of pipeline with builtins (true) 22 23 true | false 241:Exit status of pipeline with builtins (false) 25 26 false 27 $nonexistent_variable 280:Executing command that evaluates to empty resets status 29 30 false 31 sleep 1 & 32 print $? 33 # a tidy test is a happy test 34 wait $! 350:Starting background command resets status 36>0 37 38 false 39 . /dev/null 400:Sourcing empty file resets status 41 42 fn() { local foo; read foo; print $foo; } 43 coproc fn 44 print -p coproc test output 45 read -p bar 46 print $bar 470:Basic coprocess handling 48>coproc test output 49 50 true | false && print true || print false 510:Basic sublist (i) 52>false 53 54 false | true && print true || print false 550:Basic sublist (ii) 56>true 57 58 (cd /NonExistentDirectory >&/dev/null) || print false 590:Basic subshell list with error 60>false 61 62 { cd /NonExistentDirectory >&/dev/null } || print false 630:Basic current shell list with error 64>false 65 66# 67# Tests for `Precommand Modifiers' 68# 69 - $ZTST_testdir/../Src/zsh -fc "[[ \$0 = \"-$ZTST_testdir/../Src/zsh\" ]]" 700:`-' precommand modifier 71 72 echo f* 73 noglob echo f* 740:`noglob' precommand modifier 75>foo 76>f* 77 78 (exec /bin/sh; echo bar) 790:`exec' precommand modifier 80 81 (exec -l $ZTST_testdir/../Src/zsh -fc 'echo $0' | sed 's%/.*/%%' ) 820:`exec' with -l option 83>-zsh 84 85 (exec -a /bin/SPLATTER /bin/sh -c 'echo $0') 860:`exec' with -a option 87>/bin/SPLATTER 88 89 (exec -a/bin/SPLOOSH /bin/sh -c 'echo $0') 900:`exec' with -a option, no space 91>/bin/SPLOOSH 92 93 (export FOO=bar; exec -c /bin/sh -c 'echo x${FOO}x') 940:`exec' with -c option 95>xx 96 97 cat() { echo Function cat executed; } 98 command cat && unfunction cat 990:`command' precommand modifier 100<External command cat executed 101>External command cat executed 102 103 cd() { echo Not cd at all; } 104 builtin cd . && unfunction cd 1050:`builtin' precommand modifier 106 107# 108# Tests for `Complex Commands' 109# 110 111 if true; then 112 print true-1 113 elif true; then 114 print true-2 115 else 116 print false 117 fi 1180:`if ...' (i) 119>true-1 120 121 if false; then 122 print true-1 123 elif true; then 124 print true-2 125 else 126 print false 127 fi 1280:`if ...' (ii) 129>true-2 130 131 if false; then 132 print true-1 133 elif false; then 134 print true-2 135 else 136 print false 137 fi 1380:`if ...' (iii) 139>false 140 141 if true; 142 : 143 fi 1441d:`if ...' (iv) 145?(eval):3: parse error near `fi' 146 147 for name in word to term; do 148 print $name 149 done 1500:`for' loop 151>word 152>to 153>term 154 155 for name 156 in word to term; do 157 print $name 158 done 1590:`for' loop with newline before in keyword 160>word 161>to 162>term 163 164 for (( name = 0; name < 3; name++ )); do 165 print $name 166 done 1670:arithmetic `for' loop 168>0 169>1 170>2 171 172 for keyvar valvar in key1 val1 key2 val2; do 173 print key=$keyvar val=$valvar 174 done 1750:enhanced `for' syntax with two loop variables 176>key=key1 val=val1 177>key=key2 val=val2 178 179 for keyvar valvar stuffvar in keyA valA stuffA keyB valB stuffB; do 180 print key=$keyvar val=$valvar stuff=$stuffvar 181 done 1820:enhanced `for' syntax with three loop variables 183>key=keyA val=valA stuff=stuffA 184>key=keyB val=valB stuff=stuffB 185 186 for in in in in in stop; do 187 print in=$in 188 done 1890:compatibility of enhanced `for' syntax with standard syntax 190>in=in 191>in=in 192>in=in 193>in=stop 194 195 name=0 196 while (( name < 3 )); do 197 print $name 198 (( name++ )) 199 done 2000:`while' loop 201>0 202>1 203>2 204 205 name=0 206 until (( name == 3 )); do 207 print $name 208 (( name++ )) 209 done 2100:`until' loop 211>0 212>1 213>2 214 215 repeat 3 do 216 echo over and over 217 done 2180:`repeat' loop 219>over and over 220>over and over 221>over and over 222 223 word=Trinity 224 case $word in 225 Michaelmas) print 0 226 ;; 227 Hilary) print 1 228 ;; 229 Trinity) print 2 230 ;; 231 *) print 3 232 ;; 233 esac 2340:`case', old syntax 235>2 236 237 word=Trinity 238 case $word in 239 (Michaelmas) print 0 240 ;; 241 (Hilary) print 1 242 ;; 243 (Trinity) print 2 244 ;; 245 (*) print 3 246 ;; 247 esac 2480:`case', new syntax 249>2 250 251 word=Hilary 252 case $word in 253 (Michaelmas) print 0 254 ;; 255 (Hilary) print 1 256 ;& 257 (Trinity) print 2 258 ;& 259 (*) print 3 260 ;; 261 esac 2620:`case', new syntax, cascaded 263>1 264>2 265>3 266 267## Select now reads from stdin if the shell is not interactive. 268## Its own output goes to stderr. 269 (COLUMNS=80 LINES=3 270 PS3="input> " 271 select name in one two three; do 272 print $name 273 done) 2740:`select' loop 275<2 276?1) one 2) two 3) three 277?input> input> 278>two 279 280 function name1 name2 () { print This is $0; } 281 name2 282 name1 name2() { print This is still $0; } 283 name2 2840:`function' keyword 285>This is name2 286>This is still name2 287 288 (time cat) >&/dev/null 2890:`time' keyword (status only) 290 291 if [[ -f foo && -d . && -n $ZTST_testdir ]]; then 292 true 293 else 294 false 295 fi 2960:basic [[ ... ]] test 297 298# 299# Current shell execution with try/always form. 300# We put those with errors in subshells so that any unhandled error doesn't 301# propagate. 302# 303 304 { 305 print The try block. 306 } always { 307 print The always block. 308 } 309 print After the always block. 3100:Basic `always' syntax 311>The try block. 312>The always block. 313>After the always block. 314 315 ({ 316 print Position one. 317 print ${*this is an error*} 318 print Position two. 319 } always { 320 if (( TRY_BLOCK_ERROR )); then 321 print An error occurred. 322 else 323 print No error occurred. 324 fi 325 } 326 print Position three) 3271:Always block with error not reset 328>Position one. 329>An error occurred. 330?(eval):3: bad substitution 331 332 ({ 333 print Stelle eins. 334 print ${*voici une erreur} 335 print Posizione due. 336 } always { 337 if (( TRY_BLOCK_ERROR )); then 338 print Erratum factum est. Retro ponetur. 339 (( TRY_BLOCK_ERROR = 0 )) 340 else 341 print unray touay foay anguageslay 342 fi 343 } 344 print Status after always block is $?.) 3450:Always block with error reset 346>Stelle eins. 347>Erratum factum est. Retro ponetur. 348>Status after always block is 1. 349?(eval):3: bad substitution 350 351 fn() { { return } always { echo always 1 }; echo not executed } 352 fn 353 fn() { { echo try 2 } always { return }; echo not executed } 354 fn 3550:Always block interaction with return 356>always 1 357>try 2 358 359# Outputting of structures from the wordcode is distinctly non-trivial, 360# we probably ought to have more like the following... 361 fn1() { { echo foo; } } 362 fn2() { { echo foo; } always { echo bar; } } 363 fn3() { ( echo foo; ) } 364 functions fn1 fn2 fn3 3650:Output of syntactic structures with and without always blocks 366>fn1 () { 367> { 368> echo foo 369> } 370>} 371>fn2 () { 372> { 373> echo foo 374> } always { 375> echo bar 376> } 377>} 378>fn3 () { 379> ( 380> echo foo 381> ) 382>} 383 384 385# 386# Tests for `Alternate Forms For Complex Commands' 387# 388 389 if (true) { print true-1 } elif (true) { print true-2 } else { print false } 390 if (false) { print true-1 } elif (true) { print true-2 } else { print false } 391 if (false) { print true-1 } elif (false) { print true-2 } else { print false } 3920:Alternate `if' with braces 393>true-1 394>true-2 395>false 396 397 if { true } print true 398 if { false } print false 3990:Short form of `if' 400>true 401 402 eval "if" 4031:Short form of `if' can't be too short 404?(eval):1: parse error near `if' 405 406 for name ( word1 word2 word3 ) print $name 4070:Form of `for' with parentheses. 408>word1 409>word2 410>word3 411 412 for name in alpha beta gamma; print $name 4130:Short form of `for' 414>alpha 415>beta 416>gamma 417 418 for (( val = 2; val < 10; val *= val )) print $val 4190:Short arithmetic `for' 420>2 421>4 422 423 foreach name ( verbiage words periphrasis ) 424 print $name 425 end 4260:Csh-like `for' 427>verbiage 428>words 429>periphrasis 430 431# see comment with braces used in if loops 432 val=0; 433 while (( val < 2 )) { print $((val++)); } 4340:Alternative `while' 435>0 436>1 437 438 val=2; 439 until (( val == 0 )) { print $((val--)); } 4400:Alternative `until' 441>2 442>1 443 444 repeat 3 print Hip hip hooray 4450:Short `repeat' 446>Hip hip hooray 447>Hip hip hooray 448>Hip hip hooray 449 450 case bravo { 451 (alpha) print schmalpha 452 ;; 453 (bravo) print schmavo 454 ;; 455 (charlie) print schmarlie 456 ;; 457 } 4580:`case' with braces 459>schmavo 460 461 for word in artichoke bladderwort chrysanthemum Zanzibar 462 case $word in 463 (*der*) print $word contains the forbidden incantation der 464 ;; 465 (a*) print $word begins with a 466 ;& 467 ([[:upper:]]*) print $word either begins with a or an upper case letter 468 ;| 469 ([[:lower:]]*) print $word begins with a lower case letter 470 ;| 471 (*e*) print $word contains an e 472 ;; 473 esac 4740:`case' with mixed ;& and ;| 475>artichoke begins with a 476>artichoke either begins with a or an upper case letter 477>artichoke begins with a lower case letter 478>artichoke contains an e 479>bladderwort contains the forbidden incantation der 480>chrysanthemum begins with a lower case letter 481>chrysanthemum contains an e 482>Zanzibar either begins with a or an upper case letter 483 484 print -u $ZTST_fd 'This test hangs the shell when it fails...' 485 name=0 486# The number 4375 here is chosen to produce more than 16384 bytes of output 487 while (( name < 4375 )); do 488 print -n $name 489 (( name++ )) 490 done < /dev/null | { read name; print done } 4910:Bug regression: `while' loop with redirection and pipeline 492>done 493 494# This used to be buggy and print X at the end of each iteration. 495 for f in 1 2 3 4; do 496 print $f || break 497 done && print X 4980:Handling of ||'s and &&'s with a for loop in between 499>1 500>2 501>3 502>4 503>X 504 505# Same bug for &&, used to print `no' at the end of each iteration 506 for f in 1 2 3 4; do 507 false && print strange 508 done || print no 5090:Handling of &&'s and ||'s with a for loop in between 510>no 511 512 $ZTST_testdir/../Src/zsh -f unmatched_quote.txt 5131:Parse error with file causes non-zero exit status 514?unmatched_quote.txt:2: unmatched ' 515 516 $ZTST_testdir/../Src/zsh -f <unmatched_quote.txt 5171:Parse error on standard input causes non-zero exit status 518?zsh: unmatched ' 519 520 $ZTST_testdir/../Src/zsh -f -c "'" 5211:Parse error on inline command causes non-zero exit status 522?zsh:1: unmatched ' 523 524 $ZTST_testdir/../Src/zsh -f NonExistentScript 525127q:Non-existent script causes exit status 127 526?$ZTST_testdir/../Src/zsh: can't open input file: NonExistentScript 527 528 (setopt nonomatch 529 # use this to get stuff at start of line 530 contents=$'# comment \'\necho value #with " stuff\n# comment\n#comment 531 echo not#comment\n' 532 eval 'VAR=$('"$contents"')' 533 print -l $VAR) 5340:comments within $(...) 535>value 536>not#comment 537 538 . ./nonexistent 539127: Attempt to "." non-existent file. 540?(eval):.:1: no such file or directory: ./nonexistent 541 542 echo '[[' >bad_syntax 543 . ./bad_syntax 544126: Attempt to "." file with bad syntax. 545?./bad_syntax:2: parse error near `\n' 546 547 echo 'false' >dot_false 548 . ./dot_false 549 print $? 550 echo 'true' >dot_true 551 . ./dot_true 552 print $? 5530:Last status of successfully executed "." file is retained 554>1 555>0 556 557 echo 'echo $?' >dot_status 558 false 559 . ./dot_status 5600:"." file sees status from previous command 561>1 562 563 mkdir test_path_script 564 print "#!/bin/sh\necho Found the script." >test_path_script/myscript 565 chmod u+x test_path_script/myscript 566 path=($PWD/test_path_script $path) 567 export PATH 568 $ZTST_testdir/../Src/zsh -f -o pathscript myscript 5690:PATHSCRIPT option 570>Found the script. 571 572 $ZTST_testdir/../Src/zsh -f myscript 573127q:PATHSCRIPT option not used. 574?$ZTST_testdir/../Src/zsh: can't open input file: myscript 575 576 $ZTST_testdir/../Src/zsh -fc 'echo $0; echo $1' myargzero myargone 5770:$0 is traditionally if bizarrely set to the first argument with -c 578>myargzero 579>myargone 580 581 (setopt shglob 582 eval ' 583 if ! (echo success1); then echo failure1; fi 584 if !(echo success2); then echo failure2; fi 585 print -l one two | while(read foo)do(print read it)done 586 ') 5870:Parentheses in shglob 588>success1 589>success2 590>read it 591>read it 592