PageRenderTime 3332ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

/usr/src/lib/libshell/common/tests/options.sh

https://github.com/richlowe/illumos-gate
Shell | 499 lines | 437 code | 40 blank | 22 comment | 167 complexity | 1c3284f242d221205398c18a7dcf2924 MD5 | raw file
  1. ########################################################################
  2. # #
  3. # This software is part of the ast package #
  4. # Copyright (c) 1982-2010 AT&T Intellectual Property #
  5. # and is licensed under the #
  6. # Common Public License, Version 1.0 #
  7. # by AT&T Intellectual Property #
  8. # #
  9. # A copy of the License is available at #
  10. # http://www.opensource.org/licenses/cpl1.0.txt #
  11. # (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) #
  12. # #
  13. # Information and Software Systems Research #
  14. # AT&T Research #
  15. # Florham Park NJ #
  16. # #
  17. # David Korn <dgk@research.att.com> #
  18. # #
  19. ########################################################################
  20. function err_exit
  21. {
  22. print -u2 -n "\t"
  23. print -u2 -r ${Command}[$1]: "${@:2}"
  24. let Errors+=1
  25. }
  26. alias err_exit='err_exit $LINENO'
  27. Command=${0##*/}
  28. integer Errors=0
  29. unset HISTFILE
  30. export LC_ALL=C ENV=
  31. ulimit -c 0
  32. tmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; }
  33. trap "cd /; rm -rf $tmp" EXIT
  34. if [[ $( ${SHELL-ksh} -s hello<<-\!
  35. print $1
  36. !
  37. ) != hello ]]
  38. then err_exit "${SHELL-ksh} -s not working"
  39. fi
  40. x=$(
  41. set -e
  42. false && print bad
  43. print good
  44. )
  45. if [[ $x != good ]]
  46. then err_exit 'sh -e not working'
  47. fi
  48. [[ $($SHELL -D -c 'print hi; print $"hello"') == '"hello"' ]] || err_exit 'ksh -D not working'
  49. env=$tmp/.env
  50. print $'(print -u1 aha) &>/dev/null\n(print -u2 aha) &>/dev/null' > $env
  51. rc=$tmp/.kshrc
  52. print $'PS1=""\nfunction env_hit\n{\n\tprint OK\n}' > $rc
  53. export ENV=/.$env
  54. if [[ ! -o privileged ]]
  55. then
  56. got=$($SHELL -E -c : 2>/dev/null)
  57. if [[ $g ]]
  58. then
  59. got=$(printf %q "$got")
  60. err_exit "\$ENV file &>/dev/null does not redirect stdout -- expected '', got $got"
  61. fi
  62. got=$($SHELL -E -c : 2>&1 >/dev/null)
  63. if [[ $got != *nonstandard* || $got == *$'\n'* ]]
  64. then
  65. got=$(printf %q "$got")
  66. err_exit "\$ENV file &>/dev/null does not redirect stderr -- expected one diagnostic line, got $got"
  67. fi
  68. fi
  69. export ENV=/.$rc
  70. if [[ -o privileged ]]
  71. then
  72. [[ $(print env_hit | $SHELL 2>&1) == "OK" ]] &&
  73. err_exit 'privileged nointeractive shell reads $ENV file'
  74. [[ $(print env_hit | $SHELL -E 2>&1) == "OK" ]] &&
  75. err_exit 'privileged -E reads $ENV file'
  76. [[ $(print env_hit | $SHELL +E 2>&1) == "OK" ]] &&
  77. err_exit 'privileged +E reads $ENV file'
  78. [[ $(print env_hit | $SHELL --rc 2>&1) == "OK" ]] &&
  79. err_exit 'privileged --rc reads $ENV file'
  80. [[ $(print env_hit | $SHELL --norc 2>&1) == "OK" ]] &&
  81. err_exit 'privileged --norc reads $ENV file'
  82. else
  83. [[ $(print env_hit | $SHELL 2>&1) == "OK" ]] &&
  84. err_exit 'nointeractive shell reads $ENV file'
  85. [[ $(print env_hit | $SHELL -E 2>&1) == "OK" ]] ||
  86. err_exit '-E ignores $ENV file'
  87. [[ $(print env_hit | $SHELL +E 2>&1) == "OK" ]] &&
  88. err_exit '+E reads $ENV file'
  89. [[ $(print env_hit | $SHELL --rc 2>&1) == "OK" ]] ||
  90. err_exit '--rc ignores $ENV file'
  91. [[ $(print env_hit | $SHELL --norc 2>&1) == "OK" ]] &&
  92. err_exit '--norc reads $ENV file'
  93. [[ $(print env_hit | $SHELL -i 2>&1) == "OK" ]] ||
  94. err_exit '-i ignores $ENV file'
  95. fi
  96. export ENV=
  97. if [[ -o privileged ]]
  98. then
  99. [[ $(print env_hit | HOME=$tmp $SHELL 2>&1) == "OK" ]] &&
  100. err_exit 'privileged nointeractive shell reads $HOME/.kshrc file'
  101. [[ $(print env_hit | HOME=$tmp $SHELL -E 2>&1) == "OK" ]] &&
  102. err_exit 'privileged -E ignores empty $ENV'
  103. [[ $(print env_hit | HOME=$tmp $SHELL +E 2>&1) == "OK" ]] &&
  104. err_exit 'privileged +E reads $HOME/.kshrc file'
  105. [[ $(print env_hit | HOME=$tmp $SHELL --rc 2>&1) == "OK" ]] &&
  106. err_exit 'privileged --rc ignores empty $ENV'
  107. [[ $(print env_hit | HOME=$tmp $SHELL --norc 2>&1) == "OK" ]] &&
  108. err_exit 'privileged --norc reads $HOME/.kshrc file'
  109. else
  110. [[ $(print env_hit | HOME=$tmp $SHELL 2>&1) == "OK" ]] &&
  111. err_exit 'nointeractive shell reads $HOME/.kshrc file'
  112. [[ $(print env_hit | HOME=$tmp $SHELL -E 2>&1) == "OK" ]] &&
  113. err_exit '-E ignores empty $ENV'
  114. [[ $(print env_hit | HOME=$tmp $SHELL +E 2>&1) == "OK" ]] &&
  115. err_exit '+E reads $HOME/.kshrc file'
  116. [[ $(print env_hit | HOME=$tmp $SHELL --rc 2>&1) == "OK" ]] &&
  117. err_exit '--rc ignores empty $ENV'
  118. [[ $(print env_hit | HOME=$tmp $SHELL --norc 2>&1) == "OK" ]] &&
  119. err_exit '--norc reads $HOME/.kshrc file'
  120. fi
  121. unset ENV
  122. if [[ -o privileged ]]
  123. then
  124. [[ $(print env_hit | HOME=$tmp $SHELL 2>&1) == "OK" ]] &&
  125. err_exit 'privileged nointeractive shell reads $HOME/.kshrc file'
  126. [[ $(print env_hit | HOME=$tmp $SHELL -E 2>&1) == "OK" ]] &&
  127. err_exit 'privileged -E reads $HOME/.kshrc file'
  128. [[ $(print env_hit | HOME=$tmp $SHELL +E 2>&1) == "OK" ]] &&
  129. err_exit 'privileged +E reads $HOME/.kshrc file'
  130. [[ $(print env_hit | HOME=$tmp $SHELL --rc 2>&1) == "OK" ]] &&
  131. err_exit 'privileged --rc reads $HOME/.kshrc file'
  132. [[ $(print env_hit | HOME=$tmp $SHELL --norc 2>&1) == "OK" ]] &&
  133. err_exit 'privileged --norc reads $HOME/.kshrc file'
  134. else
  135. [[ $(print env_hit | HOME=$tmp $SHELL 2>&1) == "OK" ]] &&
  136. err_exit 'nointeractive shell reads $HOME/.kshrc file'
  137. [[ $(print env_hit | HOME=$tmp $SHELL -E 2>&1) == "OK" ]] ||
  138. err_exit '-E ignores $HOME/.kshrc file'
  139. [[ $(print env_hit | HOME=$tmp $SHELL +E 2>&1) == "OK" ]] &&
  140. err_exit '+E reads $HOME/.kshrc file'
  141. [[ $(print env_hit | HOME=$tmp $SHELL --rc 2>&1) == "OK" ]] ||
  142. err_exit '--rc ignores $HOME/.kshrc file'
  143. [[ $(print env_hit | HOME=$tmp $SHELL --norc 2>&1) == "OK" ]] &&
  144. err_exit '--norc reads $HOME/.kshrc file'
  145. fi
  146. rm -rf $tmp/.kshrc
  147. if command set -G 2> /dev/null
  148. then cd $tmp
  149. mkdir bar foo
  150. > bar.c > bam.c
  151. > bar/foo.c > bar/bam.c
  152. > foo/bam.c
  153. set -- **.c
  154. expected='bam.c bar.c'
  155. [[ $* == $expected ]] ||
  156. err_exit "-G **.c failed -- expected '$expected', got '$*'"
  157. set -- **
  158. expected='bam.c bar bar.c bar/bam.c bar/foo.c foo foo/bam.c'
  159. [[ $* == $expected ]] ||
  160. err_exit "-G ** failed -- expected '$expected', got '$*'"
  161. set -- **/*.c
  162. expected='bam.c bar.c bar/bam.c bar/foo.c foo/bam.c'
  163. [[ $* == $expected ]] ||
  164. err_exit "-G **/*.c failed -- expected '$expected', got '$*'"
  165. set -- **/bam.c
  166. expected='bam.c bar/bam.c foo/bam.c'
  167. [[ $* == $expected ]] ||
  168. err_exit "-G **/bam.c failed -- expected '$expected', got '$*'"
  169. cd ~-
  170. fi
  171. cd $tmp
  172. t="<$$>.profile.<$$>"
  173. echo "echo '$t'" > .profile
  174. cp $SHELL ./-ksh
  175. if [[ -o privileged ]]
  176. then
  177. [[ $(HOME=$PWD $SHELL -l </dev/null 2>&1) == *$t* ]] &&
  178. err_exit 'privileged -l reads .profile'
  179. [[ $(HOME=$PWD $SHELL --login </dev/null 2>&1) == *$t* ]] &&
  180. err_exit 'privileged --login reads .profile'
  181. [[ $(HOME=$PWD $SHELL --login-shell </dev/null 2>&1) == *$t* ]] &&
  182. err_exit 'privileged --login-shell reads .profile'
  183. [[ $(HOME=$PWD $SHELL --login_shell </dev/null 2>&1) == *$t* ]] &&
  184. err_exit 'privileged --login_shell reads .profile'
  185. [[ $(HOME=$PWD exec -a -ksh $SHELL </dev/null 2>&1) == *$t* ]] &&
  186. err_exit 'privileged exec -a -ksh ksh reads .profile'
  187. [[ $(HOME=$PWD ./-ksh -i </dev/null 2>&1) == *$t* ]] &&
  188. err_exit 'privileged ./-ksh reads .profile'
  189. [[ $(HOME=$PWD ./-ksh -ip </dev/null 2>&1) == *$t* ]] &&
  190. err_exit 'privileged ./-ksh -p reads .profile'
  191. else
  192. [[ $(HOME=$PWD $SHELL -l </dev/null 2>&1) == *$t* ]] ||
  193. err_exit '-l ignores .profile'
  194. [[ $(HOME=$PWD $SHELL --login </dev/null 2>&1) == *$t* ]] ||
  195. err_exit '--login ignores .profile'
  196. [[ $(HOME=$PWD $SHELL --login-shell </dev/null 2>&1) == *$t* ]] ||
  197. err_exit '--login-shell ignores .profile'
  198. [[ $(HOME=$PWD $SHELL --login_shell </dev/null 2>&1) == *$t* ]] ||
  199. err_exit '--login_shell ignores .profile'
  200. [[ $(HOME=$PWD exec -a -ksh $SHELL </dev/null 2>/dev/null) == *$t* ]] ||
  201. err_exit 'exec -a -ksh ksh 2>/dev/null ignores .profile'
  202. [[ $(HOME=$PWD exec -a -ksh $SHELL </dev/null 2>&1) == *$t* ]] ||
  203. err_exit 'exec -a -ksh ksh 2>&1 ignores .profile'
  204. [[ $(HOME=$PWD ./-ksh -i </dev/null 2>&1) == *$t* ]] ||
  205. err_exit './-ksh ignores .profile'
  206. [[ $(HOME=$PWD ./-ksh -ip </dev/null 2>&1) == *$t* ]] &&
  207. err_exit './-ksh -p does not ignore .profile'
  208. fi
  209. cd ~-
  210. rm -rf $tmp/.profile
  211. # { exec interactive login_shell restricted xtrace } in the following test
  212. for opt in \
  213. allexport all-export all_export \
  214. bgnice bg-nice bg_nice \
  215. clobber emacs \
  216. errexit err-exit err_exit \
  217. glob \
  218. globstar glob-star glob_star \
  219. gmacs \
  220. ignoreeof ignore-eof ignore_eof \
  221. keyword log markdirs monitor notify \
  222. pipefail pipe-fail pipe_fail \
  223. trackall track-all track_all \
  224. unset verbose vi \
  225. viraw vi-raw vi_raw
  226. do old=$opt
  227. if [[ ! -o $opt ]]
  228. then old=no$opt
  229. fi
  230. set --$opt || err_exit "set --$opt failed"
  231. [[ -o $opt ]] || err_exit "[[ -o $opt ]] failed"
  232. [[ -o no$opt ]] && err_exit "[[ -o no$opt ]] failed"
  233. [[ -o no-$opt ]] && err_exit "[[ -o no-$opt ]] failed"
  234. [[ -o no_$opt ]] && err_exit "[[ -o no_$opt ]] failed"
  235. [[ -o ?$opt ]] || err_exit "[[ -o ?$opt ]] failed"
  236. [[ -o ?no$opt ]] || err_exit "[[ -o ?no$opt ]] failed"
  237. [[ -o ?no-$opt ]] || err_exit "[[ -o ?no-$opt ]] failed"
  238. [[ -o ?no_$opt ]] || err_exit "[[ -o ?no_$opt ]] failed"
  239. set --no$opt || err_exit "set --no$opt failed"
  240. [[ -o no$opt ]] || err_exit "[[ -o no$opt ]] failed"
  241. [[ -o $opt ]] && err_exit "[[ -o $opt ]] failed"
  242. set --no-$opt || err_exit "set --no-$opt failed"
  243. [[ -o no$opt ]] || err_exit "[[ -o no$opt ]] failed"
  244. [[ -o $opt ]] && err_exit "[[ -o $opt ]] failed"
  245. set --no_$opt || err_exit "set --no_$opt failed"
  246. [[ -o no$opt ]] || err_exit "[[ -o no$opt ]] failed"
  247. [[ -o $opt ]] && err_exit "[[ -o $opt ]] failed"
  248. set -o $opt || err_exit "set -o $opt failed"
  249. [[ -o $opt ]] || err_exit "[[ -o $opt ]] failed"
  250. set -o $opt=1 || err_exit "set -o $opt=1 failed"
  251. [[ -o $opt ]] || err_exit "[[ -o $opt ]] failed"
  252. set -o no$opt=0 || err_exit "set -o no$opt=0 failed"
  253. [[ -o $opt ]] || err_exit "[[ -o $opt ]] failed"
  254. set --$opt=1 || err_exit "set --$opt=1 failed"
  255. [[ -o $opt ]] || err_exit "[[ -o $opt ]] failed"
  256. set --no$opt=0 || err_exit "set --no$opt=0 failed"
  257. [[ -o $opt ]] || err_exit "[[ -o $opt ]] failed"
  258. set -o no$opt || err_exit "set -o no$opt failed"
  259. [[ -o no$opt ]] || err_exit "[[ -o no$opt ]] failed"
  260. set -o $opt=0 || err_exit "set -o $opt=0 failed"
  261. [[ -o no$opt ]] || err_exit "[[ -o no$opt ]] failed"
  262. set -o no$opt=1 || err_exit "set -o no$opt=1 failed"
  263. [[ -o no$opt ]] || err_exit "[[ -o no$opt ]] failed"
  264. set --$opt=0 || err_exit "set --$opt=0 failed"
  265. [[ -o no$opt ]] || err_exit "[[ -o no$opt ]] failed"
  266. set --no$opt=1 || err_exit "set --no$opt=1 failed"
  267. [[ -o no$opt ]] || err_exit "[[ -o no$opt ]] failed"
  268. set -o no-$opt || err_exit "set -o no-$opt failed"
  269. [[ -o no-$opt ]] || err_exit "[[ -o no-$opt ]] failed"
  270. set -o no_$opt || err_exit "set -o no_$opt failed"
  271. [[ -o no_$opt ]] || err_exit "[[ -o no_$opt ]] failed"
  272. set +o $opt || err_exit "set +o $opt failed"
  273. [[ -o no$opt ]] || err_exit "[[ -o no$opt ]] failed"
  274. set +o no$opt || err_exit "set +o no$opt failed"
  275. [[ -o $opt ]] || err_exit "[[ -o $opt ]] failed"
  276. set +o no-$opt || err_exit "set +o no-$opt failed"
  277. [[ -o $opt ]] || err_exit "[[ -o $opt ]] failed"
  278. set +o no_$opt || err_exit "set +o no_$opt failed"
  279. [[ -o $opt ]] || err_exit "[[ -o $opt ]] failed"
  280. set --$old
  281. done
  282. for opt in \
  283. exec interactive login_shell login-shell logi privileged \
  284. rc restricted xtrace
  285. do [[ -o $opt ]]
  286. y=$?
  287. [[ -o no$opt ]]
  288. n=$?
  289. case $y$n in
  290. 10|01) ;;
  291. *) err_exit "[[ -o $opt ]] == [[ -o no$opt ]]" ;;
  292. esac
  293. done
  294. for opt in \
  295. foo foo-bar foo_bar
  296. do if [[ -o ?$opt ]]
  297. then err_exit "[[ -o ?$opt ]] should fail"
  298. fi
  299. if [[ -o ?no$opt ]]
  300. then err_exit "[[ -o ?no$opt ]] should fail"
  301. fi
  302. done
  303. [[ $(set +o) == $(set --state) ]] || err_exit "set --state different from set +o"
  304. set -- $(set --state)
  305. [[ $1 == set && $2 == --default ]] || err_exit "set --state failed -- expected 'set --default *', got '$1 $2 *'"
  306. shift
  307. restore=$*
  308. shift
  309. off=
  310. for opt
  311. do case $opt in
  312. --not*) opt=${opt/--/--no} ;;
  313. --no*) opt=${opt/--no/--} ;;
  314. --*) opt=${opt/--/--no} ;;
  315. esac
  316. off="$off $opt"
  317. done
  318. set $off
  319. state=$(set --state)
  320. default=$(set --default --state)
  321. [[ $state == $default ]] || err_exit "set --state for default options failed: expected '$default', got '$state'"
  322. set $restore
  323. state=$(set --state)
  324. [[ $state == "set $restore" ]] || err_exit "set --state after restore failed: expected 'set $restore', got '$state'"
  325. typeset -a pipeline
  326. pipeline=(
  327. ( nopipefail=0 pipefail=1 command='false|true|true' )
  328. ( nopipefail=0 pipefail=1 command='true|false|true' )
  329. ( nopipefail=1 pipefail=1 command='true|true|false' )
  330. ( nopipefail=1 pipefail=1 command='false|false|false' )
  331. ( nopipefail=0 pipefail=0 command='true|true|true' )
  332. ( nopipefail=0 pipefail=0 command='print hi|(sleep 1;/bin/cat)>/dev/null' )
  333. )
  334. set --nopipefail
  335. for ((i = 0; i < ${#pipeline[@]}; i++ ))
  336. do eval ${pipeline[i].command}
  337. status=$?
  338. expected=${pipeline[i].nopipefail}
  339. [[ $status == $expected ]] ||
  340. err_exit "--nopipefail '${pipeline[i].command}' exit status $status -- expected $expected"
  341. done
  342. ftt=0
  343. set --pipefail
  344. for ((i = 0; i < ${#pipeline[@]}; i++ ))
  345. do eval ${pipeline[i].command}
  346. status=$?
  347. expected=${pipeline[i].pipefail}
  348. if [[ $status != $expected ]]
  349. then err_exit "--pipefail '${pipeline[i].command}' exit status $status -- expected $expected"
  350. (( i == 0 )) && ftt=1
  351. fi
  352. done
  353. if (( ! ftt ))
  354. then exp=10
  355. got=$(for((n=1;n<exp;n++))do $SHELL --pipefail -c '(sleep 0.1;false)|true|true' && break; done; print $n)
  356. [[ $got == $exp ]] || err_exit "--pipefail -c '(sleep 0.1;false)|true|true' fails with exit status 0 (after $got/$exp iterations)"
  357. fi
  358. echo=$(whence -p echo)
  359. for ((i=0; i < 20; i++))
  360. do if ! x=$(true | $echo 123)
  361. then err_exit 'command substitution with wrong exit status with pipefai'
  362. break
  363. fi
  364. done
  365. (
  366. set -o pipefail
  367. false | true
  368. (( $? )) || err_exit 'pipe not failing in subshell with pipefail'
  369. ) | wc >/dev/null
  370. $SHELL -c 'set -o pipefail; false | $(whence -p true);' && err_exit 'pipefail not returning failure with sh -c'
  371. exp='1212 or 1221'
  372. got=$(
  373. set --pipefail
  374. pipe() { date | cat > /dev/null ;}
  375. print $'1\n2' |
  376. while read i
  377. do if pipe $tmp
  378. then { print -n $i; sleep 2; print -n $i; } &
  379. fi
  380. done
  381. wait
  382. )
  383. [[ $got == @((12|21)(12|21)) ]] || err_exit "& job delayed by --pipefail, expected '$exp', got '$got'"
  384. $SHELL -c '[[ $- == *c* ]]' || err_exit 'option c not in $-'
  385. > $tmp/.profile
  386. for i in i l r s D E a b e f h k n t u v x B C G H
  387. do HOME=$tmp ENV= $SHELL -$i >/dev/null 2>&1 <<- ++EOF++ || err_exit "option $i not in \$-"
  388. [[ \$- == *$i* ]] || exit 1
  389. ++EOF++
  390. done
  391. letters=ilrabefhknuvxBCGE
  392. integer j=0
  393. for i in interactive login restricted allexport notify errexit \
  394. noglob trackall keyword noexec nounset verbose xtrace braceexpand \
  395. noclobber globstar rc
  396. do HOME=$tmp ENV= $SHELL -o $i >/dev/null 2>&1 <<- ++EOF++ || err_exit "option $i not equivalent to ${letters:j:1}"
  397. [[ \$- == *${letters:j:1}* ]] || exit 1
  398. ++EOF++
  399. ((j++))
  400. done
  401. export ENV=
  402. histfile=$tmp/history
  403. exp=$(HISTFILE=$histfile $SHELL -c $'function foo\n{\ncat\n}\ntype foo')
  404. for var in HISTSIZE HISTFILE
  405. do got=$( ( HISTFILE=$histfile $SHELL -ic $'unset '$var$'\nfunction foo\n{\ncat\n}\ntype foo\nexit' ) 2>&1 )
  406. got=${got##*': '}
  407. [[ $got == "$exp" ]] || err_exit "function definition inside (...) with $var unset fails -- got '$got', expected '$exp'"
  408. got=$( { HISTFILE=$histfile $SHELL -ic $'unset '$var$'\nfunction foo\n{\ncat\n}\ntype foo\nexit' ;} 2>&1 )
  409. got=${got##*': '}
  410. [[ $got == "$exp" ]] || err_exit "function definition inside {...;} with $var unset fails -- got '$got', expected '$exp'"
  411. done
  412. ( unset HISTFILE; $SHELL -ic "HISTFILE=$histfile" 2>/dev/null ) || err_exit "setting HISTFILE when not in environment fails"
  413. # the next tests loop on all combinations of
  414. # { SUB PAR CMD ADD }
  415. SUB=(
  416. ( BEG='$( ' END=' )' )
  417. ( BEG='${ ' END='; }' )
  418. )
  419. PAR=(
  420. ( BEG='( ' END=' )' )
  421. ( BEG='{ ' END='; }' )
  422. )
  423. CMD=( command-kill script-kill )
  424. ADD=( '' '; :' )
  425. cd $tmp
  426. print $'#!'$SHELL$'\nkill -KILL $$' > command-kill
  427. print $'kill -KILL $$' > script-kill
  428. chmod +x command-kill script-kill
  429. export PATH=.:$PATH
  430. exp='Killed'
  431. for ((S=0; S<${#SUB[@]}; S++))
  432. do for ((P=0; P<${#PAR[@]}; P++))
  433. do for ((C=0; C<${#CMD[@]}; C++))
  434. do for ((A=0; A<${#ADD[@]}; A++))
  435. do cmd="${SUB[S].BEG}${PAR[P].BEG}${CMD[C]}${PAR[P].END} 2>&1${ADD[A]}${SUB[S].END}"
  436. eval got="$cmd"
  437. got=${got##*': '}
  438. got=${got%%'('*}
  439. [[ $got == "$exp" ]] || err_exit "$cmd failed -- got '$got', expected '$exp'"
  440. done
  441. done
  442. done
  443. done
  444. $SHELL 2> /dev/null -c '{; true ;}' || err_exit 'leading ; causes syntax error in brace group'
  445. $SHELL 2> /dev/null -c '(; true ;)' || err_exit 'leading ; causes syntax error in parenthesis group'
  446. print 'for ((i = 0; i < ${1:-10000}; i++ )); do printf "%.*c\n" 15 x; done' > pipefail
  447. chmod +x pipefail
  448. $SHELL --pipefail -c './pipefail 10000 | sed 1q' >/dev/null 2>&1 &
  449. tst=$!
  450. { sleep 4; kill $tst; } 2>/dev/null &
  451. spy=$!
  452. wait $tst 2>/dev/null
  453. status=$?
  454. if [[ $status == 0 || $(kill -l $status) == PIPE ]]
  455. then kill $spy 2>/dev/null
  456. else err_exit "pipefail pipeline bypasses SIGPIPE and hangs"
  457. fi
  458. wait
  459. exit $((Errors))