13427 lines
279 KiB
Bash
13427 lines
279 KiB
Bash
# $MirOS: src/bin/mksh/check.t,v 1.797 2017/08/29 13:38:29 tg Exp $
|
||
# -*- mode: sh -*-
|
||
#-
|
||
# Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
|
||
# 2011, 2012, 2013, 2014, 2015, 2016, 2017
|
||
# mirabilos <m@mirbsd.org>
|
||
#
|
||
# Provided that these terms and disclaimer and all copyright notices
|
||
# are retained or reproduced in an accompanying document, permission
|
||
# is granted to deal in this work without restriction, including un‐
|
||
# limited rights to use, publicly perform, distribute, sell, modify,
|
||
# merge, give away, or sublicence.
|
||
#
|
||
# This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to
|
||
# the utmost extent permitted by applicable law, neither express nor
|
||
# implied; without malicious intent or gross negligence. In no event
|
||
# may a licensor, author or contributor be held liable for indirect,
|
||
# direct, other damage, loss, or other issues arising in any way out
|
||
# of dealing in the work, even if advised of the possibility of such
|
||
# damage or existence of a defect, except proven that it results out
|
||
# of said person’s immediate fault when using the work as intended.
|
||
#-
|
||
# You may also want to test IFS with the script at
|
||
# http://www.research.att.com/~gsf/public/ifs.sh
|
||
#
|
||
# More testsuites at:
|
||
# http://svnweb.freebsd.org/base/head/bin/test/tests/legacy_test.sh?view=co&content-type=text%2Fplain
|
||
#
|
||
# Integrated testsuites from:
|
||
# (2013/12/02 20:39:44) http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date
|
||
|
||
expected-stdout:
|
||
@(#)MIRBSD KSH R56 2017/08/29
|
||
description:
|
||
Check base version of full shell
|
||
stdin:
|
||
echo ${KSH_VERSION%%' +'*}
|
||
name: KSH_VERSION
|
||
category: !shell:legacy-yes
|
||
---
|
||
expected-stdout:
|
||
@(#)LEGACY KSH R56 2017/08/29
|
||
description:
|
||
Check base version of legacy shell
|
||
stdin:
|
||
echo ${KSH_VERSION%%' +'*}
|
||
name: KSH_VERSION-legacy
|
||
category: !shell:legacy-no
|
||
---
|
||
name: KSH_VERSION-ascii
|
||
description:
|
||
Check that the shell version tag does not include EBCDIC
|
||
category: !shell:ebcdic-yes
|
||
stdin:
|
||
for x in $KSH_VERSION; do
|
||
[[ $x = '+EBCDIC' ]] && exit 1
|
||
done
|
||
exit 0
|
||
---
|
||
name: KSH_VERSION-ebcdic
|
||
description:
|
||
Check that the shell version tag includes EBCDIC
|
||
category: !shell:ebcdic-no
|
||
stdin:
|
||
for x in $KSH_VERSION; do
|
||
[[ $x = '+EBCDIC' ]] && exit 0
|
||
done
|
||
exit 1
|
||
---
|
||
name: KSH_VERSION-binmode
|
||
description:
|
||
Check that the shell version tag does not include TEXTMODE
|
||
category: !shell:textmode-yes
|
||
stdin:
|
||
for x in $KSH_VERSION; do
|
||
[[ $x = '+TEXTMODE' ]] && exit 1
|
||
done
|
||
exit 0
|
||
---
|
||
name: KSH_VERSION-textmode
|
||
description:
|
||
Check that the shell version tag includes TEXTMODE
|
||
category: !shell:textmode-no
|
||
stdin:
|
||
for x in $KSH_VERSION; do
|
||
[[ $x = '+TEXTMODE' ]] && exit 0
|
||
done
|
||
exit 1
|
||
---
|
||
name: selftest-1
|
||
description:
|
||
Regression test self-testing
|
||
stdin:
|
||
echo ${foo:-baz}
|
||
expected-stdout:
|
||
baz
|
||
---
|
||
name: selftest-2
|
||
description:
|
||
Regression test self-testing
|
||
env-setup: !foo=bar!
|
||
stdin:
|
||
echo ${foo:-baz}
|
||
expected-stdout:
|
||
bar
|
||
---
|
||
name: selftest-3
|
||
description:
|
||
Regression test self-testing
|
||
env-setup: !ENV=fnord!
|
||
stdin:
|
||
echo "<$ENV>"
|
||
expected-stdout:
|
||
<fnord>
|
||
---
|
||
name: selftest-exec
|
||
description:
|
||
Ensure that the test run directory (default /tmp but can be changed
|
||
with check.pl flag -T or test.sh $TMPDIR) is not mounted noexec, as
|
||
we execute scripts from the scratch directory during several tests.
|
||
stdin:
|
||
print '#!'"$__progname"'\necho tf' >lq
|
||
chmod +x lq
|
||
./lq
|
||
expected-stdout:
|
||
tf
|
||
---
|
||
name: selftest-env
|
||
description:
|
||
Just output the environment variables set (always fails)
|
||
category: disabled
|
||
stdin:
|
||
set
|
||
---
|
||
name: selftest-direct-builtin-call
|
||
description:
|
||
Check that direct builtin calls work
|
||
stdin:
|
||
ln -s "$__progname" cat || cp "$__progname" cat
|
||
ln -s "$__progname" echo || cp "$__progname" echo
|
||
./echo -c 'echo foo' | ./cat -u
|
||
expected-stdout:
|
||
-c echo foo
|
||
---
|
||
name: selftest-pathsep-unix
|
||
description:
|
||
Check that $PATHSEP is set correctly.
|
||
category: !os:os2
|
||
stdin:
|
||
PATHSEP=.; export PATHSEP
|
||
"$__progname" -c 'print -r -- $PATHSEP'
|
||
expected-stdout:
|
||
:
|
||
---
|
||
name: selftest-pathsep-dospath
|
||
description:
|
||
Check that $PATHSEP is set correctly.
|
||
category: os:os2
|
||
stdin:
|
||
PATHSEP=.; export PATHSEP
|
||
"$__progname" -c 'print -r -- $PATHSEP'
|
||
expected-stdout:
|
||
;
|
||
---
|
||
name: alias-1
|
||
description:
|
||
Check that recursion is detected/avoided in aliases.
|
||
stdin:
|
||
alias fooBar=fooBar
|
||
fooBar
|
||
exit 0
|
||
expected-stderr-pattern:
|
||
/fooBar.*not found.*/
|
||
---
|
||
name: alias-2
|
||
description:
|
||
Check that recursion is detected/avoided in aliases.
|
||
stdin:
|
||
alias fooBar=barFoo
|
||
alias barFoo=fooBar
|
||
fooBar
|
||
barFoo
|
||
exit 0
|
||
expected-stderr-pattern:
|
||
/fooBar.*not found.*\n.*barFoo.*not found/
|
||
---
|
||
name: alias-3
|
||
description:
|
||
Check that recursion is detected/avoided in aliases.
|
||
stdin:
|
||
alias Echo='echo '
|
||
alias fooBar=barFoo
|
||
alias barFoo=fooBar
|
||
Echo fooBar
|
||
unalias barFoo
|
||
Echo fooBar
|
||
expected-stdout:
|
||
fooBar
|
||
barFoo
|
||
---
|
||
name: alias-4
|
||
description:
|
||
Check that alias expansion isn't done on keywords (in keyword
|
||
postitions).
|
||
stdin:
|
||
alias Echo='echo '
|
||
alias while=While
|
||
while false; do echo hi ; done
|
||
Echo while
|
||
expected-stdout:
|
||
While
|
||
---
|
||
name: alias-5
|
||
description:
|
||
Check that alias expansion done after alias with trailing space.
|
||
stdin:
|
||
alias Echo='echo '
|
||
alias foo='bar stuff '
|
||
alias bar='Bar1 Bar2 '
|
||
alias stuff='Stuff'
|
||
alias blah='Blah'
|
||
Echo foo blah
|
||
expected-stdout:
|
||
Bar1 Bar2 Stuff Blah
|
||
---
|
||
name: alias-6
|
||
description:
|
||
Check that alias expansion done after alias with trailing space.
|
||
stdin:
|
||
alias Echo='echo '
|
||
alias foo='bar bar'
|
||
alias bar='Bar '
|
||
alias blah=Blah
|
||
Echo foo blah
|
||
expected-stdout:
|
||
Bar Bar Blah
|
||
---
|
||
name: alias-7
|
||
description:
|
||
Check that alias expansion done after alias with trailing space
|
||
after a keyword.
|
||
stdin:
|
||
alias X='case '
|
||
alias Y=Z
|
||
X Y in 'Y') echo is y ;; Z) echo is z ;; esac
|
||
expected-stdout:
|
||
is z
|
||
---
|
||
name: alias-8
|
||
description:
|
||
Check that newlines in an alias don't cause the command to be lost.
|
||
stdin:
|
||
alias foo='
|
||
|
||
|
||
echo hi
|
||
|
||
|
||
|
||
echo there
|
||
|
||
|
||
'
|
||
foo
|
||
expected-stdout:
|
||
hi
|
||
there
|
||
---
|
||
name: alias-9
|
||
description:
|
||
Check that recursion is detected/avoided in aliases.
|
||
This check fails for slow machines or Cygwin, raise
|
||
the time-limit clause (e.g. to 7) if this occurs.
|
||
time-limit: 3
|
||
stdin:
|
||
print '#!'"$__progname"'\necho tf' >lq
|
||
chmod +x lq
|
||
PATH=$PWD$PATHSEP$PATH
|
||
alias lq=lq
|
||
lq
|
||
echo = now
|
||
i=`lq`
|
||
print -r -- $i
|
||
echo = out
|
||
exit 0
|
||
expected-stdout:
|
||
tf
|
||
= now
|
||
tf
|
||
= out
|
||
---
|
||
name: alias-10
|
||
description:
|
||
Check that recursion is detected/avoided in aliases.
|
||
Regression, introduced during an old bugfix.
|
||
stdin:
|
||
alias foo='print hello '
|
||
alias bar='foo world'
|
||
echo $(bar)
|
||
expected-stdout:
|
||
hello world
|
||
---
|
||
name: alias-11
|
||
description:
|
||
Check that special argument handling still applies with escaped aliases
|
||
stdin:
|
||
alias local1='\typeset'
|
||
alias local2='\\builtin typeset'
|
||
function fooa {
|
||
local1 x=$1 y=z
|
||
print -r -- "$x,$y"
|
||
}
|
||
function foob {
|
||
local2 x=$1 y=z
|
||
print -r -- "$x,$y"
|
||
}
|
||
x=1 y=2; fooa 'bar - baz'
|
||
x=1 y=2; foob 'bar - baz'
|
||
expected-stdout:
|
||
bar - baz,z
|
||
bar - baz,z
|
||
---
|
||
name: alias-12
|
||
description:
|
||
Something weird from Martijn Dekker
|
||
stdin:
|
||
alias echo=print
|
||
x() { echo a; (echo b); x=$(echo c); }
|
||
typeset -f x
|
||
alias OPEN='{' CLOSE='};'
|
||
{ OPEN echo hi1; CLOSE }
|
||
var=`{ OPEN echo hi2; CLOSE }` && echo "$var"
|
||
var=$({ OPEN echo hi3; CLOSE }) && echo "$var"
|
||
expected-stdout:
|
||
x() {
|
||
\print a
|
||
( \print b )
|
||
x=$(\print c )
|
||
}
|
||
hi1
|
||
hi2
|
||
hi3
|
||
---
|
||
name: arith-compound
|
||
description:
|
||
Check that arithmetic expressions are compound constructs
|
||
stdin:
|
||
{ ! (( 0$(cat >&2) )) <<<1; } <<<2
|
||
expected-stderr:
|
||
1
|
||
---
|
||
name: arith-lazy-1
|
||
description:
|
||
Check that only one side of ternary operator is evaluated
|
||
stdin:
|
||
x=i+=2
|
||
y=j+=2
|
||
typeset -i i=1 j=1
|
||
echo $((1 ? 20 : (x+=2)))
|
||
echo $i,$x
|
||
echo $((0 ? (y+=2) : 30))
|
||
echo $j,$y
|
||
expected-stdout:
|
||
20
|
||
1,i+=2
|
||
30
|
||
1,j+=2
|
||
---
|
||
name: arith-lazy-2
|
||
description:
|
||
Check that assignments not done on non-evaluated side of ternary
|
||
operator
|
||
stdin:
|
||
x=i+=2
|
||
y=j+=2
|
||
typeset -i i=1 j=1
|
||
echo $((1 ? 20 : (x+=2)))
|
||
echo $i,$x
|
||
echo $((0 ? (y+=2) : 30))
|
||
echo $i,$y
|
||
expected-stdout:
|
||
20
|
||
1,i+=2
|
||
30
|
||
1,j+=2
|
||
---
|
||
name: arith-lazy-3
|
||
description:
|
||
Check that assignments not done on non-evaluated side of ternary
|
||
operator and this construct is parsed correctly (Debian #445651)
|
||
stdin:
|
||
x=4
|
||
y=$((0 ? x=1 : 2))
|
||
echo = $x $y =
|
||
expected-stdout:
|
||
= 4 2 =
|
||
---
|
||
name: arith-lazy-4
|
||
description:
|
||
Check that preun/postun not done on non-evaluated side of ternary
|
||
operator
|
||
stdin:
|
||
(( m = n = 0, 1 ? n++ : m++ ? 2 : 3 ))
|
||
echo "($n, $m)"
|
||
m=0; echo $(( 0 ? ++m : 2 )); echo $m
|
||
m=0; echo $(( 0 ? m++ : 2 )); echo $m
|
||
expected-stdout:
|
||
(1, 0)
|
||
2
|
||
0
|
||
2
|
||
0
|
||
---
|
||
name: arith-lazy-5-arr-n
|
||
description: Check lazy evaluation with side effects
|
||
stdin:
|
||
a=0; echo "$((0&&b[a++],a))"
|
||
expected-stdout:
|
||
0
|
||
---
|
||
name: arith-lazy-5-arr-p
|
||
description: Check lazy evaluation with side effects
|
||
stdin:
|
||
a=0; echo "$((0&&(b[a++]),a))"
|
||
expected-stdout:
|
||
0
|
||
---
|
||
name: arith-lazy-5-str-n
|
||
description: Check lazy evaluation with side effects
|
||
stdin:
|
||
a=0 b=a++; ((0&&b)); echo $a
|
||
expected-stdout:
|
||
0
|
||
---
|
||
name: arith-lazy-5-str-p
|
||
description: Check lazy evaluation with side effects
|
||
stdin:
|
||
a=0 b=a++; ((0&&(b))); echo $a
|
||
expected-stdout:
|
||
0
|
||
---
|
||
name: arith-lazy-5-tern-l-n
|
||
description: Check lazy evaluation with side effects
|
||
stdin:
|
||
a=0; echo "$((0?b[a++]:999,a))"
|
||
expected-stdout:
|
||
0
|
||
---
|
||
name: arith-lazy-5-tern-l-p
|
||
description: Check lazy evaluation with side effects
|
||
stdin:
|
||
a=0; echo "$((0?(b[a++]):999,a))"
|
||
expected-stdout:
|
||
0
|
||
---
|
||
name: arith-lazy-5-tern-r-n
|
||
description: Check lazy evaluation with side effects
|
||
stdin:
|
||
a=0; echo "$((1?999:b[a++],a))"
|
||
expected-stdout:
|
||
0
|
||
---
|
||
name: arith-lazy-5-tern-r-p
|
||
description: Check lazy evaluation with side effects
|
||
stdin:
|
||
a=0; echo "$((1?999:(b[a++]),a))"
|
||
expected-stdout:
|
||
0
|
||
---
|
||
name: arith-ternary-prec-1
|
||
description:
|
||
Check precedence of ternary operator vs assignment
|
||
stdin:
|
||
typeset -i x=2
|
||
y=$((1 ? 20 : x+=2))
|
||
expected-exit: e != 0
|
||
expected-stderr-pattern:
|
||
/.*:.*1 \? 20 : x\+=2.*lvalue.*\n$/
|
||
---
|
||
name: arith-ternary-prec-2
|
||
description:
|
||
Check precedence of ternary operator vs assignment
|
||
stdin:
|
||
typeset -i x=2
|
||
echo $((0 ? x+=2 : 20))
|
||
expected-stdout:
|
||
20
|
||
---
|
||
name: arith-prec-1
|
||
description:
|
||
Prove arithmetic expressions with embedded parameter
|
||
substitutions cannot be parsed ahead of time
|
||
stdin:
|
||
a='3 + 4'
|
||
print 1 $((2 * a)) .
|
||
print 2 $((2 * $a)) .
|
||
expected-stdout:
|
||
1 14 .
|
||
2 10 .
|
||
---
|
||
name: arith-div-assoc-1
|
||
description:
|
||
Check associativity of division operator
|
||
stdin:
|
||
echo $((20 / 2 / 2))
|
||
expected-stdout:
|
||
5
|
||
---
|
||
name: arith-div-byzero
|
||
description:
|
||
Check division by zero errors out
|
||
stdin:
|
||
x=$(echo $((1 / 0)))
|
||
echo =$?:$x.
|
||
expected-stdout:
|
||
=1:.
|
||
expected-stderr-pattern:
|
||
/.*divisor/
|
||
---
|
||
name: arith-div-intmin-by-minusone
|
||
description:
|
||
Check division overflow wraps around silently
|
||
category: int:32
|
||
stdin:
|
||
echo signed:$((-2147483648 / -1))r$((-2147483648 % -1)).
|
||
echo unsigned:$((# -2147483648 / -1))r$((# -2147483648 % -1)).
|
||
expected-stdout:
|
||
signed:-2147483648r0.
|
||
unsigned:0r2147483648.
|
||
---
|
||
name: arith-div-intmin-by-minusone-64
|
||
description:
|
||
Check division overflow wraps around silently
|
||
category: int:64
|
||
stdin:
|
||
echo signed:$((-9223372036854775808 / -1))r$((-9223372036854775808 % -1)).
|
||
echo unsigned:$((# -9223372036854775808 / -1))r$((# -9223372036854775808 % -1)).
|
||
expected-stdout:
|
||
signed:-9223372036854775808r0.
|
||
unsigned:0r9223372036854775808.
|
||
---
|
||
name: arith-assop-assoc-1
|
||
description:
|
||
Check associativity of assignment-operator operator
|
||
stdin:
|
||
typeset -i i=1 j=2 k=3
|
||
echo $((i += j += k))
|
||
echo $i,$j,$k
|
||
expected-stdout:
|
||
6
|
||
6,5,3
|
||
---
|
||
name: arith-mandatory
|
||
description:
|
||
Passing of this test is *mandatory* for a valid mksh executable!
|
||
category: shell:legacy-no
|
||
stdin:
|
||
typeset -i sari=0
|
||
typeset -Ui uari=0
|
||
typeset -i x=0
|
||
print -r -- $((x++)):$sari=$uari. #0
|
||
let --sari --uari
|
||
print -r -- $((x++)):$sari=$uari. #1
|
||
sari=2147483647 uari=2147483647
|
||
print -r -- $((x++)):$sari=$uari. #2
|
||
let ++sari ++uari
|
||
print -r -- $((x++)):$sari=$uari. #3
|
||
let --sari --uari
|
||
let 'sari *= 2' 'uari *= 2'
|
||
let ++sari ++uari
|
||
print -r -- $((x++)):$sari=$uari. #4
|
||
let ++sari ++uari
|
||
print -r -- $((x++)):$sari=$uari. #5
|
||
sari=-2147483648 uari=-2147483648
|
||
print -r -- $((x++)):$sari=$uari. #6
|
||
let --sari --uari
|
||
print -r -- $((x++)):$sari=$uari. #7
|
||
(( sari = -5 >> 1 ))
|
||
((# uari = -5 >> 1 ))
|
||
print -r -- $((x++)):$sari=$uari. #8
|
||
(( sari = -2 ))
|
||
((# uari = sari ))
|
||
print -r -- $((x++)):$sari=$uari. #9
|
||
expected-stdout:
|
||
0:0=0.
|
||
1:-1=4294967295.
|
||
2:2147483647=2147483647.
|
||
3:-2147483648=2147483648.
|
||
4:-1=4294967295.
|
||
5:0=0.
|
||
6:-2147483648=2147483648.
|
||
7:2147483647=2147483647.
|
||
8:-3=2147483645.
|
||
9:-2=4294967294.
|
||
---
|
||
name: arith-unsigned-1
|
||
description:
|
||
Check if unsigned arithmetics work
|
||
category: int:32
|
||
stdin:
|
||
# signed vs unsigned
|
||
echo x1 $((-1)) $((#-1))
|
||
# calculating
|
||
typeset -i vs
|
||
typeset -Ui vu
|
||
vs=4123456789; vu=4123456789
|
||
echo x2 $vs $vu
|
||
(( vs %= 2147483647 ))
|
||
(( vu %= 2147483647 ))
|
||
echo x3 $vs $vu
|
||
vs=4123456789; vu=4123456789
|
||
(( # vs %= 2147483647 ))
|
||
(( # vu %= 2147483647 ))
|
||
echo x4 $vs $vu
|
||
# make sure the calculation does not change unsigned flag
|
||
vs=4123456789; vu=4123456789
|
||
echo x5 $vs $vu
|
||
# short form
|
||
echo x6 $((# vs % 2147483647)) $((# vu % 2147483647))
|
||
# array refs
|
||
set -A va
|
||
va[1975973142]=right
|
||
va[4123456789]=wrong
|
||
echo x7 ${va[#4123456789%2147483647]}
|
||
# make sure multiple calculations don't interfere with each other
|
||
let '# mca = -4 % -2' ' mcb = -4 % -2'
|
||
echo x8 $mca $mcb
|
||
expected-stdout:
|
||
x1 -1 4294967295
|
||
x2 -171510507 4123456789
|
||
x3 -171510507 4123456789
|
||
x4 1975973142 1975973142
|
||
x5 -171510507 4123456789
|
||
x6 1975973142 1975973142
|
||
x7 right
|
||
x8 -4 0
|
||
---
|
||
name: arith-limit32-1
|
||
description:
|
||
Check if arithmetics are 32 bit
|
||
category: int:32
|
||
stdin:
|
||
# signed vs unsigned
|
||
echo x1 $((-1)) $((#-1))
|
||
# calculating
|
||
typeset -i vs
|
||
typeset -Ui vu
|
||
vs=2147483647; vu=2147483647
|
||
echo x2 $vs $vu
|
||
let vs++ vu++
|
||
echo x3 $vs $vu
|
||
vs=4294967295; vu=4294967295
|
||
echo x4 $vs $vu
|
||
let vs++ vu++
|
||
echo x5 $vs $vu
|
||
let vs++ vu++
|
||
echo x6 $vs $vu
|
||
expected-stdout:
|
||
x1 -1 4294967295
|
||
x2 2147483647 2147483647
|
||
x3 -2147483648 2147483648
|
||
x4 -1 4294967295
|
||
x5 0 0
|
||
x6 1 1
|
||
---
|
||
name: arith-limit64-1
|
||
description:
|
||
Check if arithmetics are 64 bit
|
||
category: int:64
|
||
stdin:
|
||
# signed vs unsigned
|
||
echo x1 $((-1)) $((#-1))
|
||
# calculating
|
||
typeset -i vs
|
||
typeset -Ui vu
|
||
vs=9223372036854775807; vu=9223372036854775807
|
||
echo x2 $vs $vu
|
||
let vs++ vu++
|
||
echo x3 $vs $vu
|
||
vs=18446744073709551615; vu=18446744073709551615
|
||
echo x4 $vs $vu
|
||
let vs++ vu++
|
||
echo x5 $vs $vu
|
||
let vs++ vu++
|
||
echo x6 $vs $vu
|
||
expected-stdout:
|
||
x1 -1 18446744073709551615
|
||
x2 9223372036854775807 9223372036854775807
|
||
x3 -9223372036854775808 9223372036854775808
|
||
x4 -1 18446744073709551615
|
||
x5 0 0
|
||
x6 1 1
|
||
---
|
||
name: bksl-nl-ign-1
|
||
description:
|
||
Check that \newline is not collapsed after #
|
||
stdin:
|
||
echo hi #there \
|
||
echo folks
|
||
expected-stdout:
|
||
hi
|
||
folks
|
||
---
|
||
name: bksl-nl-ign-2
|
||
description:
|
||
Check that \newline is not collapsed inside single quotes
|
||
stdin:
|
||
echo 'hi \
|
||
there'
|
||
echo folks
|
||
expected-stdout:
|
||
hi \
|
||
there
|
||
folks
|
||
---
|
||
name: bksl-nl-ign-3
|
||
description:
|
||
Check that \newline is not collapsed inside single quotes
|
||
stdin:
|
||
cat << \EOF
|
||
hi \
|
||
there
|
||
EOF
|
||
expected-stdout:
|
||
hi \
|
||
there
|
||
---
|
||
name: bksl-nl-ign-4
|
||
description:
|
||
Check interaction of aliases, single quotes and here-documents
|
||
with backslash-newline
|
||
(don't know what POSIX has to say about this)
|
||
stdin:
|
||
a=2
|
||
alias x='echo hi
|
||
cat << "EOF"
|
||
foo\
|
||
bar
|
||
some'
|
||
x
|
||
more\
|
||
stuff$a
|
||
EOF
|
||
expected-stdout:
|
||
hi
|
||
foo\
|
||
bar
|
||
some
|
||
more\
|
||
stuff$a
|
||
---
|
||
name: bksl-nl-ign-5
|
||
description:
|
||
Check what happens with backslash at end of input
|
||
(the old Bourne shell trashes them; so do we)
|
||
stdin: !
|
||
echo `echo foo\\`bar
|
||
echo hi\
|
||
expected-stdout:
|
||
foobar
|
||
hi
|
||
---
|
||
#
|
||
# Places \newline should be collapsed
|
||
#
|
||
name: bksl-nl-1
|
||
description:
|
||
Check that \newline is collapsed before, in the middle of, and
|
||
after words
|
||
stdin:
|
||
\
|
||
echo hi\
|
||
There, \
|
||
folks
|
||
expected-stdout:
|
||
hiThere, folks
|
||
---
|
||
name: bksl-nl-2
|
||
description:
|
||
Check that \newline is collapsed in $ sequences
|
||
(ksh93 fails this)
|
||
stdin:
|
||
a=12
|
||
ab=19
|
||
echo $\
|
||
a
|
||
echo $a\
|
||
b
|
||
echo $\
|
||
{a}
|
||
echo ${a\
|
||
b}
|
||
echo ${ab\
|
||
}
|
||
expected-stdout:
|
||
12
|
||
19
|
||
12
|
||
19
|
||
19
|
||
---
|
||
name: bksl-nl-3
|
||
description:
|
||
Check that \newline is collapsed in $(..) and `...` sequences
|
||
(ksh93 fails this)
|
||
stdin:
|
||
echo $\
|
||
(echo foobar1)
|
||
echo $(\
|
||
echo foobar2)
|
||
echo $(echo foo\
|
||
bar3)
|
||
echo $(echo foobar4\
|
||
)
|
||
echo `
|
||
echo stuff1`
|
||
echo `echo st\
|
||
uff2`
|
||
expected-stdout:
|
||
foobar1
|
||
foobar2
|
||
foobar3
|
||
foobar4
|
||
stuff1
|
||
stuff2
|
||
---
|
||
name: bksl-nl-4
|
||
description:
|
||
Check that \newline is collapsed in $((..)) sequences
|
||
(ksh93 fails this)
|
||
stdin:
|
||
echo $\
|
||
((1+2))
|
||
echo $(\
|
||
(1+2+3))
|
||
echo $((\
|
||
1+2+3+4))
|
||
echo $((1+\
|
||
2+3+4+5))
|
||
echo $((1+2+3+4+5+6)\
|
||
)
|
||
expected-stdout:
|
||
3
|
||
6
|
||
10
|
||
15
|
||
21
|
||
---
|
||
name: bksl-nl-5
|
||
description:
|
||
Check that \newline is collapsed in double quoted strings
|
||
stdin:
|
||
echo "\
|
||
hi"
|
||
echo "foo\
|
||
bar"
|
||
echo "folks\
|
||
"
|
||
expected-stdout:
|
||
hi
|
||
foobar
|
||
folks
|
||
---
|
||
name: bksl-nl-6
|
||
description:
|
||
Check that \newline is collapsed in here document delimiters
|
||
(ksh93 fails second part of this)
|
||
stdin:
|
||
a=12
|
||
cat << EO\
|
||
F
|
||
a=$a
|
||
foo\
|
||
bar
|
||
EOF
|
||
cat << E_O_F
|
||
foo
|
||
E_O_\
|
||
F
|
||
echo done
|
||
expected-stdout:
|
||
a=12
|
||
foobar
|
||
foo
|
||
done
|
||
---
|
||
name: bksl-nl-7
|
||
description:
|
||
Check that \newline is collapsed in double-quoted here-document
|
||
delimiter.
|
||
stdin:
|
||
a=12
|
||
cat << "EO\
|
||
F"
|
||
a=$a
|
||
foo\
|
||
bar
|
||
EOF
|
||
echo done
|
||
expected-stdout:
|
||
a=$a
|
||
foo\
|
||
bar
|
||
done
|
||
---
|
||
name: bksl-nl-8
|
||
description:
|
||
Check that \newline is collapsed in various 2+ character tokens
|
||
delimiter.
|
||
(ksh93 fails this)
|
||
stdin:
|
||
echo hi &\
|
||
& echo there
|
||
echo foo |\
|
||
| echo bar
|
||
cat <\
|
||
< EOF
|
||
stuff
|
||
EOF
|
||
cat <\
|
||
<\
|
||
- EOF
|
||
more stuff
|
||
EOF
|
||
cat <<\
|
||
EOF
|
||
abcdef
|
||
EOF
|
||
echo hi >\
|
||
> /dev/null
|
||
echo $?
|
||
i=1
|
||
case $i in
|
||
(\
|
||
x|\
|
||
1\
|
||
) echo hi;\
|
||
;
|
||
(*) echo oops
|
||
esac
|
||
expected-stdout:
|
||
hi
|
||
there
|
||
foo
|
||
stuff
|
||
more stuff
|
||
abcdef
|
||
0
|
||
hi
|
||
---
|
||
name: bksl-nl-9
|
||
description:
|
||
Check that \ at the end of an alias is collapsed when followed
|
||
by a newline
|
||
(don't know what POSIX has to say about this)
|
||
stdin:
|
||
alias x='echo hi\'
|
||
x
|
||
echo there
|
||
expected-stdout:
|
||
hiecho there
|
||
---
|
||
name: bksl-nl-10
|
||
description:
|
||
Check that \newline in a keyword is collapsed
|
||
stdin:
|
||
i\
|
||
f true; then\
|
||
echo pass; el\
|
||
se echo fail; fi
|
||
expected-stdout:
|
||
pass
|
||
---
|
||
#
|
||
# Places \newline should be collapsed (ksh extensions)
|
||
#
|
||
name: bksl-nl-ksh-1
|
||
description:
|
||
Check that \newline is collapsed in extended globbing
|
||
(ksh93 fails this)
|
||
stdin:
|
||
xxx=foo
|
||
case $xxx in
|
||
(f*\
|
||
(\
|
||
o\
|
||
)\
|
||
) echo ok ;;
|
||
*) echo bad
|
||
esac
|
||
expected-stdout:
|
||
ok
|
||
---
|
||
name: bksl-nl-ksh-2
|
||
description:
|
||
Check that \newline is collapsed in ((...)) expressions
|
||
(ksh93 fails this)
|
||
stdin:
|
||
i=1
|
||
(\
|
||
(\
|
||
i=i+2\
|
||
)\
|
||
)
|
||
echo $i
|
||
expected-stdout:
|
||
3
|
||
---
|
||
name: break-1
|
||
description:
|
||
See if break breaks out of loops
|
||
stdin:
|
||
for i in a b c; do echo $i; break; echo bad-$i; done
|
||
echo end-1
|
||
for i in a b c; do echo $i; break 1; echo bad-$i; done
|
||
echo end-2
|
||
for i in a b c; do
|
||
for j in x y z; do
|
||
echo $i:$j
|
||
break
|
||
echo bad-$i
|
||
done
|
||
echo end-$i
|
||
done
|
||
echo end-3
|
||
for i in a b c; do echo $i; eval break; echo bad-$i; done
|
||
echo end-4
|
||
expected-stdout:
|
||
a
|
||
end-1
|
||
a
|
||
end-2
|
||
a:x
|
||
end-a
|
||
b:x
|
||
end-b
|
||
c:x
|
||
end-c
|
||
end-3
|
||
a
|
||
end-4
|
||
---
|
||
name: break-2
|
||
description:
|
||
See if break breaks out of nested loops
|
||
stdin:
|
||
for i in a b c; do
|
||
for j in x y z; do
|
||
echo $i:$j
|
||
break 2
|
||
echo bad-$i
|
||
done
|
||
echo end-$i
|
||
done
|
||
echo end
|
||
expected-stdout:
|
||
a:x
|
||
end
|
||
---
|
||
name: break-3
|
||
description:
|
||
What if break used outside of any loops
|
||
(ksh88,ksh93 don't print error messages here)
|
||
stdin:
|
||
break
|
||
expected-stderr-pattern:
|
||
/.*break.*/
|
||
---
|
||
name: break-4
|
||
description:
|
||
What if break N used when only N-1 loops
|
||
(ksh88,ksh93 don't print error messages here)
|
||
stdin:
|
||
for i in a b c; do echo $i; break 2; echo bad-$i; done
|
||
echo end
|
||
expected-stdout:
|
||
a
|
||
end
|
||
expected-stderr-pattern:
|
||
/.*break.*/
|
||
---
|
||
name: break-5
|
||
description:
|
||
Error if break argument isn't a number
|
||
stdin:
|
||
for i in a b c; do echo $i; break abc; echo more-$i; done
|
||
echo end
|
||
expected-stdout:
|
||
a
|
||
expected-exit: e != 0
|
||
expected-stderr-pattern:
|
||
/.*break.*/
|
||
---
|
||
name: continue-1
|
||
description:
|
||
See if continue continues loops
|
||
stdin:
|
||
for i in a b c; do echo $i; continue; echo bad-$i ; done
|
||
echo end-1
|
||
for i in a b c; do echo $i; continue 1; echo bad-$i; done
|
||
echo end-2
|
||
for i in a b c; do
|
||
for j in x y z; do
|
||
echo $i:$j
|
||
continue
|
||
echo bad-$i-$j
|
||
done
|
||
echo end-$i
|
||
done
|
||
echo end-3
|
||
for i in a b c; do echo $i; eval continue; echo bad-$i ; done
|
||
echo end-4
|
||
expected-stdout:
|
||
a
|
||
b
|
||
c
|
||
end-1
|
||
a
|
||
b
|
||
c
|
||
end-2
|
||
a:x
|
||
a:y
|
||
a:z
|
||
end-a
|
||
b:x
|
||
b:y
|
||
b:z
|
||
end-b
|
||
c:x
|
||
c:y
|
||
c:z
|
||
end-c
|
||
end-3
|
||
a
|
||
b
|
||
c
|
||
end-4
|
||
---
|
||
name: continue-2
|
||
description:
|
||
See if continue breaks out of nested loops
|
||
stdin:
|
||
for i in a b c; do
|
||
for j in x y z; do
|
||
echo $i:$j
|
||
continue 2
|
||
echo bad-$i-$j
|
||
done
|
||
echo end-$i
|
||
done
|
||
echo end
|
||
expected-stdout:
|
||
a:x
|
||
b:x
|
||
c:x
|
||
end
|
||
---
|
||
name: continue-3
|
||
description:
|
||
What if continue used outside of any loops
|
||
(ksh88,ksh93 don't print error messages here)
|
||
stdin:
|
||
continue
|
||
expected-stderr-pattern:
|
||
/.*continue.*/
|
||
---
|
||
name: continue-4
|
||
description:
|
||
What if continue N used when only N-1 loops
|
||
(ksh88,ksh93 don't print error messages here)
|
||
stdin:
|
||
for i in a b c; do echo $i; continue 2; echo bad-$i; done
|
||
echo end
|
||
expected-stdout:
|
||
a
|
||
b
|
||
c
|
||
end
|
||
expected-stderr-pattern:
|
||
/.*continue.*/
|
||
---
|
||
name: continue-5
|
||
description:
|
||
Error if continue argument isn't a number
|
||
stdin:
|
||
for i in a b c; do echo $i; continue abc; echo more-$i; done
|
||
echo end
|
||
expected-stdout:
|
||
a
|
||
expected-exit: e != 0
|
||
expected-stderr-pattern:
|
||
/.*continue.*/
|
||
---
|
||
name: cd-history
|
||
description:
|
||
Test someone's CD history package (uses arrays)
|
||
stdin:
|
||
# go to known place before doing anything
|
||
cd /
|
||
|
||
alias cd=_cd
|
||
function _cd
|
||
{
|
||
typeset -i cdlen i
|
||
typeset t
|
||
|
||
if [ $# -eq 0 ]
|
||
then
|
||
set -- $HOME
|
||
fi
|
||
|
||
if [ "$CDHISTFILE" -a -r "$CDHISTFILE" ] # if directory history exists
|
||
then
|
||
typeset CDHIST
|
||
i=-1
|
||
while read -r t # read directory history file
|
||
do
|
||
CDHIST[i=i+1]=$t
|
||
done <$CDHISTFILE
|
||
fi
|
||
|
||
if [ "${CDHIST[0]}" != "$PWD" -a "$PWD" != "" ]
|
||
then
|
||
_cdins # insert $PWD into cd history
|
||
fi
|
||
|
||
cdlen=${#CDHIST[*]} # number of elements in history
|
||
|
||
case "$@" in
|
||
-) # cd to new dir
|
||
if [ "$OLDPWD" = "" ] && ((cdlen>1))
|
||
then
|
||
'print' ${CDHIST[1]}
|
||
'cd' ${CDHIST[1]}
|
||
_pwd
|
||
else
|
||
'cd' $@
|
||
_pwd
|
||
fi
|
||
;;
|
||
-l) # print directory list
|
||
typeset -R3 num
|
||
((i=cdlen))
|
||
while (((i=i-1)>=0))
|
||
do
|
||
num=$i
|
||
'print' "$num ${CDHIST[i]}"
|
||
done
|
||
return
|
||
;;
|
||
-[0-9]|-[0-9][0-9]) # cd to dir in list
|
||
if (((i=${1#-})<cdlen))
|
||
then
|
||
'print' ${CDHIST[i]}
|
||
'cd' ${CDHIST[i]}
|
||
_pwd
|
||
else
|
||
'cd' $@
|
||
_pwd
|
||
fi
|
||
;;
|
||
-*) # cd to matched dir in list
|
||
t=${1#-}
|
||
i=1
|
||
while ((i<cdlen))
|
||
do
|
||
case ${CDHIST[i]} in
|
||
*$t*)
|
||
'print' ${CDHIST[i]}
|
||
'cd' ${CDHIST[i]}
|
||
_pwd
|
||
break
|
||
;;
|
||
esac
|
||
((i=i+1))
|
||
done
|
||
if ((i>=cdlen))
|
||
then
|
||
'cd' $@
|
||
_pwd
|
||
fi
|
||
;;
|
||
*) # cd to new dir
|
||
'cd' $@
|
||
_pwd
|
||
;;
|
||
esac
|
||
|
||
_cdins # insert $PWD into cd history
|
||
|
||
if [ "$CDHISTFILE" ]
|
||
then
|
||
cdlen=${#CDHIST[*]} # number of elements in history
|
||
|
||
i=0
|
||
while ((i<cdlen))
|
||
do
|
||
'print' -r ${CDHIST[i]} # update directory history
|
||
((i=i+1))
|
||
done >$CDHISTFILE
|
||
fi
|
||
}
|
||
|
||
function _cdins # insert $PWD into cd history
|
||
{ # meant to be called only by _cd
|
||
typeset -i i
|
||
|
||
((i=0))
|
||
while ((i<${#CDHIST[*]})) # see if dir is already in list
|
||
do
|
||
if [ "${CDHIST[$i]}" = "$PWD" ]
|
||
then
|
||
break
|
||
fi
|
||
((i=i+1))
|
||
done
|
||
|
||
if ((i>22)) # limit max size of list
|
||
then
|
||
i=22
|
||
fi
|
||
|
||
while (((i=i-1)>=0)) # bump old dirs in list
|
||
do
|
||
CDHIST[i+1]=${CDHIST[i]}
|
||
done
|
||
|
||
CDHIST[0]=$PWD # insert new directory in list
|
||
}
|
||
|
||
|
||
function _pwd
|
||
{
|
||
if [ -n "$ECD" ]
|
||
then
|
||
pwd 1>&6
|
||
fi
|
||
}
|
||
# Start of test
|
||
cd /tmp
|
||
cd /bin
|
||
cd /etc
|
||
cd -
|
||
cd -2
|
||
cd -l
|
||
expected-stdout:
|
||
/bin
|
||
/tmp
|
||
3 /
|
||
2 /etc
|
||
1 /bin
|
||
0 /tmp
|
||
---
|
||
name: cd-pe
|
||
description:
|
||
Check package for cd -Pe
|
||
need-pass: no
|
||
# the mv command fails on Cygwin and z/OS
|
||
# Hurd aborts the testsuite (permission denied)
|
||
# QNX does not find subdir to cd into
|
||
category: !os:cygwin,!os:gnu,!os:msys,!os:nto,!os:os390,!nosymlink
|
||
file-setup: file 644 "x"
|
||
mkdir noread noread/target noread/target/subdir
|
||
ln -s noread link
|
||
chmod 311 noread
|
||
cd -P$1 .
|
||
echo 0=$?
|
||
bwd=$PWD
|
||
cd -P$1 link/target
|
||
echo 1=$?,${PWD#$bwd/}
|
||
epwd=$($TSHELL -c pwd 2>/dev/null)
|
||
# This unexpectedly succeeds on GNU/Linux and MidnightBSD
|
||
#echo pwd=$?,$epwd
|
||
# expect: pwd=1,
|
||
mv ../../noread ../../renamed
|
||
cd -P$1 subdir
|
||
echo 2=$?,${PWD#$bwd/}
|
||
cd $bwd
|
||
chmod 755 noread renamed 2>/dev/null
|
||
rm -rf noread link renamed
|
||
stdin:
|
||
export TSHELL="$__progname"
|
||
"$__progname" x
|
||
echo "now with -e:"
|
||
"$__progname" x e
|
||
expected-stdout:
|
||
0=0
|
||
1=0,noread/target
|
||
2=0,noread/target/subdir
|
||
now with -e:
|
||
0=0
|
||
1=0,noread/target
|
||
2=1,noread/target/subdir
|
||
---
|
||
name: env-prompt
|
||
description:
|
||
Check that prompt not printed when processing ENV
|
||
env-setup: !ENV=./foo!
|
||
file-setup: file 644 "foo"
|
||
XXX=_
|
||
PS1=X
|
||
false && echo hmmm
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
stdin:
|
||
echo hi${XXX}there
|
||
expected-stdout:
|
||
hi_there
|
||
expected-stderr: !
|
||
XX
|
||
---
|
||
name: expand-ugly
|
||
description:
|
||
Check that weird ${foo+bar} constructs are parsed correctly
|
||
stdin:
|
||
print '#!'"$__progname"'\nfor x in "$@"; do print -r -- "$x"; done' >pfn
|
||
print '#!'"$__progname"'\nfor x in "$@"; do print -nr -- "<$x> "; done' >pfs
|
||
chmod +x pfn pfs
|
||
(echo 1 ${IFS+'}'z}) 2>/dev/null || echo failed in 1
|
||
(echo 2 "${IFS+'}'z}") 2>/dev/null || echo failed in 2
|
||
(echo 3 "foo ${IFS+'bar} baz") 2>/dev/null || echo failed in 3
|
||
(echo -n '4 '; ./pfn "foo ${IFS+"b c"} baz") 2>/dev/null || echo failed in 4
|
||
(echo -n '5 '; ./pfn "foo ${IFS+b c} baz") 2>/dev/null || echo failed in 5
|
||
(echo 6 ${IFS+"}"z}) 2>/dev/null || echo failed in 6
|
||
(echo 7 "${IFS+"}"z}") 2>/dev/null || echo failed in 7
|
||
(echo 8 "${IFS+\"}\"z}") 2>/dev/null || echo failed in 8
|
||
(echo 9 "${IFS+\"\}\"z}") 2>/dev/null || echo failed in 9
|
||
(echo 10 foo ${IFS+'bar} baz'}) 2>/dev/null || echo failed in 10
|
||
(echo 11 "$(echo "${IFS+'}'z}")") 2>/dev/null || echo failed in 11
|
||
(echo 12 "$(echo ${IFS+'}'z})") 2>/dev/null || echo failed in 12
|
||
(echo 13 ${IFS+\}z}) 2>/dev/null || echo failed in 13
|
||
(echo 14 "${IFS+\}z}") 2>/dev/null || echo failed in 14
|
||
u=x; (echo -n '15 '; ./pfs "foo ${IFS+a"b$u{ {"{{\}b} c ${IFS+d{}} bar" ${IFS-e{}} baz; echo .) 2>/dev/null || echo failed in 15
|
||
l=t; (echo 16 ${IFS+h`echo -n i ${IFS+$l}h`ere}) 2>/dev/null || echo failed in 16
|
||
l=t; (echo 17 ${IFS+h$(echo -n i ${IFS+$l}h)ere}) 2>/dev/null || echo failed in 17
|
||
l=t; (echo 18 "${IFS+h`echo -n i ${IFS+$l}h`ere}") 2>/dev/null || echo failed in 18
|
||
l=t; (echo 19 "${IFS+h$(echo -n i ${IFS+$l}h)ere}") 2>/dev/null || echo failed in 19
|
||
l=t; (echo 20 ${IFS+h`echo -n i "${IFS+$l}"h`ere}) 2>/dev/null || echo failed in 20
|
||
l=t; (echo 21 ${IFS+h$(echo -n i "${IFS+$l}"h)ere}) 2>/dev/null || echo failed in 21
|
||
l=t; (echo 22 "${IFS+h`echo -n i "${IFS+$l}"h`ere}") 2>/dev/null || echo failed in 22
|
||
l=t; (echo 23 "${IFS+h$(echo -n i "${IFS+$l}"h)ere}") 2>/dev/null || echo failed in 23
|
||
key=value; (echo -n '24 '; ./pfn "${IFS+'$key'}") 2>/dev/null || echo failed in 24
|
||
key=value; (echo -n '25 '; ./pfn "${IFS+"'$key'"}") 2>/dev/null || echo failed in 25 # ksh93: “'$key'”
|
||
key=value; (echo -n '26 '; ./pfn ${IFS+'$key'}) 2>/dev/null || echo failed in 26
|
||
key=value; (echo -n '27 '; ./pfn ${IFS+"'$key'"}) 2>/dev/null || echo failed in 27
|
||
(echo -n '28 '; ./pfn "${IFS+"'"x ~ x'}'x"'}"x}" #') 2>/dev/null || echo failed in 28
|
||
u=x; (echo -n '29 '; ./pfs foo ${IFS+a"b$u{ {"{ {\}b} c ${IFS+d{}} bar ${IFS-e{}} baz; echo .) 2>/dev/null || echo failed in 29
|
||
(echo -n '30 '; ./pfs ${IFS+foo 'b\
|
||
ar' baz}; echo .) 2>/dev/null || (echo failed in 30; echo failed in 31)
|
||
(echo -n '32 '; ./pfs ${IFS+foo "b\
|
||
ar" baz}; echo .) 2>/dev/null || echo failed in 32
|
||
(echo -n '33 '; ./pfs "${IFS+foo 'b\
|
||
ar' baz}"; echo .) 2>/dev/null || echo failed in 33
|
||
(echo -n '34 '; ./pfs "${IFS+foo "b\
|
||
ar" baz}"; echo .) 2>/dev/null || echo failed in 34
|
||
(echo -n '35 '; ./pfs ${v=a\ b} x ${v=c\ d}; echo .) 2>/dev/null || echo failed in 35
|
||
(echo -n '36 '; ./pfs "${v=a\ b}" x "${v=c\ d}"; echo .) 2>/dev/null || echo failed in 36
|
||
(echo -n '37 '; ./pfs ${v-a\ b} x ${v-c\ d}; echo .) 2>/dev/null || echo failed in 37
|
||
(echo 38 ${IFS+x'a'y} / "${IFS+x'a'y}" .) 2>/dev/null || echo failed in 38
|
||
foo="x'a'y"; (echo 39 ${foo%*'a'*} / "${foo%*'a'*}" .) 2>/dev/null || echo failed in 39
|
||
foo="a b c"; (echo -n '40 '; ./pfs "${foo#a}"; echo .) 2>/dev/null || echo failed in 40
|
||
(foo() { return 100; }; foo; echo 41 ${#+${#:+${#?}}\ \}\}\}}) 2>/dev/null || echo failed in 41
|
||
expected-stdout:
|
||
1 }z
|
||
2 ''z}
|
||
3 foo 'bar baz
|
||
4 foo b c baz
|
||
5 foo b c baz
|
||
6 }z
|
||
7 }z
|
||
8 ""z}
|
||
9 "}"z
|
||
10 foo bar} baz
|
||
11 ''z}
|
||
12 }z
|
||
13 }z
|
||
14 }z
|
||
15 <foo abx{ {{{}b c d{} bar> <}> <baz> .
|
||
16 hi there
|
||
17 hi there
|
||
18 hi there
|
||
19 hi there
|
||
20 hi there
|
||
21 hi there
|
||
22 hi there
|
||
23 hi there
|
||
24 'value'
|
||
25 'value'
|
||
26 $key
|
||
27 'value'
|
||
28 'x ~ x''x}"x}" #
|
||
29 <foo> <abx{ {{> <{}b> <c> <d{}> <bar> <}> <baz> .
|
||
30 <foo> <b\
|
||
ar> <baz> .
|
||
32 <foo> <bar> <baz> .
|
||
33 <foo 'bar' baz> .
|
||
34 <foo bar baz> .
|
||
35 <a> <b> <x> <a> <b> .
|
||
36 <a\ b> <x> <a\ b> .
|
||
37 <a b> <x> <c d> .
|
||
38 xay / x'a'y .
|
||
39 x' / x' .
|
||
40 < b c> .
|
||
41 3 }}}
|
||
---
|
||
name: expand-unglob-dblq
|
||
description:
|
||
Check that regular "${foo+bar}" constructs are parsed correctly
|
||
stdin:
|
||
u=x
|
||
tl_norm() {
|
||
v=$2
|
||
test x"$v" = x"-" && unset v
|
||
(echo "$1 plus norm foo ${v+'bar'} baz")
|
||
(echo "$1 dash norm foo ${v-'bar'} baz")
|
||
(echo "$1 eqal norm foo ${v='bar'} baz")
|
||
(echo "$1 qstn norm foo ${v?'bar'} baz") 2>/dev/null || \
|
||
echo "$1 qstn norm -> error"
|
||
(echo "$1 PLUS norm foo ${v:+'bar'} baz")
|
||
(echo "$1 DASH norm foo ${v:-'bar'} baz")
|
||
(echo "$1 EQAL norm foo ${v:='bar'} baz")
|
||
(echo "$1 QSTN norm foo ${v:?'bar'} baz") 2>/dev/null || \
|
||
echo "$1 QSTN norm -> error"
|
||
}
|
||
tl_paren() {
|
||
v=$2
|
||
test x"$v" = x"-" && unset v
|
||
(echo "$1 plus parn foo ${v+(bar)} baz")
|
||
(echo "$1 dash parn foo ${v-(bar)} baz")
|
||
(echo "$1 eqal parn foo ${v=(bar)} baz")
|
||
(echo "$1 qstn parn foo ${v?(bar)} baz") 2>/dev/null || \
|
||
echo "$1 qstn parn -> error"
|
||
(echo "$1 PLUS parn foo ${v:+(bar)} baz")
|
||
(echo "$1 DASH parn foo ${v:-(bar)} baz")
|
||
(echo "$1 EQAL parn foo ${v:=(bar)} baz")
|
||
(echo "$1 QSTN parn foo ${v:?(bar)} baz") 2>/dev/null || \
|
||
echo "$1 QSTN parn -> error"
|
||
}
|
||
tl_brace() {
|
||
v=$2
|
||
test x"$v" = x"-" && unset v
|
||
(echo "$1 plus brac foo ${v+a$u{{{\}b} c ${v+d{}} baz")
|
||
(echo "$1 dash brac foo ${v-a$u{{{\}b} c ${v-d{}} baz")
|
||
(echo "$1 eqal brac foo ${v=a$u{{{\}b} c ${v=d{}} baz")
|
||
(echo "$1 qstn brac foo ${v?a$u{{{\}b} c ${v?d{}} baz") 2>/dev/null || \
|
||
echo "$1 qstn brac -> error"
|
||
(echo "$1 PLUS brac foo ${v:+a$u{{{\}b} c ${v:+d{}} baz")
|
||
(echo "$1 DASH brac foo ${v:-a$u{{{\}b} c ${v:-d{}} baz")
|
||
(echo "$1 EQAL brac foo ${v:=a$u{{{\}b} c ${v:=d{}} baz")
|
||
(echo "$1 QSTN brac foo ${v:?a$u{{{\}b} c ${v:?d{}} baz") 2>/dev/null || \
|
||
echo "$1 QSTN brac -> error"
|
||
}
|
||
: '}}}' '}}}' '}}}' '}}}' '}}}' '}}}' '}}}' '}}}'
|
||
tl_norm 1 -
|
||
tl_norm 2 ''
|
||
tl_norm 3 x
|
||
tl_paren 4 -
|
||
tl_paren 5 ''
|
||
tl_paren 6 x
|
||
tl_brace 7 -
|
||
tl_brace 8 ''
|
||
tl_brace 9 x
|
||
expected-stdout:
|
||
1 plus norm foo baz
|
||
1 dash norm foo 'bar' baz
|
||
1 eqal norm foo 'bar' baz
|
||
1 qstn norm -> error
|
||
1 PLUS norm foo baz
|
||
1 DASH norm foo 'bar' baz
|
||
1 EQAL norm foo 'bar' baz
|
||
1 QSTN norm -> error
|
||
2 plus norm foo 'bar' baz
|
||
2 dash norm foo baz
|
||
2 eqal norm foo baz
|
||
2 qstn norm foo baz
|
||
2 PLUS norm foo baz
|
||
2 DASH norm foo 'bar' baz
|
||
2 EQAL norm foo 'bar' baz
|
||
2 QSTN norm -> error
|
||
3 plus norm foo 'bar' baz
|
||
3 dash norm foo x baz
|
||
3 eqal norm foo x baz
|
||
3 qstn norm foo x baz
|
||
3 PLUS norm foo 'bar' baz
|
||
3 DASH norm foo x baz
|
||
3 EQAL norm foo x baz
|
||
3 QSTN norm foo x baz
|
||
4 plus parn foo baz
|
||
4 dash parn foo (bar) baz
|
||
4 eqal parn foo (bar) baz
|
||
4 qstn parn -> error
|
||
4 PLUS parn foo baz
|
||
4 DASH parn foo (bar) baz
|
||
4 EQAL parn foo (bar) baz
|
||
4 QSTN parn -> error
|
||
5 plus parn foo (bar) baz
|
||
5 dash parn foo baz
|
||
5 eqal parn foo baz
|
||
5 qstn parn foo baz
|
||
5 PLUS parn foo baz
|
||
5 DASH parn foo (bar) baz
|
||
5 EQAL parn foo (bar) baz
|
||
5 QSTN parn -> error
|
||
6 plus parn foo (bar) baz
|
||
6 dash parn foo x baz
|
||
6 eqal parn foo x baz
|
||
6 qstn parn foo x baz
|
||
6 PLUS parn foo (bar) baz
|
||
6 DASH parn foo x baz
|
||
6 EQAL parn foo x baz
|
||
6 QSTN parn foo x baz
|
||
7 plus brac foo c } baz
|
||
7 dash brac foo ax{{{}b c d{} baz
|
||
7 eqal brac foo ax{{{}b c ax{{{}b} baz
|
||
7 qstn brac -> error
|
||
7 PLUS brac foo c } baz
|
||
7 DASH brac foo ax{{{}b c d{} baz
|
||
7 EQAL brac foo ax{{{}b c ax{{{}b} baz
|
||
7 QSTN brac -> error
|
||
8 plus brac foo ax{{{}b c d{} baz
|
||
8 dash brac foo c } baz
|
||
8 eqal brac foo c } baz
|
||
8 qstn brac foo c } baz
|
||
8 PLUS brac foo c } baz
|
||
8 DASH brac foo ax{{{}b c d{} baz
|
||
8 EQAL brac foo ax{{{}b c ax{{{}b} baz
|
||
8 QSTN brac -> error
|
||
9 plus brac foo ax{{{}b c d{} baz
|
||
9 dash brac foo x c x} baz
|
||
9 eqal brac foo x c x} baz
|
||
9 qstn brac foo x c x} baz
|
||
9 PLUS brac foo ax{{{}b c d{} baz
|
||
9 DASH brac foo x c x} baz
|
||
9 EQAL brac foo x c x} baz
|
||
9 QSTN brac foo x c x} baz
|
||
---
|
||
name: expand-unglob-unq
|
||
description:
|
||
Check that regular ${foo+bar} constructs are parsed correctly
|
||
stdin:
|
||
u=x
|
||
tl_norm() {
|
||
v=$2
|
||
test x"$v" = x"-" && unset v
|
||
(echo $1 plus norm foo ${v+'bar'} baz)
|
||
(echo $1 dash norm foo ${v-'bar'} baz)
|
||
(echo $1 eqal norm foo ${v='bar'} baz)
|
||
(echo $1 qstn norm foo ${v?'bar'} baz) 2>/dev/null || \
|
||
echo "$1 qstn norm -> error"
|
||
(echo $1 PLUS norm foo ${v:+'bar'} baz)
|
||
(echo $1 DASH norm foo ${v:-'bar'} baz)
|
||
(echo $1 EQAL norm foo ${v:='bar'} baz)
|
||
(echo $1 QSTN norm foo ${v:?'bar'} baz) 2>/dev/null || \
|
||
echo "$1 QSTN norm -> error"
|
||
}
|
||
tl_paren() {
|
||
v=$2
|
||
test x"$v" = x"-" && unset v
|
||
(echo $1 plus parn foo ${v+\(bar')'} baz)
|
||
(echo $1 dash parn foo ${v-\(bar')'} baz)
|
||
(echo $1 eqal parn foo ${v=\(bar')'} baz)
|
||
(echo $1 qstn parn foo ${v?\(bar')'} baz) 2>/dev/null || \
|
||
echo "$1 qstn parn -> error"
|
||
(echo $1 PLUS parn foo ${v:+\(bar')'} baz)
|
||
(echo $1 DASH parn foo ${v:-\(bar')'} baz)
|
||
(echo $1 EQAL parn foo ${v:=\(bar')'} baz)
|
||
(echo $1 QSTN parn foo ${v:?\(bar')'} baz) 2>/dev/null || \
|
||
echo "$1 QSTN parn -> error"
|
||
}
|
||
tl_brace() {
|
||
v=$2
|
||
test x"$v" = x"-" && unset v
|
||
(echo $1 plus brac foo ${v+a$u{{{\}b} c ${v+d{}} baz)
|
||
(echo $1 dash brac foo ${v-a$u{{{\}b} c ${v-d{}} baz)
|
||
(echo $1 eqal brac foo ${v=a$u{{{\}b} c ${v=d{}} baz)
|
||
(echo $1 qstn brac foo ${v?a$u{{{\}b} c ${v?d{}} baz) 2>/dev/null || \
|
||
echo "$1 qstn brac -> error"
|
||
(echo $1 PLUS brac foo ${v:+a$u{{{\}b} c ${v:+d{}} baz)
|
||
(echo $1 DASH brac foo ${v:-a$u{{{\}b} c ${v:-d{}} baz)
|
||
(echo $1 EQAL brac foo ${v:=a$u{{{\}b} c ${v:=d{}} baz)
|
||
(echo $1 QSTN brac foo ${v:?a$u{{{\}b} c ${v:?d{}} baz) 2>/dev/null || \
|
||
echo "$1 QSTN brac -> error"
|
||
}
|
||
: '}}}' '}}}' '}}}' '}}}' '}}}' '}}}' '}}}' '}}}'
|
||
tl_norm 1 -
|
||
tl_norm 2 ''
|
||
tl_norm 3 x
|
||
tl_paren 4 -
|
||
tl_paren 5 ''
|
||
tl_paren 6 x
|
||
tl_brace 7 -
|
||
tl_brace 8 ''
|
||
tl_brace 9 x
|
||
expected-stdout:
|
||
1 plus norm foo baz
|
||
1 dash norm foo bar baz
|
||
1 eqal norm foo bar baz
|
||
1 qstn norm -> error
|
||
1 PLUS norm foo baz
|
||
1 DASH norm foo bar baz
|
||
1 EQAL norm foo bar baz
|
||
1 QSTN norm -> error
|
||
2 plus norm foo bar baz
|
||
2 dash norm foo baz
|
||
2 eqal norm foo baz
|
||
2 qstn norm foo baz
|
||
2 PLUS norm foo baz
|
||
2 DASH norm foo bar baz
|
||
2 EQAL norm foo bar baz
|
||
2 QSTN norm -> error
|
||
3 plus norm foo bar baz
|
||
3 dash norm foo x baz
|
||
3 eqal norm foo x baz
|
||
3 qstn norm foo x baz
|
||
3 PLUS norm foo bar baz
|
||
3 DASH norm foo x baz
|
||
3 EQAL norm foo x baz
|
||
3 QSTN norm foo x baz
|
||
4 plus parn foo baz
|
||
4 dash parn foo (bar) baz
|
||
4 eqal parn foo (bar) baz
|
||
4 qstn parn -> error
|
||
4 PLUS parn foo baz
|
||
4 DASH parn foo (bar) baz
|
||
4 EQAL parn foo (bar) baz
|
||
4 QSTN parn -> error
|
||
5 plus parn foo (bar) baz
|
||
5 dash parn foo baz
|
||
5 eqal parn foo baz
|
||
5 qstn parn foo baz
|
||
5 PLUS parn foo baz
|
||
5 DASH parn foo (bar) baz
|
||
5 EQAL parn foo (bar) baz
|
||
5 QSTN parn -> error
|
||
6 plus parn foo (bar) baz
|
||
6 dash parn foo x baz
|
||
6 eqal parn foo x baz
|
||
6 qstn parn foo x baz
|
||
6 PLUS parn foo (bar) baz
|
||
6 DASH parn foo x baz
|
||
6 EQAL parn foo x baz
|
||
6 QSTN parn foo x baz
|
||
7 plus brac foo c } baz
|
||
7 dash brac foo ax{{{}b c d{} baz
|
||
7 eqal brac foo ax{{{}b c ax{{{}b} baz
|
||
7 qstn brac -> error
|
||
7 PLUS brac foo c } baz
|
||
7 DASH brac foo ax{{{}b c d{} baz
|
||
7 EQAL brac foo ax{{{}b c ax{{{}b} baz
|
||
7 QSTN brac -> error
|
||
8 plus brac foo ax{{{}b c d{} baz
|
||
8 dash brac foo c } baz
|
||
8 eqal brac foo c } baz
|
||
8 qstn brac foo c } baz
|
||
8 PLUS brac foo c } baz
|
||
8 DASH brac foo ax{{{}b c d{} baz
|
||
8 EQAL brac foo ax{{{}b c ax{{{}b} baz
|
||
8 QSTN brac -> error
|
||
9 plus brac foo ax{{{}b c d{} baz
|
||
9 dash brac foo x c x} baz
|
||
9 eqal brac foo x c x} baz
|
||
9 qstn brac foo x c x} baz
|
||
9 PLUS brac foo ax{{{}b c d{} baz
|
||
9 DASH brac foo x c x} baz
|
||
9 EQAL brac foo x c x} baz
|
||
9 QSTN brac foo x c x} baz
|
||
---
|
||
name: expand-threecolons-dblq
|
||
description:
|
||
Check for a particular thing that used to segfault
|
||
stdin:
|
||
TEST=1234
|
||
echo "${TEST:1:2:3}"
|
||
echo $? but still living
|
||
expected-stderr-pattern:
|
||
/bad substitution/
|
||
expected-exit: 1
|
||
---
|
||
name: expand-threecolons-unq
|
||
description:
|
||
Check for a particular thing that used to not error out
|
||
stdin:
|
||
TEST=1234
|
||
echo ${TEST:1:2:3}
|
||
echo $? but still living
|
||
expected-stderr-pattern:
|
||
/bad substitution/
|
||
expected-exit: 1
|
||
---
|
||
name: expand-weird-1
|
||
description:
|
||
Check corner cases of trim expansion vs. $# vs. ${#var} vs. ${var?}
|
||
stdin:
|
||
set 1 2 3 4 5 6 7 8 9 10 11
|
||
echo ${#} # value of $#
|
||
echo ${##} # length of $#
|
||
echo ${##1} # $# trimmed 1
|
||
set 1 2 3 4 5 6 7 8 9 10 11 12
|
||
echo ${##1}
|
||
(exit 0)
|
||
echo $? = ${#?} .
|
||
(exit 111)
|
||
echo $? = ${#?} .
|
||
expected-stdout:
|
||
11
|
||
2
|
||
1
|
||
2
|
||
0 = 1 .
|
||
111 = 3 .
|
||
---
|
||
name: expand-weird-2
|
||
description:
|
||
Check more substitution and extension corner cases
|
||
stdin:
|
||
:& set -C; pid=$$; sub=$!; flg=$-; set -- i; exec 3>x.tmp
|
||
#echo "D: !=$! #=$# \$=$$ -=$- ?=$?"
|
||
echo >&3 3 = s^${!-word} , ${#-word} , p^${$-word} , f^${--word} , ${?-word} .
|
||
echo >&3 4 = ${!+word} , ${#+word} , ${$+word} , ${-+word} , ${?+word} .
|
||
echo >&3 5 = s^${!=word} , ${#=word} , p^${$=word} , f^${-=word} , ${?=word} .
|
||
echo >&3 6 = s^${!?word} , ${#?word} , p^${$?word} , f^${-?word} , ${??word} .
|
||
echo >&3 7 = sl^${#!} , ${##} , pl^${#$} , fl^${#-} , ${#?} .
|
||
echo >&3 8 = sw^${%!} , ${%#} , pw^${%$} , fw^${%-} , ${%?} .
|
||
echo >&3 9 = ${!!} , s^${!#} , ${!$} , s^${!-} , s^${!?} .
|
||
echo >&3 10 = s^${!#pattern} , ${##pattern} , p^${$#pattern} , f^${-#pattern} , ${?#pattern} .
|
||
echo >&3 11 = s^${!%pattern} , ${#%pattern} , p^${$%pattern} , f^${-%pattern} , ${?%pattern} .
|
||
echo >&3 12 = $# : ${##} , ${##1} .
|
||
set --
|
||
echo >&3 14 = $# : ${##} , ${##1} .
|
||
set -- 1 2 3 4 5
|
||
echo >&3 16 = $# : ${##} , ${##1} .
|
||
set -- 1 2 3 4 5 6 7 8 9 a b c d e
|
||
echo >&3 18 = $# : ${##} , ${##1} .
|
||
exec 3>&-
|
||
<x.tmp sed \
|
||
-e "s/ pl^${#pid} / PID /g" -e "s/ sl^${#sub} / SUB /g" -e "s/ fl^${#flg} / FLG /g" \
|
||
-e "s/ pw^${%pid} / PID /g" -e "s/ sw^${%sub} / SUB /g" -e "s/ fw^${%flg} / FLG /g" \
|
||
-e "s/ p^$pid / PID /g" -e "s/ s^$sub / SUB /g" -e "s/ f^$flg / FLG /g"
|
||
expected-stdout:
|
||
3 = SUB , 1 , PID , FLG , 0 .
|
||
4 = word , word , word , word , word .
|
||
5 = SUB , 1 , PID , FLG , 0 .
|
||
6 = SUB , 1 , PID , FLG , 0 .
|
||
7 = SUB , 1 , PID , FLG , 1 .
|
||
8 = SUB , 1 , PID , FLG , 1 .
|
||
9 = ! , SUB , $ , SUB , SUB .
|
||
10 = SUB , 1 , PID , FLG , 0 .
|
||
11 = SUB , 1 , PID , FLG , 0 .
|
||
12 = 1 : 1 , .
|
||
14 = 0 : 1 , 0 .
|
||
16 = 5 : 1 , 5 .
|
||
18 = 14 : 2 , 4 .
|
||
---
|
||
name: expand-weird-3
|
||
description:
|
||
Check that trimming works with positional parameters (Debian #48453)
|
||
stdin:
|
||
A=9999-02
|
||
B=9999
|
||
echo 1=${A#$B?}.
|
||
set -- $A $B
|
||
echo 2=${1#$2?}.
|
||
expected-stdout:
|
||
1=02.
|
||
2=02.
|
||
---
|
||
name: expand-weird-4
|
||
description:
|
||
Check that tilde expansion is enabled in ${x#~}
|
||
and cases that are modelled after it (${x/~/~})
|
||
stdin:
|
||
HOME=/etc
|
||
a="~/x"
|
||
echo "<${a#~}> <${a#\~}> <${b:-~}> <${b:-\~}> <${c:=~}><$c> <${a/~}> <${a/x/~}> <${a/x/\~}>"
|
||
expected-stdout:
|
||
<~/x> </x> <~> <\~> <~><~> <~/x> <~//etc> <~/~>
|
||
---
|
||
name: expand-bang-1
|
||
description:
|
||
Check corner case of ${!?} with ! being var vs. op
|
||
stdin:
|
||
echo ${!?}
|
||
expected-exit: 1
|
||
expected-stderr-pattern: /not set/
|
||
---
|
||
name: expand-bang-2
|
||
description:
|
||
Check corner case of ${!var} vs. ${var op} with var=!
|
||
stdin:
|
||
echo 1 $! .
|
||
echo 2 ${!#} .
|
||
echo 3 ${!#[0-9]} .
|
||
echo 4 ${!-foo} .
|
||
# get an at least three-digit bg pid
|
||
while :; do
|
||
:&
|
||
x=$!
|
||
if [[ $x != +([0-9]) ]]; then
|
||
echo >&2 "cannot test, pid '$x' not numeric"
|
||
echo >&2 report this with as many details as possible
|
||
exit 1
|
||
fi
|
||
[[ $x = [0-9][0-9][0-9]* ]] && break
|
||
done
|
||
y=${x#?}
|
||
t=$!; [[ $t = $x ]]; echo 5 $? .
|
||
t=${!#}; [[ $t = $x ]]; echo 6 $? .
|
||
t=${!#[0-9]}; [[ $t = $y ]]; echo 7 $? .
|
||
t=${!-foo}; [[ $t = $x ]]; echo 8 $? .
|
||
t=${!?bar}; [[ $t = $x ]]; echo 9 $? .
|
||
expected-stdout:
|
||
1 .
|
||
2 .
|
||
3 .
|
||
4 foo .
|
||
5 0 .
|
||
6 0 .
|
||
7 0 .
|
||
8 0 .
|
||
9 0 .
|
||
---
|
||
name: expand-number-1
|
||
description:
|
||
Check that positional arguments do not overflow
|
||
stdin:
|
||
echo "1 ${12345678901234567890} ."
|
||
expected-stdout:
|
||
1 .
|
||
---
|
||
name: expand-slashes-1
|
||
description:
|
||
Check that side effects in substring replacement are handled correctly
|
||
stdin:
|
||
foo=n1n1n1n2n3
|
||
i=2
|
||
n=1
|
||
echo 1 ${foo//n$((n++))/[$((++i))]} .
|
||
echo 2 $n , $i .
|
||
expected-stdout:
|
||
1 [3][3][3]n2n3 .
|
||
2 2 , 3 .
|
||
---
|
||
name: expand-slashes-2
|
||
description:
|
||
Check that side effects in substring replacement are handled correctly
|
||
stdin:
|
||
foo=n1n1n1n2n3
|
||
i=2
|
||
n=1
|
||
echo 1 ${foo@/n$((n++))/[$((++i))]} .
|
||
echo 2 $n , $i .
|
||
expected-stdout:
|
||
1 [3]n1n1[4][5] .
|
||
2 5 , 5 .
|
||
---
|
||
name: expand-slashes-3
|
||
description:
|
||
Check that we can access the replaced string
|
||
stdin:
|
||
foo=n1n1n1n2n3
|
||
echo 1 ${foo@/n[12]/[$KSH_MATCH]} .
|
||
expected-stdout:
|
||
1 [n1][n1][n1][n2]n3 .
|
||
---
|
||
name: eglob-bad-1
|
||
description:
|
||
Check that globbing isn't done when glob has syntax error
|
||
category: !os:cygwin,!os:msys,!os:os2
|
||
file-setup: file 644 "@(a[b|)c]foo"
|
||
stdin:
|
||
echo @(a[b|)c]*
|
||
expected-stdout:
|
||
@(a[b|)c]*
|
||
---
|
||
name: eglob-bad-2
|
||
description:
|
||
Check that globbing isn't done when glob has syntax error
|
||
(AT&T ksh fails this test)
|
||
file-setup: file 644 "abcx"
|
||
file-setup: file 644 "abcz"
|
||
file-setup: file 644 "bbc"
|
||
stdin:
|
||
echo [a*(]*)z
|
||
expected-stdout:
|
||
[a*(]*)z
|
||
---
|
||
name: eglob-infinite-plus
|
||
description:
|
||
Check that shell doesn't go into infinite loop expanding +(...)
|
||
expressions.
|
||
file-setup: file 644 "abc"
|
||
time-limit: 3
|
||
stdin:
|
||
echo +()c
|
||
echo +()x
|
||
echo +(*)c
|
||
echo +(*)x
|
||
expected-stdout:
|
||
+()c
|
||
+()x
|
||
abc
|
||
+(*)x
|
||
---
|
||
name: eglob-subst-1
|
||
description:
|
||
Check that eglobbing isn't done on substitution results
|
||
file-setup: file 644 "abc"
|
||
stdin:
|
||
x='@(*)'
|
||
echo $x
|
||
expected-stdout:
|
||
@(*)
|
||
---
|
||
name: eglob-nomatch-1
|
||
description:
|
||
Check that the pattern doesn't match
|
||
stdin:
|
||
echo 1: no-file+(a|b)stuff
|
||
echo 2: no-file+(a*(c)|b)stuff
|
||
echo 3: no-file+((((c)))|b)stuff
|
||
expected-stdout:
|
||
1: no-file+(a|b)stuff
|
||
2: no-file+(a*(c)|b)stuff
|
||
3: no-file+((((c)))|b)stuff
|
||
---
|
||
name: eglob-match-1
|
||
description:
|
||
Check that the pattern matches correctly
|
||
file-setup: file 644 "abd"
|
||
file-setup: file 644 "acd"
|
||
file-setup: file 644 "abac"
|
||
stdin:
|
||
echo 1: a+(b|c)d
|
||
echo 2: a!(@(b|B))d
|
||
echo 3: *(a(b|c)) # (...|...) can be used within X(..)
|
||
echo 4: a[b*(foo|bar)]d # patterns not special inside [...]
|
||
expected-stdout:
|
||
1: abd acd
|
||
2: acd
|
||
3: abac
|
||
4: abd
|
||
---
|
||
name: eglob-case-1
|
||
description:
|
||
Simple negation tests
|
||
stdin:
|
||
case foo in !(foo|bar)) echo yes;; *) echo no;; esac
|
||
case bar in !(foo|bar)) echo yes;; *) echo no;; esac
|
||
expected-stdout:
|
||
no
|
||
no
|
||
---
|
||
name: eglob-case-2
|
||
description:
|
||
Simple kleene tests
|
||
stdin:
|
||
case foo in *(a|b[)) echo yes;; *) echo no;; esac
|
||
case foo in *(a|b[)|f*) echo yes;; *) echo no;; esac
|
||
case '*(a|b[)' in *(a|b[)) echo yes;; *) echo no;; esac
|
||
case 'aab[b[ab[a' in *(a|b[)) echo yes;; *) echo no;; esac
|
||
expected-stdout:
|
||
no
|
||
yes
|
||
no
|
||
yes
|
||
---
|
||
name: eglob-trim-1
|
||
description:
|
||
Eglobbing in trim expressions...
|
||
(AT&T ksh fails this - docs say # matches shortest string, ## matches
|
||
longest...)
|
||
stdin:
|
||
x=abcdef
|
||
echo 1: ${x#a|abc}
|
||
echo 2: ${x##a|abc}
|
||
echo 3: ${x%def|f}
|
||
echo 4: ${x%%f|def}
|
||
expected-stdout:
|
||
1: bcdef
|
||
2: def
|
||
3: abcde
|
||
4: abc
|
||
---
|
||
name: eglob-trim-2
|
||
description:
|
||
Check eglobbing works in trims...
|
||
stdin:
|
||
x=abcdef
|
||
echo 1: ${x#*(a|b)cd}
|
||
echo 2: "${x#*(a|b)cd}"
|
||
echo 3: ${x#"*(a|b)cd"}
|
||
echo 4: ${x#a(b|c)}
|
||
expected-stdout:
|
||
1: ef
|
||
2: ef
|
||
3: abcdef
|
||
4: cdef
|
||
---
|
||
name: eglob-trim-3
|
||
description:
|
||
Check eglobbing works in trims, for Korn Shell
|
||
Ensure eglobbing does not work for reduced-feature /bin/sh
|
||
stdin:
|
||
set +o sh
|
||
x=foobar
|
||
y=foobaz
|
||
z=fooba\?
|
||
echo "<${x%bar|baz},${y%bar|baz},${z%\?}>"
|
||
echo "<${x%ba(r|z)},${y%ba(r|z)}>"
|
||
set -o sh
|
||
echo "<${x%bar|baz},${y%bar|baz},${z%\?}>"
|
||
z='foo(bar'
|
||
echo "<${z%(*}>"
|
||
expected-stdout:
|
||
<foo,foo,fooba>
|
||
<foo,foo>
|
||
<foobar,foobaz,fooba>
|
||
<foo>
|
||
---
|
||
name: eglob-substrpl-1
|
||
description:
|
||
Check eglobbing works in substs... and they work at all
|
||
stdin:
|
||
[[ -n $BASH_VERSION ]] && shopt -s extglob
|
||
x=1222321_ab/cde_b/c_1221
|
||
y=xyz
|
||
echo 1: ${x/2} . ${x/}
|
||
echo 2: ${x//2}
|
||
echo 3: ${x/+(2)}
|
||
echo 4: ${x//+(2)}
|
||
echo 5: ${x/2/4}
|
||
echo 6: ${x//2/4}
|
||
echo 7: ${x/+(2)/4}
|
||
echo 8: ${x//+(2)/4}
|
||
echo 9: ${x/b/c/e/f}
|
||
echo 10: ${x/b\/c/e/f}
|
||
echo 11: ${x/b\/c/e\/f}
|
||
echo 12: ${x/b\/c/e\\/f}
|
||
echo 13: ${x/b\\/c/e\\/f}
|
||
echo 14: ${x//b/c/e/f}
|
||
echo 15: ${x//b\/c/e/f}
|
||
echo 16: ${x//b\/c/e\/f}
|
||
echo 17: ${x//b\/c/e\\/f}
|
||
echo 18: ${x//b\\/c/e\\/f}
|
||
echo 19: ${x/b\/*\/c/x}
|
||
echo 20: ${x/\//.}
|
||
echo 21: ${x//\//.}
|
||
echo 22: ${x///.}
|
||
echo 23: ${x/#1/9}
|
||
echo 24: ${x//#1/9}
|
||
echo 25: ${x/%1/9}
|
||
echo 26: ${x//%1/9}
|
||
echo 27: ${x//\%1/9}
|
||
echo 28: ${x//\\%1/9}
|
||
echo 29: ${x//\a/9}
|
||
echo 30: ${x//\\a/9}
|
||
echo 31: ${x/2/$y}
|
||
expected-stdout:
|
||
1: 122321_ab/cde_b/c_1221 . 1222321_ab/cde_b/c_1221
|
||
2: 131_ab/cde_b/c_11
|
||
3: 1321_ab/cde_b/c_1221
|
||
4: 131_ab/cde_b/c_11
|
||
5: 1422321_ab/cde_b/c_1221
|
||
6: 1444341_ab/cde_b/c_1441
|
||
7: 14321_ab/cde_b/c_1221
|
||
8: 14341_ab/cde_b/c_141
|
||
9: 1222321_ac/e/f/cde_b/c_1221
|
||
10: 1222321_ae/fde_b/c_1221
|
||
11: 1222321_ae/fde_b/c_1221
|
||
12: 1222321_ae\/fde_b/c_1221
|
||
13: 1222321_ab/cde_b/c_1221
|
||
14: 1222321_ac/e/f/cde_c/e/f/c_1221
|
||
15: 1222321_ae/fde_e/f_1221
|
||
16: 1222321_ae/fde_e/f_1221
|
||
17: 1222321_ae\/fde_e\/f_1221
|
||
18: 1222321_ab/cde_b/c_1221
|
||
19: 1222321_ax_1221
|
||
20: 1222321_ab.cde_b/c_1221
|
||
21: 1222321_ab.cde_b.c_1221
|
||
22: 1222321_ab/cde_b/c_1221
|
||
23: 9222321_ab/cde_b/c_1221
|
||
24: 1222321_ab/cde_b/c_1221
|
||
25: 1222321_ab/cde_b/c_1229
|
||
26: 1222321_ab/cde_b/c_1221
|
||
27: 1222321_ab/cde_b/c_1221
|
||
28: 1222321_ab/cde_b/c_1221
|
||
29: 1222321_9b/cde_b/c_1221
|
||
30: 1222321_ab/cde_b/c_1221
|
||
31: 1xyz22321_ab/cde_b/c_1221
|
||
---
|
||
name: eglob-substrpl-2
|
||
description:
|
||
Check anchored substring replacement works, corner cases
|
||
stdin:
|
||
foo=123
|
||
echo 1: ${foo/#/x}
|
||
echo 2: ${foo/%/x}
|
||
echo 3: ${foo/#/}
|
||
echo 4: ${foo/#}
|
||
echo 5: ${foo/%/}
|
||
echo 6: ${foo/%}
|
||
expected-stdout:
|
||
1: x123
|
||
2: 123x
|
||
3: 123
|
||
4: 123
|
||
5: 123
|
||
6: 123
|
||
---
|
||
name: eglob-substrpl-3a
|
||
description:
|
||
Check substring replacement works with variables and slashes, too
|
||
stdin:
|
||
HOME=/etc
|
||
pfx=/home/user
|
||
wd=/home/user/tmp
|
||
echo "${wd/#$pfx/~}"
|
||
echo "${wd/#\$pfx/~}"
|
||
echo "${wd/#"$pfx"/~}"
|
||
echo "${wd/#'$pfx'/~}"
|
||
echo "${wd/#"\$pfx"/~}"
|
||
echo "${wd/#'\$pfx'/~}"
|
||
expected-stdout:
|
||
/etc/tmp
|
||
/home/user/tmp
|
||
/etc/tmp
|
||
/home/user/tmp
|
||
/home/user/tmp
|
||
/home/user/tmp
|
||
---
|
||
name: eglob-substrpl-3b
|
||
description:
|
||
More of this, bash fails it (bash4 passes)
|
||
stdin:
|
||
HOME=/etc
|
||
pfx=/home/user
|
||
wd=/home/user/tmp
|
||
echo "${wd/#$(echo /home/user)/~}"
|
||
echo "${wd/#"$(echo /home/user)"/~}"
|
||
echo "${wd/#'$(echo /home/user)'/~}"
|
||
expected-stdout:
|
||
/etc/tmp
|
||
/etc/tmp
|
||
/home/user/tmp
|
||
---
|
||
name: eglob-substrpl-3c
|
||
description:
|
||
Even more weird cases
|
||
stdin:
|
||
HOME=/etc
|
||
pfx=/home/user
|
||
wd='$pfx/tmp'
|
||
echo 1: ${wd/#$pfx/~}
|
||
echo 2: ${wd/#\$pfx/~}
|
||
echo 3: ${wd/#"$pfx"/~}
|
||
echo 4: ${wd/#'$pfx'/~}
|
||
echo 5: ${wd/#"\$pfx"/~}
|
||
echo 6: ${wd/#'\$pfx'/~}
|
||
ts='a/ba/b$tp$tp_a/b$tp_*(a/b)_*($tp)'
|
||
tp=a/b
|
||
tr=c/d
|
||
[[ -n $BASH_VERSION ]] && shopt -s extglob
|
||
echo 7: ${ts/a\/b/$tr}
|
||
echo 8: ${ts/a\/b/\$tr}
|
||
echo 9: ${ts/$tp/$tr}
|
||
echo 10: ${ts/\$tp/$tr}
|
||
echo 11: ${ts/\\$tp/$tr}
|
||
echo 12: ${ts/$tp/c/d}
|
||
echo 13: ${ts/$tp/c\/d}
|
||
echo 14: ${ts/$tp/c\\/d}
|
||
echo 15: ${ts/+(a\/b)/$tr}
|
||
echo 16: ${ts/+(a\/b)/\$tr}
|
||
echo 17: ${ts/+($tp)/$tr}
|
||
echo 18: ${ts/+($tp)/c/d}
|
||
echo 19: ${ts/+($tp)/c\/d}
|
||
echo 20: ${ts//a\/b/$tr}
|
||
echo 21: ${ts//a\/b/\$tr}
|
||
echo 22: ${ts//$tp/$tr}
|
||
echo 23: ${ts//$tp/c/d}
|
||
echo 24: ${ts//$tp/c\/d}
|
||
echo 25: ${ts//+(a\/b)/$tr}
|
||
echo 26: ${ts//+(a\/b)/\$tr}
|
||
echo 27: ${ts//+($tp)/$tr}
|
||
echo 28: ${ts//+($tp)/c/d}
|
||
echo 29: ${ts//+($tp)/c\/d}
|
||
tp="+($tp)"
|
||
echo 30: ${ts/$tp/$tr}
|
||
echo 31: ${ts//$tp/$tr}
|
||
expected-stdout:
|
||
1: $pfx/tmp
|
||
2: /etc/tmp
|
||
3: $pfx/tmp
|
||
4: /etc/tmp
|
||
5: /etc/tmp
|
||
6: $pfx/tmp
|
||
7: c/da/b$tp$tp_a/b$tp_*(a/b)_*($tp)
|
||
8: $tra/b$tp$tp_a/b$tp_*(a/b)_*($tp)
|
||
9: c/da/b$tp$tp_a/b$tp_*(a/b)_*($tp)
|
||
10: a/ba/bc/d$tp_a/b$tp_*(a/b)_*($tp)
|
||
11: a/ba/b$tp$tp_a/b$tp_*(a/b)_*($tp)
|
||
12: c/da/b$tp$tp_a/b$tp_*(a/b)_*($tp)
|
||
13: c/da/b$tp$tp_a/b$tp_*(a/b)_*($tp)
|
||
14: c\/da/b$tp$tp_a/b$tp_*(a/b)_*($tp)
|
||
15: c/d$tp$tp_a/b$tp_*(a/b)_*($tp)
|
||
16: $tr$tp$tp_a/b$tp_*(a/b)_*($tp)
|
||
17: c/d$tp$tp_a/b$tp_*(a/b)_*($tp)
|
||
18: c/d$tp$tp_a/b$tp_*(a/b)_*($tp)
|
||
19: c/d$tp$tp_a/b$tp_*(a/b)_*($tp)
|
||
20: c/dc/d$tp$tp_c/d$tp_*(c/d)_*($tp)
|
||
21: $tr$tr$tp$tp_$tr$tp_*($tr)_*($tp)
|
||
22: c/dc/d$tp$tp_c/d$tp_*(c/d)_*($tp)
|
||
23: c/dc/d$tp$tp_c/d$tp_*(c/d)_*($tp)
|
||
24: c/dc/d$tp$tp_c/d$tp_*(c/d)_*($tp)
|
||
25: c/d$tp$tp_c/d$tp_*(c/d)_*($tp)
|
||
26: $tr$tp$tp_$tr$tp_*($tr)_*($tp)
|
||
27: c/d$tp$tp_c/d$tp_*(c/d)_*($tp)
|
||
28: c/d$tp$tp_c/d$tp_*(c/d)_*($tp)
|
||
29: c/d$tp$tp_c/d$tp_*(c/d)_*($tp)
|
||
30: a/ba/b$tp$tp_a/b$tp_*(a/b)_*($tp)
|
||
31: a/ba/b$tp$tp_a/b$tp_*(a/b)_*($tp)
|
||
# This is what GNU bash does:
|
||
# 30: c/d$tp$tp_a/b$tp_*(a/b)_*($tp)
|
||
# 31: c/d$tp$tp_c/d$tp_*(c/d)_*($tp)
|
||
---
|
||
name: eglob-utf8-1
|
||
description:
|
||
UTF-8 mode differences for eglobbing
|
||
category: !shell:ebcdic-yes
|
||
stdin:
|
||
s=blöd
|
||
set +U
|
||
print 1: ${s%???} .
|
||
print 2: ${s/b???d/x} .
|
||
set -U
|
||
print 3: ${s%???} .
|
||
print 4: ${s/b??d/x} .
|
||
x=nö
|
||
print 5: ${x%?} ${x%%?} .
|
||
x=äh
|
||
print 6: ${x#?} ${x##?} .
|
||
x=<3D><>
|
||
print 7: ${x%?} ${x%%?} .
|
||
x=mä<6D>
|
||
print 8: ${x%?} ${x%%?} .
|
||
x=何
|
||
print 9: ${x%?} ${x%%?} .
|
||
expected-stdout:
|
||
1: bl .
|
||
2: x .
|
||
3: b .
|
||
4: x .
|
||
5: n n .
|
||
6: h h .
|
||
7: <20> <20> .
|
||
8: mä mä .
|
||
9: .
|
||
---
|
||
name: glob-bad-1
|
||
description:
|
||
Check that [ matches itself if it's not a valid bracket expr
|
||
but does not prevent globbing, while backslash-escaping does
|
||
file-setup: dir 755 "[x"
|
||
file-setup: file 644 "[x/foo"
|
||
stdin:
|
||
echo [*
|
||
echo *[x
|
||
echo [x/*
|
||
:>'ab[x'
|
||
:>'a[a-z][x'
|
||
echo a[a-z][*
|
||
echo a[a-z]*
|
||
echo a[a\-z]*
|
||
expected-stdout:
|
||
[x
|
||
[x
|
||
[x/foo
|
||
ab[x
|
||
ab[x
|
||
a[a-z]*
|
||
---
|
||
name: glob-bad-2
|
||
description:
|
||
Check that symbolic links aren't stat()'d
|
||
# breaks on Dell UNIX 4.0 R2.2 (SVR4) where unlink also fails
|
||
# breaks on FreeMiNT (cannot unlink dangling symlinks)
|
||
# breaks on MSYS, OS/2 (do not support symlinks)
|
||
category: !os:mint,!os:msys,!os:svr4.0,!nosymlink
|
||
file-setup: dir 755 "dir"
|
||
file-setup: symlink 644 "dir/abc"
|
||
non-existent-file
|
||
stdin:
|
||
echo d*/*
|
||
echo d*/abc
|
||
expected-stdout:
|
||
dir/abc
|
||
dir/abc
|
||
---
|
||
name: glob-bad-3
|
||
description:
|
||
Check that the slash is parsed before the glob
|
||
stdin:
|
||
mkdir a 'a[b'
|
||
(cd 'a[b'; echo ok >'c]d')
|
||
echo nok >abd
|
||
echo fail >a/d
|
||
cat a[b/c]d
|
||
expected-stdout:
|
||
ok
|
||
---
|
||
name: glob-range-1
|
||
description:
|
||
Test range matching
|
||
file-setup: file 644 ".bc"
|
||
file-setup: file 644 "abc"
|
||
file-setup: file 644 "bbc"
|
||
file-setup: file 644 "cbc"
|
||
file-setup: file 644 "-bc"
|
||
file-setup: file 644 "!bc"
|
||
file-setup: file 644 "^bc"
|
||
file-setup: file 644 "+bc"
|
||
file-setup: file 644 ",bc"
|
||
file-setup: file 644 "0bc"
|
||
file-setup: file 644 "1bc"
|
||
stdin:
|
||
echo [ab-]*
|
||
echo [-ab]*
|
||
echo [!-ab]*
|
||
echo [!ab]*
|
||
echo []ab]*
|
||
echo [^ab]*
|
||
echo [+--]*
|
||
echo [--1]*
|
||
|
||
expected-stdout:
|
||
-bc abc bbc
|
||
-bc abc bbc
|
||
!bc +bc ,bc 0bc 1bc ^bc cbc
|
||
!bc +bc ,bc -bc 0bc 1bc ^bc cbc
|
||
abc bbc
|
||
^bc abc bbc
|
||
+bc ,bc -bc
|
||
-bc 0bc 1bc
|
||
---
|
||
name: glob-range-2
|
||
description:
|
||
Test range matching
|
||
(AT&T ksh fails this; POSIX says invalid)
|
||
file-setup: file 644 "abc"
|
||
stdin:
|
||
echo [a--]*
|
||
expected-stdout:
|
||
[a--]*
|
||
---
|
||
name: glob-range-3
|
||
description:
|
||
Check that globbing matches the right things...
|
||
# breaks on Mac OSX (HFS+ non-standard Unicode canonical decomposition)
|
||
# breaks on Cygwin 1.7 (files are now UTF-16 or something)
|
||
# breaks on QNX 6.4.1 (says RT)
|
||
category: !os:cygwin,!os:darwin,!os:msys,!os:nto,!os:os2,!os:os390
|
||
need-pass: no
|
||
file-setup: file 644 "a<>c"
|
||
stdin:
|
||
echo a[<EFBFBD>-<2D>]*
|
||
expected-stdout:
|
||
a<>c
|
||
---
|
||
name: glob-range-4
|
||
description:
|
||
Results unspecified according to POSIX
|
||
file-setup: file 644 ".bc"
|
||
stdin:
|
||
echo [a.]*
|
||
expected-stdout:
|
||
[a.]*
|
||
---
|
||
name: glob-range-5
|
||
description:
|
||
Results unspecified according to POSIX
|
||
(AT&T ksh treats this like [a-cc-e]*)
|
||
file-setup: file 644 "abc"
|
||
file-setup: file 644 "bbc"
|
||
file-setup: file 644 "cbc"
|
||
file-setup: file 644 "dbc"
|
||
file-setup: file 644 "ebc"
|
||
file-setup: file 644 "-bc"
|
||
file-setup: file 644 "@bc"
|
||
stdin:
|
||
echo [a-c-e]*
|
||
echo [a--@]*
|
||
expected-stdout:
|
||
-bc abc bbc cbc ebc
|
||
@bc
|
||
---
|
||
name: glob-word-1
|
||
description:
|
||
Check BSD word boundary matches
|
||
stdin:
|
||
t() { [[ $1 = *[[:\<:]]bar[[:\>:]]* ]]; echo =$?; }
|
||
t 'foo bar baz'
|
||
t 'foobar baz'
|
||
t 'foo barbaz'
|
||
t 'bar'
|
||
t '_bar'
|
||
t 'bar_'
|
||
expected-stdout:
|
||
=0
|
||
=1
|
||
=1
|
||
=0
|
||
=1
|
||
=1
|
||
---
|
||
name: glob-trim-1
|
||
description:
|
||
Check against a regression from fixing IFS-subst-2
|
||
stdin:
|
||
x='#foo'
|
||
print -r "before='$x'"
|
||
x=${x%%#*}
|
||
print -r "after ='$x'"
|
||
expected-stdout:
|
||
before='#foo'
|
||
after =''
|
||
---
|
||
name: heredoc-1
|
||
description:
|
||
Check ordering/content of redundent here documents.
|
||
stdin:
|
||
cat << EOF1 << EOF2
|
||
hi
|
||
EOF1
|
||
there
|
||
EOF2
|
||
expected-stdout:
|
||
there
|
||
---
|
||
name: heredoc-2
|
||
description:
|
||
Check quoted here-doc is protected.
|
||
stdin:
|
||
a=foo
|
||
cat << 'EOF'
|
||
hi\
|
||
there$a
|
||
stuff
|
||
EO\
|
||
F
|
||
EOF
|
||
expected-stdout:
|
||
hi\
|
||
there$a
|
||
stuff
|
||
EO\
|
||
F
|
||
---
|
||
name: heredoc-3
|
||
description:
|
||
Check that newline isn't needed after heredoc-delimiter marker.
|
||
stdin: !
|
||
cat << EOF
|
||
hi
|
||
there
|
||
EOF
|
||
expected-stdout:
|
||
hi
|
||
there
|
||
---
|
||
name: heredoc-4a
|
||
description:
|
||
Check that an error occurs if the heredoc-delimiter is missing.
|
||
stdin: !
|
||
cat << EOF
|
||
hi
|
||
there
|
||
expected-exit: e > 0
|
||
expected-stderr-pattern: /.*/
|
||
---
|
||
name: heredoc-4an
|
||
description:
|
||
Check that an error occurs if the heredoc-delimiter is missing.
|
||
arguments: !-n!
|
||
stdin: !
|
||
cat << EOF
|
||
hi
|
||
there
|
||
expected-exit: e > 0
|
||
expected-stderr-pattern: /.*/
|
||
---
|
||
name: heredoc-4b
|
||
description:
|
||
Check that an error occurs if the heredoc is missing.
|
||
stdin: !
|
||
cat << EOF
|
||
expected-exit: e > 0
|
||
expected-stderr-pattern: /.*/
|
||
---
|
||
name: heredoc-4bn
|
||
description:
|
||
Check that an error occurs if the heredoc is missing.
|
||
arguments: !-n!
|
||
stdin: !
|
||
cat << EOF
|
||
expected-exit: e > 0
|
||
expected-stderr-pattern: /.*/
|
||
---
|
||
name: heredoc-5
|
||
description:
|
||
Check that backslash quotes a $, ` and \ and kills a \newline
|
||
stdin:
|
||
a=BAD
|
||
b=ok
|
||
cat << EOF
|
||
h\${a}i
|
||
h\\${b}i
|
||
th\`echo not-run\`ere
|
||
th\\`echo is-run`ere
|
||
fol\\ks
|
||
more\\
|
||
last \
|
||
line
|
||
EOF
|
||
expected-stdout:
|
||
h${a}i
|
||
h\oki
|
||
th`echo not-run`ere
|
||
th\is-runere
|
||
fol\ks
|
||
more\
|
||
last line
|
||
---
|
||
name: heredoc-6
|
||
description:
|
||
Check that \newline in initial here-delim word doesn't imply
|
||
a quoted here-doc.
|
||
stdin:
|
||
a=i
|
||
cat << EO\
|
||
F
|
||
h$a
|
||
there
|
||
EOF
|
||
expected-stdout:
|
||
hi
|
||
there
|
||
---
|
||
name: heredoc-7
|
||
description:
|
||
Check that double quoted $ expressions in here delimiters are
|
||
not expanded and match the delimiter.
|
||
POSIX says only quote removal is applied to the delimiter.
|
||
stdin:
|
||
a=b
|
||
cat << "E$a"
|
||
hi
|
||
h$a
|
||
hb
|
||
E$a
|
||
echo done
|
||
expected-stdout:
|
||
hi
|
||
h$a
|
||
hb
|
||
done
|
||
---
|
||
name: heredoc-8
|
||
description:
|
||
Check that double quoted escaped $ expressions in here
|
||
delimiters are not expanded and match the delimiter.
|
||
POSIX says only quote removal is applied to the delimiter
|
||
(\ counts as a quote).
|
||
stdin:
|
||
a=b
|
||
cat << "E\$a"
|
||
hi
|
||
h$a
|
||
h\$a
|
||
hb
|
||
h\b
|
||
E$a
|
||
echo done
|
||
expected-stdout:
|
||
hi
|
||
h$a
|
||
h\$a
|
||
hb
|
||
h\b
|
||
done
|
||
---
|
||
name: heredoc-9a
|
||
description:
|
||
Check that here strings work.
|
||
stdin:
|
||
bar="bar
|
||
baz"
|
||
tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<foo
|
||
"$__progname" -c "tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<foo"
|
||
tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<"$bar"
|
||
tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<'$bar'
|
||
tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<\$bar
|
||
tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<-foo
|
||
tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<"$(echo "foo bar")"
|
||
tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<"A $(echo "foo bar") B"
|
||
tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<\$b\$b$bar
|
||
expected-stdout:
|
||
sbb
|
||
sbb
|
||
one
|
||
onm
|
||
$one
|
||
$one
|
||
-sbb
|
||
sbb one
|
||
A sbb one B
|
||
$o$oone
|
||
onm
|
||
---
|
||
name: heredoc-9b
|
||
description:
|
||
Check that a corner case of here strings works like bash
|
||
stdin:
|
||
fnord=42
|
||
bar="bar
|
||
\$fnord baz"
|
||
tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<$bar
|
||
expected-stdout:
|
||
one $sabeq onm
|
||
category: bash
|
||
---
|
||
name: heredoc-9c
|
||
description:
|
||
Check that a corner case of here strings works like ksh93, zsh
|
||
stdin:
|
||
fnord=42
|
||
bar="bar
|
||
\$fnord baz"
|
||
tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<$bar
|
||
expected-stdout:
|
||
one
|
||
$sabeq onm
|
||
---
|
||
name: heredoc-9d
|
||
description:
|
||
Check another corner case of here strings
|
||
stdin:
|
||
tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<< bar
|
||
expected-stdout:
|
||
one
|
||
---
|
||
name: heredoc-9e
|
||
description:
|
||
Check here string related regression with multiple iops
|
||
stdin:
|
||
echo $(tr r z <<<'bar' 2>/dev/null)
|
||
expected-stdout:
|
||
baz
|
||
---
|
||
name: heredoc-9f
|
||
description:
|
||
Check long here strings
|
||
stdin:
|
||
cat <<< "$( : )aa"
|
||
expected-stdout:
|
||
aa
|
||
---
|
||
name: heredoc-10
|
||
description:
|
||
Check direct here document assignment
|
||
category: !shell:ebcdic-yes
|
||
stdin:
|
||
x=u
|
||
va=<<EOF
|
||
=a $x \x40=
|
||
EOF
|
||
vb=<<'EOF'
|
||
=b $x \x40=
|
||
EOF
|
||
function foo {
|
||
vc=<<-EOF
|
||
=c $x \x40=
|
||
EOF
|
||
}
|
||
fnd=$(typeset -f foo)
|
||
print -r -- "$fnd"
|
||
function foo {
|
||
echo blub
|
||
}
|
||
foo
|
||
eval "$fnd"
|
||
foo
|
||
# rather nonsensical, but…
|
||
vd=<<<"=d $x \x40="
|
||
ve=<<<'=e $x \x40='
|
||
vf=<<<$'=f $x \x40='
|
||
# now check
|
||
print -r -- "| va={$va} vb={$vb} vc={$vc} vd={$vd} ve={$ve} vf={$vf} |"
|
||
# check append
|
||
v=<<-EOF
|
||
vapp1
|
||
EOF
|
||
v+=<<-EOF
|
||
vapp2
|
||
EOF
|
||
print -r -- "| ${v//$'\n'/^} |"
|
||
expected-stdout:
|
||
function foo {
|
||
vc=<<-EOF
|
||
=c $x \x40=
|
||
EOF
|
||
|
||
}
|
||
blub
|
||
| va={=a u \x40=
|
||
} vb={=b $x \x40=
|
||
} vc={=c u \x40=
|
||
} vd={=d u \x40=
|
||
} ve={=e $x \x40=
|
||
} vf={=f $x @=
|
||
} |
|
||
| vapp1^vapp2^ |
|
||
---
|
||
name: heredoc-10-ebcdic
|
||
description:
|
||
Check direct here document assignment
|
||
category: !shell:ebcdic-no
|
||
stdin:
|
||
x=u
|
||
va=<<EOF
|
||
=a $x \x7C=
|
||
EOF
|
||
vb=<<'EOF'
|
||
=b $x \x7C=
|
||
EOF
|
||
function foo {
|
||
vc=<<-EOF
|
||
=c $x \x7C=
|
||
EOF
|
||
}
|
||
fnd=$(typeset -f foo)
|
||
print -r -- "$fnd"
|
||
function foo {
|
||
echo blub
|
||
}
|
||
foo
|
||
eval "$fnd"
|
||
foo
|
||
# rather nonsensical, but…
|
||
vd=<<<"=d $x \x7C="
|
||
ve=<<<'=e $x \x7C='
|
||
vf=<<<$'=f $x \x7C='
|
||
# now check
|
||
print -r -- "| va={$va} vb={$vb} vc={$vc} vd={$vd} ve={$ve} vf={$vf} |"
|
||
# check append
|
||
v=<<-EOF
|
||
vapp1
|
||
EOF
|
||
v+=<<-EOF
|
||
vapp2
|
||
EOF
|
||
print -r -- "| ${v//$'\n'/^} |"
|
||
expected-stdout:
|
||
function foo {
|
||
vc=<<-EOF
|
||
=c $x \x7C=
|
||
EOF
|
||
|
||
}
|
||
blub
|
||
| va={=a u \x7C=
|
||
} vb={=b $x \x7C=
|
||
} vc={=c u \x7C=
|
||
} vd={=d u \x7C=
|
||
} ve={=e $x \x7C=
|
||
} vf={=f $x @=
|
||
} |
|
||
| vapp1^vapp2^ |
|
||
---
|
||
name: heredoc-11
|
||
description:
|
||
Check here documents with no or empty delimiter
|
||
stdin:
|
||
x=u
|
||
va=<<
|
||
=a $x \x40=
|
||
<<
|
||
vb=<<''
|
||
=b $x \x40=
|
||
|
||
function foo {
|
||
vc=<<-
|
||
=c $x \x40=
|
||
<<
|
||
vd=<<-''
|
||
=d $x \x40=
|
||
|
||
}
|
||
fnd=$(typeset -f foo)
|
||
print -r -- "$fnd"
|
||
function foo {
|
||
echo blub
|
||
}
|
||
foo
|
||
eval "$fnd"
|
||
foo
|
||
print -r -- "| va={$va} vb={$vb} vc={$vc} vd={$vd} |"
|
||
x=y
|
||
foo
|
||
typeset -f foo
|
||
print -r -- "| vc={$vc} vd={$vd} |"
|
||
# check append
|
||
v=<<-
|
||
vapp1
|
||
<<
|
||
v+=<<-''
|
||
vapp2
|
||
|
||
print -r -- "| ${v//$'\n'/^} |"
|
||
expected-stdout:
|
||
function foo {
|
||
vc=<<-
|
||
=c $x \x40=
|
||
<<
|
||
|
||
vd=<<-""
|
||
=d $x \x40=
|
||
|
||
|
||
}
|
||
blub
|
||
| va={=a u \x40=
|
||
} vb={=b $x \x40=
|
||
} vc={=c u \x40=
|
||
} vd={=d $x \x40=
|
||
} |
|
||
function foo {
|
||
vc=<<-
|
||
=c $x \x40=
|
||
<<
|
||
|
||
vd=<<-""
|
||
=d $x \x40=
|
||
|
||
|
||
}
|
||
| vc={=c y \x40=
|
||
} vd={=d $x \x40=
|
||
} |
|
||
| vapp1^vapp2^ |
|
||
---
|
||
name: heredoc-12
|
||
description:
|
||
Check here documents can use $* and $@; note shells vary:
|
||
• pdksh 5.2.14 acts the same
|
||
• dash has 1 and 2 the same but 3 lacks the space
|
||
• ksh93, bash4 differ in 2 by using space ipv colon
|
||
stdin:
|
||
set -- a b
|
||
nl='
|
||
'
|
||
IFS=" $nl"; n=1
|
||
cat <<EOF
|
||
$n foo $* foo
|
||
$n bar "$*" bar
|
||
$n baz $@ baz
|
||
$n bla "$@" bla
|
||
EOF
|
||
IFS=":"; n=2
|
||
cat <<EOF
|
||
$n foo $* foo
|
||
$n bar "$*" bar
|
||
$n baz $@ baz
|
||
$n bla "$@" bla
|
||
EOF
|
||
IFS=; n=3
|
||
cat <<EOF
|
||
$n foo $* foo
|
||
$n bar "$*" bar
|
||
$n baz $@ baz
|
||
$n bla "$@" bla
|
||
EOF
|
||
expected-stdout:
|
||
1 foo a b foo
|
||
1 bar "a b" bar
|
||
1 baz a b baz
|
||
1 bla "a b" bla
|
||
2 foo a:b foo
|
||
2 bar "a:b" bar
|
||
2 baz a:b baz
|
||
2 bla "a:b" bla
|
||
3 foo a b foo
|
||
3 bar "a b" bar
|
||
3 baz a b baz
|
||
3 bla "a b" bla
|
||
---
|
||
name: heredoc-14
|
||
description:
|
||
Check that using multiple here documents works
|
||
stdin:
|
||
foo() {
|
||
echo "got $(cat) on stdin"
|
||
echo "got $(cat <&4) on fd#4"
|
||
echo "got $(cat <&5) on fd#5"
|
||
}
|
||
bar() {
|
||
foo 4<<-a <<-b 5<<-c
|
||
four
|
||
a
|
||
zero
|
||
b
|
||
five
|
||
c
|
||
}
|
||
x=$(typeset -f bar)
|
||
eval "$x"
|
||
y=$(typeset -f bar)
|
||
[[ $x = "$y" ]]; echo $?
|
||
typeset -f bar
|
||
bar
|
||
expected-stdout:
|
||
0
|
||
bar() {
|
||
\foo 4<<-a <<-b 5<<-c
|
||
four
|
||
a
|
||
zero
|
||
b
|
||
five
|
||
c
|
||
|
||
}
|
||
got zero on stdin
|
||
got four on fd#4
|
||
got five on fd#5
|
||
---
|
||
name: heredoc-comsub-1
|
||
description:
|
||
Tests for here documents in COMSUB, taken from Austin ML
|
||
stdin:
|
||
text=$(cat <<EOF
|
||
here is the text
|
||
EOF)
|
||
echo = $text =
|
||
expected-stdout:
|
||
= here is the text =
|
||
---
|
||
name: heredoc-comsub-2
|
||
description:
|
||
Tests for here documents in COMSUB, taken from Austin ML
|
||
stdin:
|
||
unbalanced=$(cat <<EOF
|
||
this paren ) is a problem
|
||
EOF)
|
||
echo = $unbalanced =
|
||
expected-stdout:
|
||
= this paren ) is a problem =
|
||
---
|
||
name: heredoc-comsub-3
|
||
description:
|
||
Tests for here documents in COMSUB, taken from Austin ML
|
||
stdin:
|
||
balanced=$(cat <<EOF
|
||
these parens ( ) are not a problem
|
||
EOF)
|
||
echo = $balanced =
|
||
expected-stdout:
|
||
= these parens ( ) are not a problem =
|
||
---
|
||
name: heredoc-comsub-4
|
||
description:
|
||
Tests for here documents in COMSUB, taken from Austin ML
|
||
stdin:
|
||
balanced=$(cat <<EOF
|
||
these parens \( ) are a problem
|
||
EOF)
|
||
echo = $balanced =
|
||
expected-stdout:
|
||
= these parens \( ) are a problem =
|
||
---
|
||
name: heredoc-comsub-5
|
||
description:
|
||
Check heredoc and COMSUB mixture in input
|
||
stdin:
|
||
prefix() { sed -e "s/^/$1:/"; }
|
||
XXX() { echo x-en; }
|
||
YYY() { echo y-es; }
|
||
|
||
prefix A <<XXX && echo "$(prefix B <<XXX
|
||
echo line 1
|
||
XXX
|
||
echo line 2)" && prefix C <<YYY
|
||
echo line 3
|
||
XXX
|
||
echo line 4)"
|
||
echo line 5
|
||
YYY
|
||
XXX
|
||
expected-stdout:
|
||
A:echo line 3
|
||
B:echo line 1
|
||
line 2
|
||
C:echo line 4)"
|
||
C:echo line 5
|
||
x-en
|
||
---
|
||
name: heredoc-comsub-6
|
||
description:
|
||
Check here documents and here strings can be used
|
||
without a specific command, like $(<…) (extension)
|
||
stdin:
|
||
foo=bar
|
||
x=$(<<<EO${foo}F)
|
||
echo "3<$x>"
|
||
y=$(<<-EOF
|
||
hi!
|
||
|
||
$foo) is not a problem
|
||
|
||
|
||
EOF)
|
||
echo "7<$y>"
|
||
expected-stdout:
|
||
3<EObarF>
|
||
7<hi!
|
||
|
||
bar) is not a problem>
|
||
---
|
||
name: heredoc-subshell-1
|
||
description:
|
||
Tests for here documents in subshells, taken from Austin ML
|
||
stdin:
|
||
(cat <<EOF
|
||
some text
|
||
EOF)
|
||
echo end
|
||
expected-stdout:
|
||
some text
|
||
end
|
||
---
|
||
name: heredoc-subshell-2
|
||
description:
|
||
Tests for here documents in subshells, taken from Austin ML
|
||
stdin:
|
||
(cat <<EOF
|
||
some text
|
||
EOF
|
||
)
|
||
echo end
|
||
expected-stdout:
|
||
some text
|
||
end
|
||
---
|
||
name: heredoc-subshell-3
|
||
description:
|
||
Tests for here documents in subshells, taken from Austin ML
|
||
stdin:
|
||
(cat <<EOF; )
|
||
some text
|
||
EOF
|
||
echo end
|
||
expected-stdout:
|
||
some text
|
||
end
|
||
---
|
||
name: heredoc-weird-1
|
||
description:
|
||
Tests for here documents, taken from Austin ML
|
||
Documents current state in mksh, *NOT* necessarily correct!
|
||
stdin:
|
||
cat <<END
|
||
hello
|
||
END\
|
||
END
|
||
END
|
||
echo end
|
||
expected-stdout:
|
||
hello
|
||
ENDEND
|
||
end
|
||
---
|
||
name: heredoc-weird-2
|
||
description:
|
||
Tests for here documents, taken from Austin ML
|
||
stdin:
|
||
cat <<' END '
|
||
hello
|
||
END
|
||
echo end
|
||
expected-stdout:
|
||
hello
|
||
end
|
||
---
|
||
name: heredoc-weird-4
|
||
description:
|
||
Tests for here documents, taken from Austin ML
|
||
Documents current state in mksh, *NOT* necessarily correct!
|
||
stdin:
|
||
cat <<END
|
||
hello\
|
||
END
|
||
END
|
||
echo end
|
||
expected-stdout:
|
||
helloEND
|
||
end
|
||
---
|
||
name: heredoc-weird-5
|
||
description:
|
||
Tests for here documents, taken from Austin ML
|
||
Documents current state in mksh, *NOT* necessarily correct!
|
||
stdin:
|
||
cat <<END
|
||
hello
|
||
\END
|
||
END
|
||
echo end
|
||
expected-stdout:
|
||
hello
|
||
\END
|
||
end
|
||
---
|
||
name: heredoc-tmpfile-1
|
||
description:
|
||
Check that heredoc temp files aren't removed too soon or too late.
|
||
Heredoc in simple command.
|
||
stdin:
|
||
TMPDIR=$PWD
|
||
eval '
|
||
cat <<- EOF
|
||
hi
|
||
EOF
|
||
for i in a b ; do
|
||
cat <<- EOF
|
||
more
|
||
EOF
|
||
done
|
||
' &
|
||
sleep 1
|
||
echo Left overs: *
|
||
expected-stdout:
|
||
hi
|
||
more
|
||
more
|
||
Left overs: *
|
||
---
|
||
name: heredoc-tmpfile-2
|
||
description:
|
||
Check that heredoc temp files aren't removed too soon or too late.
|
||
Heredoc in function, multiple calls to function.
|
||
stdin:
|
||
TMPDIR=$PWD
|
||
eval '
|
||
foo() {
|
||
cat <<- EOF
|
||
hi
|
||
EOF
|
||
}
|
||
foo
|
||
foo
|
||
' &
|
||
sleep 1
|
||
echo Left overs: *
|
||
expected-stdout:
|
||
hi
|
||
hi
|
||
Left overs: *
|
||
---
|
||
name: heredoc-tmpfile-3
|
||
description:
|
||
Check that heredoc temp files aren't removed too soon or too late.
|
||
Heredoc in function in loop, multiple calls to function.
|
||
stdin:
|
||
TMPDIR=$PWD
|
||
eval '
|
||
foo() {
|
||
cat <<- EOF
|
||
hi
|
||
EOF
|
||
}
|
||
for i in a b; do
|
||
foo
|
||
foo() {
|
||
cat <<- EOF
|
||
folks $i
|
||
EOF
|
||
}
|
||
done
|
||
foo
|
||
' &
|
||
sleep 1
|
||
echo Left overs: *
|
||
expected-stdout:
|
||
hi
|
||
folks b
|
||
folks b
|
||
Left overs: *
|
||
---
|
||
name: heredoc-tmpfile-4
|
||
description:
|
||
Check that heredoc temp files aren't removed too soon or too late.
|
||
Backgrounded simple command with here doc
|
||
stdin:
|
||
TMPDIR=$PWD
|
||
eval '
|
||
cat <<- EOF &
|
||
hi
|
||
EOF
|
||
' &
|
||
sleep 1
|
||
echo Left overs: *
|
||
expected-stdout:
|
||
hi
|
||
Left overs: *
|
||
---
|
||
name: heredoc-tmpfile-5
|
||
description:
|
||
Check that heredoc temp files aren't removed too soon or too late.
|
||
Backgrounded subshell command with here doc
|
||
stdin:
|
||
TMPDIR=$PWD
|
||
eval '
|
||
(
|
||
sleep 1 # so parent exits
|
||
echo A
|
||
cat <<- EOF
|
||
hi
|
||
EOF
|
||
echo B
|
||
) &
|
||
' &
|
||
sleep 2
|
||
echo Left overs: *
|
||
expected-stdout:
|
||
A
|
||
hi
|
||
B
|
||
Left overs: *
|
||
---
|
||
name: heredoc-tmpfile-6
|
||
description:
|
||
Check that heredoc temp files aren't removed too soon or too late.
|
||
Heredoc in pipeline.
|
||
stdin:
|
||
TMPDIR=$PWD
|
||
eval '
|
||
cat <<- EOF | sed "s/hi/HI/"
|
||
hi
|
||
EOF
|
||
' &
|
||
sleep 1
|
||
echo Left overs: *
|
||
expected-stdout:
|
||
HI
|
||
Left overs: *
|
||
---
|
||
name: heredoc-tmpfile-7
|
||
description:
|
||
Check that heredoc temp files aren't removed too soon or too late.
|
||
Heredoc in backgrounded pipeline.
|
||
stdin:
|
||
TMPDIR=$PWD
|
||
eval '
|
||
cat <<- EOF | sed 's/hi/HI/' &
|
||
hi
|
||
EOF
|
||
' &
|
||
sleep 1
|
||
echo Left overs: *
|
||
expected-stdout:
|
||
HI
|
||
Left overs: *
|
||
---
|
||
name: heredoc-tmpfile-8
|
||
description:
|
||
Check that heredoc temp files aren't removed too soon or too
|
||
late. Heredoc in function, backgrounded call to function.
|
||
This check can fail on slow machines (<100 MHz), or Cygwin,
|
||
that's normal.
|
||
need-pass: no
|
||
stdin:
|
||
TMPDIR=$PWD
|
||
# Background eval so main shell doesn't do parsing
|
||
eval '
|
||
foo() {
|
||
cat <<- EOF
|
||
hi
|
||
EOF
|
||
}
|
||
foo
|
||
# sleep so eval can die
|
||
(sleep 1; foo) &
|
||
(sleep 1; foo) &
|
||
foo
|
||
' &
|
||
sleep 2
|
||
echo Left overs: *
|
||
expected-stdout:
|
||
hi
|
||
hi
|
||
hi
|
||
hi
|
||
Left overs: *
|
||
---
|
||
name: heredoc-quoting-unsubst
|
||
description:
|
||
Check for correct handling of quoted characters in
|
||
here documents without substitution (marker is quoted).
|
||
stdin:
|
||
foo=bar
|
||
cat <<-'EOF'
|
||
x " \" \ \\ $ \$ `echo baz` \`echo baz\` $foo \$foo x
|
||
EOF
|
||
expected-stdout:
|
||
x " \" \ \\ $ \$ `echo baz` \`echo baz\` $foo \$foo x
|
||
---
|
||
name: heredoc-quoting-subst
|
||
description:
|
||
Check for correct handling of quoted characters in
|
||
here documents with substitution (marker is not quoted).
|
||
stdin:
|
||
foo=bar
|
||
cat <<-EOF
|
||
x " \" \ \\ $ \$ `echo baz` \`echo baz\` $foo \$foo x
|
||
EOF
|
||
expected-stdout:
|
||
x " \" \ \ $ $ baz `echo baz` bar $foo x
|
||
---
|
||
name: single-quotes-in-braces
|
||
description:
|
||
Check that single quotes inside unquoted {} are treated as quotes
|
||
stdin:
|
||
foo=1
|
||
echo ${foo:+'blah $foo'}
|
||
expected-stdout:
|
||
blah $foo
|
||
---
|
||
name: single-quotes-in-quoted-braces
|
||
description:
|
||
Check that single quotes inside quoted {} are treated as
|
||
normal char
|
||
stdin:
|
||
foo=1
|
||
echo "${foo:+'blah $foo'}"
|
||
expected-stdout:
|
||
'blah 1'
|
||
---
|
||
name: single-quotes-in-braces-nested
|
||
description:
|
||
Check that single quotes inside unquoted {} are treated as quotes,
|
||
even if that's inside a double-quoted command expansion
|
||
stdin:
|
||
foo=1
|
||
echo "$( echo ${foo:+'blah $foo'})"
|
||
expected-stdout:
|
||
blah $foo
|
||
---
|
||
name: single-quotes-in-brace-pattern
|
||
description:
|
||
Check that single quotes inside {} pattern are treated as quotes
|
||
stdin:
|
||
foo=1234
|
||
echo ${foo%'2'*} "${foo%'2'*}" ${foo%2'*'} "${foo%2'*'}"
|
||
expected-stdout:
|
||
1 1 1234 1234
|
||
---
|
||
name: single-quotes-in-heredoc-braces
|
||
description:
|
||
Check that single quotes inside {} in heredoc are treated
|
||
as normal char
|
||
stdin:
|
||
foo=1
|
||
cat <<EOM
|
||
${foo:+'blah $foo'}
|
||
EOM
|
||
expected-stdout:
|
||
'blah 1'
|
||
---
|
||
name: single-quotes-in-nested-braces
|
||
description:
|
||
Check that single quotes inside nested unquoted {} are
|
||
treated as quotes
|
||
stdin:
|
||
foo=1
|
||
echo ${foo:+${foo:+'blah $foo'}}
|
||
expected-stdout:
|
||
blah $foo
|
||
---
|
||
name: single-quotes-in-nested-quoted-braces
|
||
description:
|
||
Check that single quotes inside nested quoted {} are treated
|
||
as normal char
|
||
stdin:
|
||
foo=1
|
||
echo "${foo:+${foo:+'blah $foo'}}"
|
||
expected-stdout:
|
||
'blah 1'
|
||
---
|
||
name: single-quotes-in-nested-braces-nested
|
||
description:
|
||
Check that single quotes inside nested unquoted {} are treated
|
||
as quotes, even if that's inside a double-quoted command expansion
|
||
stdin:
|
||
foo=1
|
||
echo "$( echo ${foo:+${foo:+'blah $foo'}})"
|
||
expected-stdout:
|
||
blah $foo
|
||
---
|
||
name: single-quotes-in-nested-brace-pattern
|
||
description:
|
||
Check that single quotes inside nested {} pattern are treated as quotes
|
||
stdin:
|
||
foo=1234
|
||
echo ${foo:+${foo%'2'*}} "${foo:+${foo%'2'*}}" ${foo:+${foo%2'*'}} "${foo:+${foo%2'*'}}"
|
||
expected-stdout:
|
||
1 1 1234 1234
|
||
---
|
||
name: single-quotes-in-heredoc-nested-braces
|
||
description:
|
||
Check that single quotes inside nested {} in heredoc are treated
|
||
as normal char
|
||
stdin:
|
||
foo=1
|
||
cat <<EOM
|
||
${foo:+${foo:+'blah $foo'}}
|
||
EOM
|
||
expected-stdout:
|
||
'blah 1'
|
||
---
|
||
name: history-basic
|
||
description:
|
||
See if we can test history at all
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
echo hi
|
||
fc -l
|
||
expected-stdout:
|
||
hi
|
||
1 echo hi
|
||
expected-stderr-pattern:
|
||
/^X*$/
|
||
---
|
||
name: history-dups
|
||
description:
|
||
Verify duplicates and spaces are not entered
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
echo hi
|
||
echo yo
|
||
echo hi
|
||
fc -l
|
||
expected-stdout:
|
||
hi
|
||
yo
|
||
hi
|
||
1 echo hi
|
||
expected-stderr-pattern:
|
||
/^X*$/
|
||
---
|
||
name: history-unlink
|
||
description:
|
||
Check if broken HISTFILEs do not cause trouble
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=foo/hist.file!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
file-setup: dir 755 "foo"
|
||
file-setup: file 644 "foo/hist.file"
|
||
sometext
|
||
time-limit: 5
|
||
perl-setup: chmod(0555, "foo");
|
||
stdin:
|
||
echo hi
|
||
fc -l
|
||
chmod 0755 foo
|
||
expected-stdout:
|
||
hi
|
||
1 echo hi
|
||
expected-stderr-pattern:
|
||
/(.*can't unlink HISTFILE.*\n)?X*$/
|
||
---
|
||
name: history-multiline
|
||
description:
|
||
Check correct multiline history, Debian #783978
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
PS2=Y
|
||
stdin:
|
||
for i in A B C
|
||
do
|
||
print $i
|
||
print $i
|
||
done
|
||
fc -l
|
||
expected-stdout:
|
||
A
|
||
A
|
||
B
|
||
B
|
||
C
|
||
C
|
||
1 for i in A B C
|
||
do
|
||
print $i
|
||
print $i
|
||
done
|
||
expected-stderr-pattern:
|
||
/^XYYYYXX$/
|
||
---
|
||
name: history-e-minus-1
|
||
description:
|
||
Check if more recent command is executed
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
echo hi
|
||
echo there
|
||
fc -e -
|
||
expected-stdout:
|
||
hi
|
||
there
|
||
there
|
||
expected-stderr-pattern:
|
||
/^X*echo there\nX*$/
|
||
---
|
||
name: history-e-minus-2
|
||
description:
|
||
Check that repeated command is printed before command
|
||
is re-executed.
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
exec 2>&1
|
||
echo hi
|
||
echo there
|
||
fc -e -
|
||
expected-stdout-pattern:
|
||
/X*hi\nX*there\nX*echo there\nthere\nX*/
|
||
expected-stderr-pattern:
|
||
/^X*$/
|
||
---
|
||
name: history-e-minus-3
|
||
description:
|
||
fc -e - fails when there is no history
|
||
(ksh93 has a bug that causes this to fail)
|
||
(ksh88 loops on this)
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
fc -e -
|
||
echo ok
|
||
expected-stdout:
|
||
ok
|
||
expected-stderr-pattern:
|
||
/^X*.*:.*history.*\nX*$/
|
||
---
|
||
name: history-e-minus-4
|
||
description:
|
||
Check if "fc -e -" command output goes to stdout.
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
echo abc
|
||
fc -e - | (read x; echo "A $x")
|
||
echo ok
|
||
expected-stdout:
|
||
abc
|
||
A abc
|
||
ok
|
||
expected-stderr-pattern:
|
||
/^X*echo abc\nX*/
|
||
---
|
||
name: history-e-minus-5
|
||
description:
|
||
fc is replaced in history by new command.
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
echo abc def
|
||
echo ghi jkl
|
||
:
|
||
fc -e - echo
|
||
fc -l 2 5
|
||
expected-stdout:
|
||
abc def
|
||
ghi jkl
|
||
ghi jkl
|
||
2 echo ghi jkl
|
||
3 :
|
||
4 echo ghi jkl
|
||
5 fc -l 2 5
|
||
expected-stderr-pattern:
|
||
/^X*echo ghi jkl\nX*$/
|
||
---
|
||
name: history-list-1
|
||
description:
|
||
List lists correct range
|
||
(ksh88 fails 'cause it lists the fc command)
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
echo line 1
|
||
echo line 2
|
||
echo line 3
|
||
fc -l -- -2
|
||
expected-stdout:
|
||
line 1
|
||
line 2
|
||
line 3
|
||
2 echo line 2
|
||
3 echo line 3
|
||
expected-stderr-pattern:
|
||
/^X*$/
|
||
---
|
||
name: history-list-2
|
||
description:
|
||
Lists oldest history if given pre-historic number
|
||
(ksh93 has a bug that causes this to fail)
|
||
(ksh88 fails 'cause it lists the fc command)
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
echo line 1
|
||
echo line 2
|
||
echo line 3
|
||
fc -l -- -40
|
||
expected-stdout:
|
||
line 1
|
||
line 2
|
||
line 3
|
||
1 echo line 1
|
||
2 echo line 2
|
||
3 echo line 3
|
||
expected-stderr-pattern:
|
||
/^X*$/
|
||
---
|
||
name: history-list-3
|
||
description:
|
||
Can give number 'options' to fc
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
echo line 1
|
||
echo line 2
|
||
echo line 3
|
||
echo line 4
|
||
fc -l -3 -2
|
||
expected-stdout:
|
||
line 1
|
||
line 2
|
||
line 3
|
||
line 4
|
||
2 echo line 2
|
||
3 echo line 3
|
||
expected-stderr-pattern:
|
||
/^X*$/
|
||
---
|
||
name: history-list-4
|
||
description:
|
||
-1 refers to previous command
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
echo line 1
|
||
echo line 2
|
||
echo line 3
|
||
echo line 4
|
||
fc -l -1 -1
|
||
expected-stdout:
|
||
line 1
|
||
line 2
|
||
line 3
|
||
line 4
|
||
4 echo line 4
|
||
expected-stderr-pattern:
|
||
/^X*$/
|
||
---
|
||
name: history-list-5
|
||
description:
|
||
List command stays in history
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
echo line 1
|
||
echo line 2
|
||
echo line 3
|
||
echo line 4
|
||
fc -l -1 -1
|
||
fc -l -2 -1
|
||
expected-stdout:
|
||
line 1
|
||
line 2
|
||
line 3
|
||
line 4
|
||
4 echo line 4
|
||
4 echo line 4
|
||
5 fc -l -1 -1
|
||
expected-stderr-pattern:
|
||
/^X*$/
|
||
---
|
||
name: history-list-6
|
||
description:
|
||
HISTSIZE limits about of history kept.
|
||
(ksh88 fails 'cause it lists the fc command)
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!HISTSIZE=3!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
echo line 1
|
||
echo line 2
|
||
echo line 3
|
||
echo line 4
|
||
echo line 5
|
||
fc -l
|
||
expected-stdout:
|
||
line 1
|
||
line 2
|
||
line 3
|
||
line 4
|
||
line 5
|
||
4 echo line 4
|
||
5 echo line 5
|
||
expected-stderr-pattern:
|
||
/^X*$/
|
||
---
|
||
name: history-list-7
|
||
description:
|
||
fc allows too old/new errors in range specification
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!HISTSIZE=3!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
echo line 1
|
||
echo line 2
|
||
echo line 3
|
||
echo line 4
|
||
echo line 5
|
||
fc -l 1 30
|
||
expected-stdout:
|
||
line 1
|
||
line 2
|
||
line 3
|
||
line 4
|
||
line 5
|
||
4 echo line 4
|
||
5 echo line 5
|
||
6 fc -l 1 30
|
||
expected-stderr-pattern:
|
||
/^X*$/
|
||
---
|
||
name: history-list-r-1
|
||
description:
|
||
test -r flag in history
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
echo line 1
|
||
echo line 2
|
||
echo line 3
|
||
echo line 4
|
||
echo line 5
|
||
fc -l -r 2 4
|
||
expected-stdout:
|
||
line 1
|
||
line 2
|
||
line 3
|
||
line 4
|
||
line 5
|
||
4 echo line 4
|
||
3 echo line 3
|
||
2 echo line 2
|
||
expected-stderr-pattern:
|
||
/^X*$/
|
||
---
|
||
name: history-list-r-2
|
||
description:
|
||
If first is newer than last, -r is implied.
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
echo line 1
|
||
echo line 2
|
||
echo line 3
|
||
echo line 4
|
||
echo line 5
|
||
fc -l 4 2
|
||
expected-stdout:
|
||
line 1
|
||
line 2
|
||
line 3
|
||
line 4
|
||
line 5
|
||
4 echo line 4
|
||
3 echo line 3
|
||
2 echo line 2
|
||
expected-stderr-pattern:
|
||
/^X*$/
|
||
---
|
||
name: history-list-r-3
|
||
description:
|
||
If first is newer than last, -r is cancelled.
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
echo line 1
|
||
echo line 2
|
||
echo line 3
|
||
echo line 4
|
||
echo line 5
|
||
fc -l -r 4 2
|
||
expected-stdout:
|
||
line 1
|
||
line 2
|
||
line 3
|
||
line 4
|
||
line 5
|
||
2 echo line 2
|
||
3 echo line 3
|
||
4 echo line 4
|
||
expected-stderr-pattern:
|
||
/^X*$/
|
||
---
|
||
name: history-subst-1
|
||
description:
|
||
Basic substitution
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
echo abc def
|
||
echo ghi jkl
|
||
fc -e - abc=AB 'echo a'
|
||
expected-stdout:
|
||
abc def
|
||
ghi jkl
|
||
AB def
|
||
expected-stderr-pattern:
|
||
/^X*echo AB def\nX*$/
|
||
---
|
||
name: history-subst-2
|
||
description:
|
||
Does subst find previous command?
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
echo abc def
|
||
echo ghi jkl
|
||
fc -e - jkl=XYZQRT 'echo g'
|
||
expected-stdout:
|
||
abc def
|
||
ghi jkl
|
||
ghi XYZQRT
|
||
expected-stderr-pattern:
|
||
/^X*echo ghi XYZQRT\nX*$/
|
||
---
|
||
name: history-subst-3
|
||
description:
|
||
Does subst find previous command when no arguments given
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
echo abc def
|
||
echo ghi jkl
|
||
fc -e - jkl=XYZQRT
|
||
expected-stdout:
|
||
abc def
|
||
ghi jkl
|
||
ghi XYZQRT
|
||
expected-stderr-pattern:
|
||
/^X*echo ghi XYZQRT\nX*$/
|
||
---
|
||
name: history-subst-4
|
||
description:
|
||
Global substitutions work
|
||
(ksh88 and ksh93 do not have -g option)
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
echo abc def asjj sadjhasdjh asdjhasd
|
||
fc -e - -g a=FooBAR
|
||
expected-stdout:
|
||
abc def asjj sadjhasdjh asdjhasd
|
||
FooBARbc def FooBARsjj sFooBARdjhFooBARsdjh FooBARsdjhFooBARsd
|
||
expected-stderr-pattern:
|
||
/^X*echo FooBARbc def FooBARsjj sFooBARdjhFooBARsdjh FooBARsdjhFooBARsd\nX*$/
|
||
---
|
||
name: history-subst-5
|
||
description:
|
||
Make sure searches don't find current (fc) command
|
||
(ksh88/ksh93 don't have the ? prefix thing so they fail this test)
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
echo abc def
|
||
echo ghi jkl
|
||
fc -e - abc=AB \?abc
|
||
expected-stdout:
|
||
abc def
|
||
ghi jkl
|
||
AB def
|
||
expected-stderr-pattern:
|
||
/^X*echo AB def\nX*$/
|
||
---
|
||
name: history-ed-1-old
|
||
description:
|
||
Basic (ed) editing works (assumes you have generic ed editor
|
||
that prints no prompts). This is for oldish ed(1) which write
|
||
the character count to stdout.
|
||
category: stdout-ed
|
||
need-ctty: yes
|
||
need-pass: no
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
echo abc def
|
||
fc echo
|
||
s/abc/FOOBAR/
|
||
w
|
||
q
|
||
expected-stdout:
|
||
abc def
|
||
13
|
||
16
|
||
FOOBAR def
|
||
expected-stderr-pattern:
|
||
/^X*echo FOOBAR def\nX*$/
|
||
---
|
||
name: history-ed-2-old
|
||
description:
|
||
Correct command is edited when number given
|
||
category: stdout-ed
|
||
need-ctty: yes
|
||
need-pass: no
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
echo line 1
|
||
echo line 2 is here
|
||
echo line 3
|
||
echo line 4
|
||
fc 2
|
||
s/is here/is changed/
|
||
w
|
||
q
|
||
expected-stdout:
|
||
line 1
|
||
line 2 is here
|
||
line 3
|
||
line 4
|
||
20
|
||
23
|
||
line 2 is changed
|
||
expected-stderr-pattern:
|
||
/^X*echo line 2 is changed\nX*$/
|
||
---
|
||
name: history-ed-3-old
|
||
description:
|
||
Newly created multi line commands show up as single command
|
||
in history.
|
||
(ksh88 fails 'cause it lists the fc command)
|
||
category: stdout-ed
|
||
need-ctty: yes
|
||
need-pass: no
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
echo abc def
|
||
fc echo
|
||
s/abc/FOOBAR/
|
||
$a
|
||
echo a new line
|
||
.
|
||
w
|
||
q
|
||
fc -l
|
||
expected-stdout:
|
||
abc def
|
||
13
|
||
32
|
||
FOOBAR def
|
||
a new line
|
||
1 echo abc def
|
||
2 echo FOOBAR def
|
||
echo a new line
|
||
expected-stderr-pattern:
|
||
/^X*echo FOOBAR def\necho a new line\nX*$/
|
||
---
|
||
name: history-ed-1
|
||
description:
|
||
Basic (ed) editing works (assumes you have generic ed editor
|
||
that prints no prompts). This is for newish ed(1) and stderr.
|
||
category: !no-stderr-ed
|
||
need-ctty: yes
|
||
need-pass: no
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
echo abc def
|
||
fc echo
|
||
s/abc/FOOBAR/
|
||
w
|
||
q
|
||
expected-stdout:
|
||
abc def
|
||
FOOBAR def
|
||
expected-stderr-pattern:
|
||
/^X*13\n16\necho FOOBAR def\nX*$/
|
||
---
|
||
name: history-ed-2
|
||
description:
|
||
Correct command is edited when number given
|
||
category: !no-stderr-ed
|
||
need-ctty: yes
|
||
need-pass: no
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
echo line 1
|
||
echo line 2 is here
|
||
echo line 3
|
||
echo line 4
|
||
fc 2
|
||
s/is here/is changed/
|
||
w
|
||
q
|
||
expected-stdout:
|
||
line 1
|
||
line 2 is here
|
||
line 3
|
||
line 4
|
||
line 2 is changed
|
||
expected-stderr-pattern:
|
||
/^X*20\n23\necho line 2 is changed\nX*$/
|
||
---
|
||
name: history-ed-3
|
||
description:
|
||
Newly created multi line commands show up as single command
|
||
in history.
|
||
category: !no-stderr-ed
|
||
need-ctty: yes
|
||
need-pass: no
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
echo abc def
|
||
fc echo
|
||
s/abc/FOOBAR/
|
||
$a
|
||
echo a new line
|
||
.
|
||
w
|
||
q
|
||
fc -l
|
||
expected-stdout:
|
||
abc def
|
||
FOOBAR def
|
||
a new line
|
||
1 echo abc def
|
||
2 echo FOOBAR def
|
||
echo a new line
|
||
expected-stderr-pattern:
|
||
/^X*13\n32\necho FOOBAR def\necho a new line\nX*$/
|
||
---
|
||
name: IFS-space-1
|
||
description:
|
||
Simple test, default IFS
|
||
stdin:
|
||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||
set -- A B C
|
||
showargs 1 $*
|
||
showargs 2 "$*"
|
||
showargs 3 $@
|
||
showargs 4 "$@"
|
||
expected-stdout:
|
||
<1> <A> <B> <C> .
|
||
<2> <A B C> .
|
||
<3> <A> <B> <C> .
|
||
<4> <A> <B> <C> .
|
||
---
|
||
name: IFS-colon-1
|
||
description:
|
||
Simple test, IFS=:
|
||
stdin:
|
||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||
IFS=:
|
||
set -- A B C
|
||
showargs 1 $*
|
||
showargs 2 "$*"
|
||
showargs 3 $@
|
||
showargs 4 "$@"
|
||
expected-stdout:
|
||
<1> <A> <B> <C> .
|
||
<2> <A:B:C> .
|
||
<3> <A> <B> <C> .
|
||
<4> <A> <B> <C> .
|
||
---
|
||
name: IFS-null-1
|
||
description:
|
||
Simple test, IFS=""
|
||
stdin:
|
||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||
IFS=""
|
||
set -- A B C
|
||
showargs 1 $*
|
||
showargs 2 "$*"
|
||
showargs 3 $@
|
||
showargs 4 "$@"
|
||
expected-stdout:
|
||
<1> <A> <B> <C> .
|
||
<2> <ABC> .
|
||
<3> <A> <B> <C> .
|
||
<4> <A> <B> <C> .
|
||
---
|
||
name: IFS-space-colon-1
|
||
description:
|
||
Simple test, IFS=<white-space>:
|
||
stdin:
|
||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||
IFS="$IFS:"
|
||
set --
|
||
showargs 1 $*
|
||
showargs 2 "$*"
|
||
showargs 3 $@
|
||
showargs 4 "$@"
|
||
showargs 5 : "$@"
|
||
expected-stdout:
|
||
<1> .
|
||
<2> <> .
|
||
<3> .
|
||
<4> .
|
||
<5> <:> .
|
||
---
|
||
name: IFS-space-colon-2
|
||
description:
|
||
Simple test, IFS=<white-space>:
|
||
AT&T ksh fails this, POSIX says the test is correct.
|
||
stdin:
|
||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||
IFS="$IFS:"
|
||
set --
|
||
showargs :"$@"
|
||
expected-stdout:
|
||
<:> .
|
||
---
|
||
name: IFS-space-colon-4
|
||
description:
|
||
Simple test, IFS=<white-space>:
|
||
stdin:
|
||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||
IFS="$IFS:"
|
||
set --
|
||
showargs "$@$@"
|
||
expected-stdout:
|
||
.
|
||
---
|
||
name: IFS-space-colon-5
|
||
description:
|
||
Simple test, IFS=<white-space>:
|
||
Don't know what POSIX thinks of this. AT&T ksh does not do this.
|
||
stdin:
|
||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||
IFS="$IFS:"
|
||
set --
|
||
showargs "${@:-}"
|
||
expected-stdout:
|
||
<> .
|
||
---
|
||
name: IFS-subst-1
|
||
description:
|
||
Simple test, IFS=<white-space>:
|
||
stdin:
|
||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||
IFS="$IFS:"
|
||
x=":b: :"
|
||
echo -n '1:'; for i in $x ; do echo -n " [$i]" ; done ; echo
|
||
echo -n '2:'; for i in :b:: ; do echo -n " [$i]" ; done ; echo
|
||
showargs 3 $x
|
||
showargs 4 :b::
|
||
x="a:b:"
|
||
echo -n '5:'; for i in $x ; do echo -n " [$i]" ; done ; echo
|
||
showargs 6 $x
|
||
x="a::c"
|
||
echo -n '7:'; for i in $x ; do echo -n " [$i]" ; done ; echo
|
||
showargs 8 $x
|
||
echo -n '9:'; for i in ${FOO-`echo -n h:i`th:ere} ; do echo -n " [$i]" ; done ; echo
|
||
showargs 10 ${FOO-`echo -n h:i`th:ere}
|
||
showargs 11 "${FOO-`echo -n h:i`th:ere}"
|
||
x=" A : B::D"
|
||
echo -n '12:'; for i in $x ; do echo -n " [$i]" ; done ; echo
|
||
showargs 13 $x
|
||
expected-stdout:
|
||
1: [] [b] []
|
||
2: [:b::]
|
||
<3> <> <b> <> .
|
||
<4> <:b::> .
|
||
5: [a] [b]
|
||
<6> <a> <b> .
|
||
7: [a] [] [c]
|
||
<8> <a> <> <c> .
|
||
9: [h] [ith] [ere]
|
||
<10> <h> <ith> <ere> .
|
||
<11> <h:ith:ere> .
|
||
12: [A] [B] [] [D]
|
||
<13> <A> <B> <> <D> .
|
||
---
|
||
name: IFS-subst-2
|
||
description:
|
||
Check leading whitespace after trim does not make a field
|
||
stdin:
|
||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||
x="X 1 2"
|
||
showargs 1 shift ${x#X}
|
||
expected-stdout:
|
||
<1> <shift> <1> <2> .
|
||
---
|
||
name: IFS-subst-3-arr
|
||
description:
|
||
Check leading IFS non-whitespace after trim does make a field
|
||
but leading IFS whitespace does not, nor empty replacements
|
||
stdin:
|
||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||
showargs 0 ${-+}
|
||
IFS=:
|
||
showargs 1 ${-+:foo:bar}
|
||
IFS=' '
|
||
showargs 2 ${-+ foo bar}
|
||
expected-stdout:
|
||
<0> .
|
||
<1> <> <foo> <bar> .
|
||
<2> <foo> <bar> .
|
||
---
|
||
name: IFS-subst-3-ass
|
||
description:
|
||
Check non-field semantics
|
||
stdin:
|
||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||
showargs 0 x=${-+}
|
||
IFS=:
|
||
showargs 1 x=${-+:foo:bar}
|
||
IFS=' '
|
||
showargs 2 x=${-+ foo bar}
|
||
expected-stdout:
|
||
<0> <x=> .
|
||
<1> <x=> <foo> <bar> .
|
||
<2> <x=> <foo> <bar> .
|
||
---
|
||
name: IFS-subst-3-lcl
|
||
description:
|
||
Check non-field semantics, smaller corner case (LP#1381965)
|
||
stdin:
|
||
set -x
|
||
local regex=${2:-}
|
||
exit 1
|
||
expected-exit: e != 0
|
||
expected-stderr-pattern:
|
||
/regex=/
|
||
---
|
||
name: IFS-subst-4-1
|
||
description:
|
||
reported by mikeserv
|
||
stdin:
|
||
pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; }
|
||
a='space divded argument
|
||
here'
|
||
IFS=\ ; set -- $a
|
||
IFS= ; q="$*" ; nq=$*
|
||
pfn "$*" $* "$q" "$nq"
|
||
[ "$q" = "$nq" ] && echo =true || echo =false
|
||
expected-stdout:
|
||
<spacedivdedargument
|
||
here>
|
||
<space>
|
||
<divded>
|
||
<argument
|
||
here>
|
||
<spacedivdedargument
|
||
here>
|
||
<spacedivdedargument
|
||
here>
|
||
=true
|
||
---
|
||
name: IFS-subst-4-2
|
||
description:
|
||
extended testsuite based on problem by mikeserv
|
||
stdin:
|
||
pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; }
|
||
a='space divded argument
|
||
here'
|
||
IFS=\ ; set -- $a
|
||
IFS= ; q="$@" ; nq=$@
|
||
pfn "$*" $* "$q" "$nq"
|
||
[ "$q" = "$nq" ] && echo =true || echo =false
|
||
expected-stdout:
|
||
<spacedivdedargument
|
||
here>
|
||
<space>
|
||
<divded>
|
||
<argument
|
||
here>
|
||
<space divded argument
|
||
here>
|
||
<space divded argument
|
||
here>
|
||
=true
|
||
---
|
||
name: IFS-subst-4-3
|
||
description:
|
||
extended testsuite based on problem by mikeserv
|
||
stdin:
|
||
pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; }
|
||
a='space divded argument
|
||
here'
|
||
IFS=\ ; set -- $a; IFS=
|
||
qs="$*"
|
||
nqs=$*
|
||
qk="$@"
|
||
nqk=$@
|
||
print -nr -- '= qs '; pfn "$qs"
|
||
print -nr -- '=nqs '; pfn "$nqs"
|
||
print -nr -- '= qk '; pfn "$qk"
|
||
print -nr -- '=nqk '; pfn "$nqk"
|
||
print -nr -- '~ qs '; pfn "$*"
|
||
print -nr -- '~nqs '; pfn $*
|
||
print -nr -- '~ qk '; pfn "$@"
|
||
print -nr -- '~nqk '; pfn $@
|
||
expected-stdout:
|
||
= qs <spacedivdedargument
|
||
here>
|
||
=nqs <spacedivdedargument
|
||
here>
|
||
= qk <space divded argument
|
||
here>
|
||
=nqk <space divded argument
|
||
here>
|
||
~ qs <spacedivdedargument
|
||
here>
|
||
~nqs <space>
|
||
<divded>
|
||
<argument
|
||
here>
|
||
~ qk <space>
|
||
<divded>
|
||
<argument
|
||
here>
|
||
~nqk <space>
|
||
<divded>
|
||
<argument
|
||
here>
|
||
---
|
||
name: IFS-subst-4-4
|
||
description:
|
||
extended testsuite based on problem by mikeserv
|
||
stdin:
|
||
pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; }
|
||
a='space divded argument
|
||
here'
|
||
IFS=\ ; set -- $a; IFS=
|
||
qs="$*"
|
||
print -nr -- '= qs '; pfn "$qs"
|
||
print -nr -- '~ qs '; pfn "$*"
|
||
nqs=$*
|
||
print -nr -- '=nqs '; pfn "$nqs"
|
||
print -nr -- '~nqs '; pfn $*
|
||
qk="$@"
|
||
print -nr -- '= qk '; pfn "$qk"
|
||
print -nr -- '~ qk '; pfn "$@"
|
||
nqk=$@
|
||
print -nr -- '=nqk '; pfn "$nqk"
|
||
print -nr -- '~nqk '; pfn $@
|
||
expected-stdout:
|
||
= qs <spacedivdedargument
|
||
here>
|
||
~ qs <spacedivdedargument
|
||
here>
|
||
=nqs <spacedivdedargument
|
||
here>
|
||
~nqs <space>
|
||
<divded>
|
||
<argument
|
||
here>
|
||
= qk <space divded argument
|
||
here>
|
||
~ qk <space>
|
||
<divded>
|
||
<argument
|
||
here>
|
||
=nqk <space divded argument
|
||
here>
|
||
~nqk <space>
|
||
<divded>
|
||
<argument
|
||
here>
|
||
---
|
||
name: IFS-subst-4-4p
|
||
description:
|
||
extended testsuite based on problem by mikeserv
|
||
stdin:
|
||
pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; }
|
||
a='space divded argument
|
||
here'
|
||
IFS=\ ; set -- $a; IFS=
|
||
unset v
|
||
qs=${v:-"$*"}
|
||
print -nr -- '= qs '; pfn "$qs"
|
||
print -nr -- '~ qs '; pfn ${v:-"$*"}
|
||
nqs=${v:-$*}
|
||
print -nr -- '=nqs '; pfn "$nqs"
|
||
print -nr -- '~nqs '; pfn ${v:-$*}
|
||
qk=${v:-"$@"}
|
||
print -nr -- '= qk '; pfn "$qk"
|
||
print -nr -- '~ qk '; pfn ${v:-"$@"}
|
||
nqk=${v:-$@}
|
||
print -nr -- '=nqk '; pfn "$nqk"
|
||
print -nr -- '~nqk '; pfn ${v:-$@}
|
||
expected-stdout:
|
||
= qs <spacedivdedargument
|
||
here>
|
||
~ qs <spacedivdedargument
|
||
here>
|
||
=nqs <spacedivdedargument
|
||
here>
|
||
~nqs <space>
|
||
<divded>
|
||
<argument
|
||
here>
|
||
= qk <space divded argument
|
||
here>
|
||
~ qk <space>
|
||
<divded>
|
||
<argument
|
||
here>
|
||
=nqk <space divded argument
|
||
here>
|
||
~nqk <space>
|
||
<divded>
|
||
<argument
|
||
here>
|
||
---
|
||
name: IFS-subst-4-5
|
||
description:
|
||
extended testsuite based on problem by mikeserv
|
||
stdin:
|
||
pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; }
|
||
a='space divded argument
|
||
here'
|
||
IFS=\ ; set -- $a; IFS=,
|
||
qs="$*"
|
||
print -nr -- '= qs '; pfn "$qs"
|
||
print -nr -- '~ qs '; pfn "$*"
|
||
nqs=$*
|
||
print -nr -- '=nqs '; pfn "$nqs"
|
||
print -nr -- '~nqs '; pfn $*
|
||
qk="$@"
|
||
print -nr -- '= qk '; pfn "$qk"
|
||
print -nr -- '~ qk '; pfn "$@"
|
||
nqk=$@
|
||
print -nr -- '=nqk '; pfn "$nqk"
|
||
print -nr -- '~nqk '; pfn $@
|
||
expected-stdout:
|
||
= qs <space,divded,argument
|
||
here>
|
||
~ qs <space,divded,argument
|
||
here>
|
||
=nqs <space,divded,argument
|
||
here>
|
||
~nqs <space>
|
||
<divded>
|
||
<argument
|
||
here>
|
||
= qk <space divded argument
|
||
here>
|
||
~ qk <space>
|
||
<divded>
|
||
<argument
|
||
here>
|
||
=nqk <space divded argument
|
||
here>
|
||
~nqk <space>
|
||
<divded>
|
||
<argument
|
||
here>
|
||
---
|
||
name: IFS-subst-4-5p
|
||
description:
|
||
extended testsuite based on problem by mikeserv
|
||
stdin:
|
||
pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; }
|
||
a='space divded argument
|
||
here'
|
||
IFS=\ ; set -- $a; IFS=,
|
||
unset v
|
||
qs=${v:-"$*"}
|
||
print -nr -- '= qs '; pfn "$qs"
|
||
print -nr -- '~ qs '; pfn ${v:-"$*"}
|
||
nqs=${v:-$*}
|
||
print -nr -- '=nqs '; pfn "$nqs"
|
||
print -nr -- '~nqs '; pfn ${v:-$*}
|
||
qk=${v:-"$@"}
|
||
print -nr -- '= qk '; pfn "$qk"
|
||
print -nr -- '~ qk '; pfn ${v:-"$@"}
|
||
nqk=${v:-$@}
|
||
print -nr -- '=nqk '; pfn "$nqk"
|
||
print -nr -- '~nqk '; pfn ${v:-$@}
|
||
expected-stdout:
|
||
= qs <space,divded,argument
|
||
here>
|
||
~ qs <space,divded,argument
|
||
here>
|
||
=nqs <space,divded,argument
|
||
here>
|
||
~nqs <space>
|
||
<divded>
|
||
<argument
|
||
here>
|
||
= qk <space divded argument
|
||
here>
|
||
~ qk <space>
|
||
<divded>
|
||
<argument
|
||
here>
|
||
=nqk <space divded argument
|
||
here>
|
||
~nqk <space>
|
||
<divded>
|
||
<argument
|
||
here>
|
||
---
|
||
name: IFS-subst-5
|
||
description:
|
||
extended testsuite based on IFS-subst-3
|
||
differs slightly from ksh93:
|
||
- omit trailing field in a3zna, a7ina (unquoted $@ expansion)
|
||
- has extra middle fields in b5ins, b7ina (IFS_NWS unquoted expansion)
|
||
differs slightly from bash:
|
||
- omit leading field in a5ins, a7ina (IFS_NWS unquoted expansion)
|
||
differs slightly from zsh:
|
||
- differs in assignment, not expansion; probably zsh bug
|
||
- has extra middle fields in b5ins, b7ina (IFS_NWS unquoted expansion)
|
||
'emulate sh' zsh has extra fields in
|
||
- a5ins (IFS_NWS unquoted $*)
|
||
- b5ins, matching mksh’s
|
||
!!WARNING!! more to come: http://austingroupbugs.net/view.php?id=888
|
||
stdin:
|
||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||
IFS=; set -- "" 2 ""; pfb $*; x=$*; pfn "$x"'
|
||
echo '=a1zns'
|
||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||
IFS=; set -- "" 2 ""; pfb "$*"; x="$*"; pfn "$x"'
|
||
echo '=a2zqs'
|
||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||
IFS=; set -- "" 2 ""; pfb $@; x=$@; pfn "$x"'
|
||
echo '=a3zna'
|
||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||
IFS=; set -- "" 2 ""; pfb "$@"; x="$@"; pfn "$x"'
|
||
echo '=a4zqa'
|
||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||
IFS=,; set -- "" 2 ""; pfb $*; x=$*; pfn "$x"'
|
||
echo '=a5ins'
|
||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||
IFS=,; set -- "" 2 ""; pfb "$*"; x="$*"; pfn "$x"'
|
||
echo '=a6iqs'
|
||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||
IFS=,; set -- "" 2 ""; pfb $@; x=$@; pfn "$x"'
|
||
echo '=a7ina'
|
||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||
IFS=,; set -- "" 2 ""; pfb "$@"; x="$@"; pfn "$x"'
|
||
echo '=a8iqa'
|
||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||
IFS=; set -- A B "" "" C; pfb $*; x=$*; pfn "$x"'
|
||
echo '=b1zns'
|
||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||
IFS=; set -- A B "" "" C; pfb "$*"; x="$*"; pfn "$x"'
|
||
echo '=b2zqs'
|
||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||
IFS=; set -- A B "" "" C; pfb $@; x=$@; pfn "$x"'
|
||
echo '=b3zna'
|
||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||
IFS=; set -- A B "" "" C; pfb "$@"; x="$@"; pfn "$x"'
|
||
echo '=b4zqa'
|
||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||
IFS=,; set -- A B "" "" C; pfb $*; x=$*; pfn "$x"'
|
||
echo '=b5ins'
|
||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||
IFS=,; set -- A B "" "" C; pfb "$*"; x="$*"; pfn "$x"'
|
||
echo '=b6iqs'
|
||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||
IFS=,; set -- A B "" "" C; pfb $@; x=$@; pfn "$x"'
|
||
echo '=b7ina'
|
||
"$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
|
||
IFS=,; set -- A B "" "" C; pfb "$@"; x="$@"; pfn "$x"'
|
||
echo '=b8iqa'
|
||
expected-stdout:
|
||
[2]
|
||
<2>
|
||
=a1zns
|
||
[2]
|
||
<2>
|
||
=a2zqs
|
||
[2]
|
||
< 2 >
|
||
=a3zna
|
||
[]
|
||
[2]
|
||
[]
|
||
< 2 >
|
||
=a4zqa
|
||
[2]
|
||
<,2,>
|
||
=a5ins
|
||
[,2,]
|
||
<,2,>
|
||
=a6iqs
|
||
[2]
|
||
< 2 >
|
||
=a7ina
|
||
[]
|
||
[2]
|
||
[]
|
||
< 2 >
|
||
=a8iqa
|
||
[A]
|
||
[B]
|
||
[C]
|
||
<ABC>
|
||
=b1zns
|
||
[ABC]
|
||
<ABC>
|
||
=b2zqs
|
||
[A]
|
||
[B]
|
||
[C]
|
||
<A B C>
|
||
=b3zna
|
||
[A]
|
||
[B]
|
||
[]
|
||
[]
|
||
[C]
|
||
<A B C>
|
||
=b4zqa
|
||
[A]
|
||
[B]
|
||
[]
|
||
[]
|
||
[C]
|
||
<A,B,,,C>
|
||
=b5ins
|
||
[A,B,,,C]
|
||
<A,B,,,C>
|
||
=b6iqs
|
||
[A]
|
||
[B]
|
||
[]
|
||
[]
|
||
[C]
|
||
<A B C>
|
||
=b7ina
|
||
[A]
|
||
[B]
|
||
[]
|
||
[]
|
||
[C]
|
||
<A B C>
|
||
=b8iqa
|
||
---
|
||
name: IFS-subst-6
|
||
description:
|
||
Regression wrt. vector expansion in trim
|
||
stdin:
|
||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||
IFS=
|
||
x=abc
|
||
set -- a b
|
||
showargs ${x#$*}
|
||
expected-stdout:
|
||
<c> .
|
||
---
|
||
name: IFS-subst-7
|
||
description:
|
||
ksh93 bug wrt. vector expansion in trim
|
||
stdin:
|
||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||
IFS="*"
|
||
a=abcd
|
||
set -- '' c
|
||
showargs "$*" ${a##"$*"}
|
||
expected-stdout:
|
||
<*c> <abcd> .
|
||
---
|
||
name: IFS-subst-8
|
||
description:
|
||
http://austingroupbugs.net/view.php?id=221
|
||
stdin:
|
||
n() { echo "$#"; }; n "${foo-$@}"
|
||
expected-stdout:
|
||
1
|
||
---
|
||
name: IFS-subst-9
|
||
description:
|
||
Scalar context for $*/$@ in [[ and case
|
||
stdin:
|
||
"$__progname" -c 'IFS=; set a b; [[ $* = "$1$2" ]]; echo 1 $?' sh a b
|
||
"$__progname" -c 'IFS=; [[ $* = ab ]]; echo 2 "$?"' sh a b
|
||
"$__progname" -c 'IFS=; [[ "$*" = ab ]]; echo 3 "$?"' sh a b
|
||
"$__progname" -c 'IFS=; [[ $* = a ]]; echo 4 "$?"' sh a b
|
||
"$__progname" -c 'IFS=; [[ "$*" = a ]]; echo 5 "$?"' sh a b
|
||
"$__progname" -c 'IFS=; [[ "$@" = a ]]; echo 6 "$?"' sh a b
|
||
"$__progname" -c 'IFS=; case "$@" in a) echo 7 a;; ab) echo 7 b;; a\ b) echo 7 ok;; esac' sh a b
|
||
"$__progname" -c 'IFS=; case $* in a) echo 8 a;; ab) echo 8 ok;; esac' sh a b
|
||
"$__progname" -c 'pfsp() { for s_arg in "$@"; do print -nr -- "<$s_arg> "; done; print .; }; IFS=; star=$* at="$@"; pfsp 9 "$star" "$at"' sh a b
|
||
expected-stdout:
|
||
1 0
|
||
2 0
|
||
3 0
|
||
4 1
|
||
5 1
|
||
6 1
|
||
7 ok
|
||
8 ok
|
||
<9> <ab> <a b> .
|
||
---
|
||
name: IFS-subst-10
|
||
description:
|
||
Scalar context in ${var=$subst}
|
||
stdin:
|
||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||
set -- one "two three" four
|
||
unset -v var
|
||
save_IFS=$IFS
|
||
IFS=
|
||
set -- ${var=$*}
|
||
IFS=$save_IFS
|
||
echo "var=$var"
|
||
showargs "$@"
|
||
expected-stdout:
|
||
var=onetwo threefour
|
||
<onetwo threefour> .
|
||
---
|
||
name: IFS-arith-1
|
||
description:
|
||
http://austingroupbugs.net/view.php?id=832
|
||
stdin:
|
||
${ZSH_VERSION+false} || emulate sh
|
||
${BASH_VERSION+set -o posix}
|
||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||
IFS=0
|
||
showargs $((1230456))
|
||
expected-stdout:
|
||
<123> <456> .
|
||
---
|
||
name: integer-base-err-1
|
||
description:
|
||
Can't have 0 base (causes shell to exit)
|
||
expected-exit: e != 0
|
||
stdin:
|
||
typeset -i i
|
||
i=3
|
||
i=0#4
|
||
echo $i
|
||
expected-stderr-pattern:
|
||
/^.*:.*0#4.*\n$/
|
||
---
|
||
name: integer-base-err-2
|
||
description:
|
||
Can't have multiple bases in a 'constant' (causes shell to exit)
|
||
(ksh88 fails this test)
|
||
expected-exit: e != 0
|
||
stdin:
|
||
typeset -i i
|
||
i=3
|
||
i=2#110#11
|
||
echo $i
|
||
expected-stderr-pattern:
|
||
/^.*:.*2#110#11.*\n$/
|
||
---
|
||
name: integer-base-err-3
|
||
description:
|
||
Syntax errors in expressions and effects on bases
|
||
(interactive so errors don't cause exits)
|
||
(ksh88 fails this test - shell exits, even with -i)
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
stdin:
|
||
PS1= # minimise prompt hassles
|
||
typeset -i4 a=10
|
||
typeset -i a=2+
|
||
echo $a
|
||
typeset -i4 a=10
|
||
typeset -i2 a=2+
|
||
echo $a
|
||
expected-stderr-pattern:
|
||
/^([#\$] )?.*:.*2+.*\n.*:.*2+.*\n$/
|
||
expected-stdout:
|
||
4#22
|
||
4#22
|
||
---
|
||
name: integer-base-err-4
|
||
description:
|
||
Are invalid digits (according to base) errors?
|
||
(ksh93 fails this test)
|
||
expected-exit: e != 0
|
||
stdin:
|
||
typeset -i i;
|
||
i=3#4
|
||
expected-stderr-pattern:
|
||
/^([#\$] )?.*:.*3#4.*\n$/
|
||
---
|
||
name: integer-base-1
|
||
description:
|
||
Missing number after base is treated as 0.
|
||
stdin:
|
||
typeset -i i
|
||
i=3
|
||
i=2#
|
||
echo $i
|
||
expected-stdout:
|
||
0
|
||
---
|
||
name: integer-base-2
|
||
description:
|
||
Check 'stickyness' of base in various situations
|
||
stdin:
|
||
typeset -i i=8
|
||
echo $i
|
||
echo ---------- A
|
||
typeset -i4 j=8
|
||
echo $j
|
||
echo ---------- B
|
||
typeset -i k=8
|
||
typeset -i4 k=8
|
||
echo $k
|
||
echo ---------- C
|
||
typeset -i4 l
|
||
l=3#10
|
||
echo $l
|
||
echo ---------- D
|
||
typeset -i m
|
||
m=3#10
|
||
echo $m
|
||
echo ---------- E
|
||
n=2#11
|
||
typeset -i n
|
||
echo $n
|
||
n=10
|
||
echo $n
|
||
echo ---------- F
|
||
typeset -i8 o=12
|
||
typeset -i4 o
|
||
echo $o
|
||
echo ---------- G
|
||
typeset -i p
|
||
let p=8#12
|
||
echo $p
|
||
expected-stdout:
|
||
8
|
||
---------- A
|
||
4#20
|
||
---------- B
|
||
4#20
|
||
---------- C
|
||
4#3
|
||
---------- D
|
||
3#10
|
||
---------- E
|
||
2#11
|
||
2#1010
|
||
---------- F
|
||
4#30
|
||
---------- G
|
||
8#12
|
||
---
|
||
name: integer-base-3
|
||
description:
|
||
More base parsing (hmm doesn't test much..)
|
||
stdin:
|
||
typeset -i aa
|
||
aa=1+12#10+2
|
||
echo $aa
|
||
typeset -i bb
|
||
bb=1+$aa
|
||
echo $bb
|
||
typeset -i bb
|
||
bb=$aa
|
||
echo $bb
|
||
typeset -i cc
|
||
cc=$aa
|
||
echo $cc
|
||
expected-stdout:
|
||
15
|
||
16
|
||
15
|
||
15
|
||
---
|
||
name: integer-base-4
|
||
description:
|
||
Check that things not declared as integers are not made integers,
|
||
also, check if base is not reset by -i with no arguments.
|
||
(ksh93 fails - prints 10#20 - go figure)
|
||
stdin:
|
||
xx=20
|
||
let xx=10
|
||
typeset -i | grep '^xx='
|
||
typeset -i4 a=10
|
||
typeset -i a=20
|
||
echo $a
|
||
expected-stdout:
|
||
4#110
|
||
---
|
||
name: integer-base-5
|
||
description:
|
||
More base stuff
|
||
stdin:
|
||
typeset -i4 a=3#10
|
||
echo $a
|
||
echo --
|
||
typeset -i j=3
|
||
j='~3'
|
||
echo $j
|
||
echo --
|
||
typeset -i k=1
|
||
x[k=k+1]=3
|
||
echo $k
|
||
echo --
|
||
typeset -i l
|
||
for l in 1 2+3 4; do echo $l; done
|
||
expected-stdout:
|
||
4#3
|
||
--
|
||
-4
|
||
--
|
||
2
|
||
--
|
||
1
|
||
5
|
||
4
|
||
---
|
||
name: integer-base-6
|
||
description:
|
||
Even more base stuff
|
||
(ksh93 fails this test - prints 0)
|
||
stdin:
|
||
typeset -i7 i
|
||
i=
|
||
echo $i
|
||
expected-stdout:
|
||
7#0
|
||
---
|
||
name: integer-base-7
|
||
description:
|
||
Check that non-integer parameters don't get bases assigned
|
||
stdin:
|
||
echo $(( zz = 8#100 ))
|
||
echo $zz
|
||
expected-stdout:
|
||
64
|
||
64
|
||
---
|
||
name: integer-base-8
|
||
description:
|
||
Check that base-36 works (full span)
|
||
stdin:
|
||
echo 1:$((36#109AZ)).
|
||
typeset -i36 x=1691675
|
||
echo 2:$x.
|
||
typeset -Uui36 x
|
||
echo 3:$x.
|
||
expected-stdout:
|
||
1:1691675.
|
||
2:36#109az.
|
||
3:36#109AZ.
|
||
---
|
||
name: integer-base-check-flat
|
||
description:
|
||
Check behaviour does not match POSuX (except if set -o posix),
|
||
because a not type-safe scripting language has *no* business
|
||
interpreting the string "010" as octal number eight (dangerous).
|
||
stdin:
|
||
echo 1 "$("$__progname" -c 'echo :$((10))/$((010)),$((0x10)):')" .
|
||
echo 2 "$("$__progname" -o posix -c 'echo :$((10))/$((010)),$((0x10)):')" .
|
||
echo 3 "$("$__progname" -o sh -c 'echo :$((10))/$((010)),$((0x10)):')" .
|
||
expected-stdout:
|
||
1 :10/10,16: .
|
||
2 :10/8,16: .
|
||
3 :10/10,16: .
|
||
---
|
||
name: integer-base-check-numeric-from-1
|
||
description:
|
||
Check behaviour for base one
|
||
category: !shell:ebcdic-yes
|
||
stdin:
|
||
echo 1:$((1#1))0.
|
||
expected-stdout:
|
||
1:490.
|
||
---
|
||
name: integer-base-check-numeric-from-1-ebcdic
|
||
description:
|
||
Check behaviour for base one
|
||
category: !shell:ebcdic-no
|
||
stdin:
|
||
echo 1:$((1#1))0.
|
||
expected-stdout:
|
||
1:2410.
|
||
---
|
||
name: integer-base-check-numeric-from-2
|
||
description:
|
||
Check behaviour for base two to 36, and that 37 degrades to 10
|
||
stdin:
|
||
i=1
|
||
while (( ++i <= 37 )); do
|
||
eval 'echo '$i':$(('$i'#10)).'
|
||
done
|
||
echo 37:$($__progname -c 'echo $((37#10))').$?:
|
||
expected-stdout:
|
||
2:2.
|
||
3:3.
|
||
4:4.
|
||
5:5.
|
||
6:6.
|
||
7:7.
|
||
8:8.
|
||
9:9.
|
||
10:10.
|
||
11:11.
|
||
12:12.
|
||
13:13.
|
||
14:14.
|
||
15:15.
|
||
16:16.
|
||
17:17.
|
||
18:18.
|
||
19:19.
|
||
20:20.
|
||
21:21.
|
||
22:22.
|
||
23:23.
|
||
24:24.
|
||
25:25.
|
||
26:26.
|
||
27:27.
|
||
28:28.
|
||
29:29.
|
||
30:30.
|
||
31:31.
|
||
32:32.
|
||
33:33.
|
||
34:34.
|
||
35:35.
|
||
36:36.
|
||
37:10.
|
||
37:10.0:
|
||
---
|
||
name: integer-base-check-numeric-to-1
|
||
description:
|
||
Check behaviour for base one
|
||
category: !shell:ebcdic-yes
|
||
stdin:
|
||
i=1
|
||
typeset -Uui$i x=0x40
|
||
eval "typeset -i10 y=$x"
|
||
print $i:$x.$y.
|
||
expected-stdout:
|
||
1:1#@.64.
|
||
---
|
||
name: integer-base-check-numeric-to-1-ebcdic
|
||
description:
|
||
Check behaviour for base one
|
||
category: !shell:ebcdic-no
|
||
stdin:
|
||
i=1
|
||
typeset -Uui$i x=0x7C
|
||
eval "typeset -i10 y=$x"
|
||
print $i:$x.$y.
|
||
expected-stdout:
|
||
1:1#@.124.
|
||
---
|
||
name: integer-base-check-numeric-to-2
|
||
description:
|
||
Check behaviour for base two to 36, and that 37 degrades to 10
|
||
stdin:
|
||
i=1
|
||
while (( ++i <= 37 )); do
|
||
typeset -Uui$i x=0x40
|
||
eval "typeset -i10 y=$x"
|
||
print $i:$x.$y.
|
||
done
|
||
expected-stdout:
|
||
2:2#1000000.64.
|
||
3:3#2101.64.
|
||
4:4#1000.64.
|
||
5:5#224.64.
|
||
6:6#144.64.
|
||
7:7#121.64.
|
||
8:8#100.64.
|
||
9:9#71.64.
|
||
10:64.64.
|
||
11:11#59.64.
|
||
12:12#54.64.
|
||
13:13#4C.64.
|
||
14:14#48.64.
|
||
15:15#44.64.
|
||
16:16#40.64.
|
||
17:17#3D.64.
|
||
18:18#3A.64.
|
||
19:19#37.64.
|
||
20:20#34.64.
|
||
21:21#31.64.
|
||
22:22#2K.64.
|
||
23:23#2I.64.
|
||
24:24#2G.64.
|
||
25:25#2E.64.
|
||
26:26#2C.64.
|
||
27:27#2A.64.
|
||
28:28#28.64.
|
||
29:29#26.64.
|
||
30:30#24.64.
|
||
31:31#22.64.
|
||
32:32#20.64.
|
||
33:33#1V.64.
|
||
34:34#1U.64.
|
||
35:35#1T.64.
|
||
36:36#1S.64.
|
||
37:64.64.
|
||
---
|
||
name: integer-arithmetic-span
|
||
description:
|
||
Check wraparound and size that is defined in mksh
|
||
category: int:32
|
||
stdin:
|
||
echo s:$((2147483647+1)).$(((2147483647*2)+1)).$(((2147483647*2)+2)).
|
||
echo u:$((#2147483647+1)).$((#(2147483647*2)+1)).$((#(2147483647*2)+2)).
|
||
expected-stdout:
|
||
s:-2147483648.-1.0.
|
||
u:2147483648.4294967295.0.
|
||
---
|
||
name: integer-arithmetic-span-64
|
||
description:
|
||
Check wraparound and size that is defined in mksh
|
||
category: int:64
|
||
stdin:
|
||
echo s:$((9223372036854775807+1)).$(((9223372036854775807*2)+1)).$(((9223372036854775807*2)+2)).
|
||
echo u:$((#9223372036854775807+1)).$((#(9223372036854775807*2)+1)).$((#(9223372036854775807*2)+2)).
|
||
expected-stdout:
|
||
s:-9223372036854775808.-1.0.
|
||
u:9223372036854775808.18446744073709551615.0.
|
||
---
|
||
name: integer-size-FAIL-to-detect
|
||
description:
|
||
Notify the user that their ints are not 32 or 64 bit
|
||
category: int:u
|
||
stdin:
|
||
:
|
||
---
|
||
name: lineno-stdin
|
||
description:
|
||
See if $LINENO is updated and can be modified.
|
||
stdin:
|
||
echo A $LINENO
|
||
echo B $LINENO
|
||
LINENO=20
|
||
echo C $LINENO
|
||
expected-stdout:
|
||
A 1
|
||
B 2
|
||
C 20
|
||
---
|
||
name: lineno-inc
|
||
description:
|
||
See if $LINENO is set for .'d files.
|
||
file-setup: file 644 "dotfile"
|
||
echo dot A $LINENO
|
||
echo dot B $LINENO
|
||
LINENO=20
|
||
echo dot C $LINENO
|
||
stdin:
|
||
echo A $LINENO
|
||
echo B $LINENO
|
||
. ./dotfile
|
||
expected-stdout:
|
||
A 1
|
||
B 2
|
||
dot A 1
|
||
dot B 2
|
||
dot C 20
|
||
---
|
||
name: lineno-func
|
||
description:
|
||
See if $LINENO is set for commands in a function.
|
||
stdin:
|
||
echo A $LINENO
|
||
echo B $LINENO
|
||
bar() {
|
||
echo func A $LINENO
|
||
echo func B $LINENO
|
||
}
|
||
bar
|
||
echo C $LINENO
|
||
expected-stdout:
|
||
A 1
|
||
B 2
|
||
func A 4
|
||
func B 5
|
||
C 8
|
||
---
|
||
name: lineno-unset
|
||
description:
|
||
See if unsetting LINENO makes it non-magic.
|
||
file-setup: file 644 "dotfile"
|
||
echo dot A $LINENO
|
||
echo dot B $LINENO
|
||
stdin:
|
||
unset LINENO
|
||
echo A $LINENO
|
||
echo B $LINENO
|
||
bar() {
|
||
echo func A $LINENO
|
||
echo func B $LINENO
|
||
}
|
||
bar
|
||
. ./dotfile
|
||
echo C $LINENO
|
||
expected-stdout:
|
||
A
|
||
B
|
||
func A
|
||
func B
|
||
dot A
|
||
dot B
|
||
C
|
||
---
|
||
name: lineno-unset-use
|
||
description:
|
||
See if unsetting LINENO makes it non-magic even
|
||
when it is re-used.
|
||
file-setup: file 644 "dotfile"
|
||
echo dot A $LINENO
|
||
echo dot B $LINENO
|
||
stdin:
|
||
unset LINENO
|
||
LINENO=3
|
||
echo A $LINENO
|
||
echo B $LINENO
|
||
bar() {
|
||
echo func A $LINENO
|
||
echo func B $LINENO
|
||
}
|
||
bar
|
||
. ./dotfile
|
||
echo C $LINENO
|
||
expected-stdout:
|
||
A 3
|
||
B 3
|
||
func A 3
|
||
func B 3
|
||
dot A 3
|
||
dot B 3
|
||
C 3
|
||
---
|
||
name: lineno-trap
|
||
description:
|
||
Check if LINENO is tracked in traps
|
||
stdin:
|
||
fail() {
|
||
echo "line <$1>"
|
||
exit 1
|
||
}
|
||
trap 'fail $LINENO' INT ERR
|
||
false
|
||
expected-stdout:
|
||
line <6>
|
||
expected-exit: 1
|
||
---
|
||
name: lineno-eval-alias
|
||
description:
|
||
Check if LINENO is trapped in eval and aliases
|
||
stdin:
|
||
${ZSH_VERSION+false} || emulate sh; echo $LINENO
|
||
echo $LINENO
|
||
eval ' echo $LINENO
|
||
echo $LINENO
|
||
echo $LINENO'
|
||
echo $LINENO
|
||
expected-stdout:
|
||
1
|
||
2
|
||
3
|
||
3
|
||
3
|
||
6
|
||
---
|
||
name: unknown-trap
|
||
description:
|
||
Ensure unknown traps are not a syntax error
|
||
stdin:
|
||
(
|
||
trap "echo trap 1 executed" UNKNOWNSIGNAL || echo "foo"
|
||
echo =1
|
||
trap "echo trap 2 executed" UNKNOWNSIGNAL EXIT 999999 FNORD
|
||
echo = $?
|
||
) 2>&1 | sed "s^${__progname%.exe}\.*e*x*e*: <stdin>\[[0-9]*]PROG"
|
||
expected-stdout:
|
||
PROG: trap: bad signal 'UNKNOWNSIGNAL'
|
||
foo
|
||
=1
|
||
PROG: trap: bad signal 'UNKNOWNSIGNAL'
|
||
PROG: trap: bad signal '999999'
|
||
PROG: trap: bad signal 'FNORD'
|
||
= 1
|
||
trap 2 executed
|
||
---
|
||
name: read-IFS-1
|
||
description:
|
||
Simple test, default IFS
|
||
stdin:
|
||
echo "A B " > IN
|
||
unset x y z
|
||
read x y z < IN
|
||
echo 1: "x[$x] y[$y] z[$z]"
|
||
echo 1a: ${z-z not set}
|
||
read x < IN
|
||
echo 2: "x[$x]"
|
||
expected-stdout:
|
||
1: x[A] y[B] z[]
|
||
1a:
|
||
2: x[A B]
|
||
---
|
||
name: read-IFS-2
|
||
description:
|
||
Complex tests, IFS either colon (IFS-NWS) or backslash (tricky)
|
||
stdin:
|
||
n=0
|
||
showargs() { print -nr "$1"; shift; for s_arg in "$@"; do print -nr -- " [$s_arg]"; done; print; }
|
||
(IFS=\\ a=\<\\\>; showargs 3 $a)
|
||
(IFS=: b=\<:\>; showargs 4 $b)
|
||
print -r '<\>' | (IFS=\\ read f g; showargs 5 "$f" "$g")
|
||
print -r '<\\>' | (IFS=\\ read f g; showargs 6 "$f" "$g")
|
||
print '<\\\n>' | (IFS=\\ read f g; showargs 7 "$f" "$g")
|
||
print -r '<\>' | (IFS=\\ read f; showargs 8 "$f")
|
||
print -r '<\\>' | (IFS=\\ read f; showargs 9 "$f")
|
||
print '<\\\n>' | (IFS=\\ read f; showargs 10 "$f")
|
||
print -r '<\>' | (IFS=\\ read -r f g; showargs 11 "$f" "$g")
|
||
print -r '<\\>' | (IFS=\\ read -r f g; showargs 12 "$f" "$g")
|
||
print '<\\\n>' | (IFS=\\ read -r f g; showargs 13 "$f" "$g")
|
||
print -r '<\>' | (IFS=\\ read -r f; showargs 14 "$f")
|
||
print -r '<\\>' | (IFS=\\ read -r f; showargs 15 "$f")
|
||
print '<\\\n>' | (IFS=\\ read -r f; showargs 16 "$f")
|
||
print -r '<:>' | (IFS=: read f g; showargs 17 "$f" "$g")
|
||
print -r '<::>' | (IFS=: read f g; showargs 18 "$f" "$g")
|
||
print '<:\n>' | (IFS=: read f g; showargs 19 "$f" "$g")
|
||
print -r '<:>' | (IFS=: read f; showargs 20 "$f")
|
||
print -r '<::>' | (IFS=: read f; showargs 21 "$f")
|
||
print '<:\n>' | (IFS=: read f; showargs 22 "$f")
|
||
print -r '<:>' | (IFS=: read -r f g; showargs 23 "$f" "$g")
|
||
print -r '<::>' | (IFS=: read -r f g; showargs 24 "$f" "$g")
|
||
print '<:\n>' | (IFS=: read -r f g; showargs 25 "$f" "$g")
|
||
print -r '<:>' | (IFS=: read -r f; showargs 26 "$f")
|
||
print -r '<::>' | (IFS=: read -r f; showargs 27 "$f")
|
||
print '<:\n>' | (IFS=: read -r f; showargs 28 "$f")
|
||
expected-stdout:
|
||
3 [<] [>]
|
||
4 [<] [>]
|
||
5 [<] [>]
|
||
6 [<] [>]
|
||
7 [<>] []
|
||
8 [<>]
|
||
9 [<\>]
|
||
10 [<>]
|
||
11 [<] [>]
|
||
12 [<] [\>]
|
||
13 [<] []
|
||
14 [<\>]
|
||
15 [<\\>]
|
||
16 [<]
|
||
17 [<] [>]
|
||
18 [<] [:>]
|
||
19 [<] []
|
||
20 [<:>]
|
||
21 [<::>]
|
||
22 [<]
|
||
23 [<] [>]
|
||
24 [<] [:>]
|
||
25 [<] []
|
||
26 [<:>]
|
||
27 [<::>]
|
||
28 [<]
|
||
---
|
||
name: read-ksh-1
|
||
description:
|
||
If no var specified, REPLY is used
|
||
stdin:
|
||
echo "abc" > IN
|
||
read < IN
|
||
echo "[$REPLY]";
|
||
expected-stdout:
|
||
[abc]
|
||
---
|
||
name: read-regress-1
|
||
description:
|
||
Check a regression of read
|
||
file-setup: file 644 "foo"
|
||
foo bar
|
||
baz
|
||
blah
|
||
stdin:
|
||
while read a b c; do
|
||
read d
|
||
break
|
||
done <foo
|
||
echo "<$a|$b|$c><$d>"
|
||
expected-stdout:
|
||
<foo|bar|><baz>
|
||
---
|
||
name: read-delim-1
|
||
description:
|
||
Check read with delimiters
|
||
stdin:
|
||
emit() {
|
||
print -n 'foo bar\tbaz\nblah \0blub\tblech\nmyok meck \0'
|
||
}
|
||
emit | while IFS= read -d "" foo; do print -r -- "<$foo>"; done
|
||
emit | while read -d "" foo; do print -r -- "<$foo>"; done
|
||
emit | while read -d "eh?" foo; do print -r -- "<$foo>"; done
|
||
expected-stdout:
|
||
<foo bar baz
|
||
blah >
|
||
<blub blech
|
||
myok meck >
|
||
<foo bar baz
|
||
blah>
|
||
<blub blech
|
||
myok meck>
|
||
<foo bar baz
|
||
blah blub bl>
|
||
<ch
|
||
myok m>
|
||
---
|
||
name: read-ext-1
|
||
description:
|
||
Check read with number of bytes specified, and -A
|
||
stdin:
|
||
print 'foo\nbar' >x1
|
||
print -n x >x2
|
||
print 'foo\\ bar baz' >x3
|
||
x1a=u; read x1a <x1
|
||
x1b=u; read -N-1 x1b <x1
|
||
x2a=u; read x2a <x2; r2a=$?
|
||
x2b=u; read -N2 x2c <x2; r2b=$?
|
||
x2c=u; read -n2 x2c <x2; r2c=$?
|
||
x3a=u; read -A x3a <x3
|
||
print -r "x1a=<$x1a>"
|
||
print -r "x1b=<$x1b>"
|
||
print -r "x2a=$r2a<$x2a>"
|
||
print -r "x2b=$r2b<$x2b>"
|
||
print -r "x2c=$r2c<$x2c>"
|
||
print -r "x3a=<${x3a[0]}|${x3a[1]}|${x3a[2]}>"
|
||
expected-stdout:
|
||
x1a=<foo>
|
||
x1b=<foo
|
||
bar>
|
||
x2a=1<x>
|
||
x2b=1<u>
|
||
x2c=0<x>
|
||
x3a=<foo bar|baz|>
|
||
---
|
||
name: regression-1
|
||
description:
|
||
Lex array code had problems with this.
|
||
stdin:
|
||
echo foo[
|
||
n=bar
|
||
echo "hi[ $n ]=1"
|
||
expected-stdout:
|
||
foo[
|
||
hi[ bar ]=1
|
||
---
|
||
name: regression-2
|
||
description:
|
||
When PATH is set before running a command, the new path is
|
||
not used in doing the path search
|
||
$ echo echo hi > /tmp/q ; chmod a+rx /tmp/q
|
||
$ PATH=/tmp q
|
||
q: not found
|
||
$
|
||
in comexec() the two lines
|
||
while (*vp != NULL)
|
||
(void) typeset(*vp++, xxx, 0);
|
||
need to be moved out of the switch to before findcom() is
|
||
called - I don't know what this will break.
|
||
stdin:
|
||
: "${PWD:-`pwd 2> /dev/null`}"
|
||
: "${PWD:?"PWD not set - cannot do test"}"
|
||
mkdir Y
|
||
cat > Y/xxxscript << EOF
|
||
#!/bin/sh
|
||
# Need to restore path so echo can be found (some shells don't have
|
||
# it as a built-in)
|
||
PATH=\$OLDPATH
|
||
echo hi
|
||
exit 0
|
||
EOF
|
||
chmod a+rx Y/xxxscript
|
||
export OLDPATH="$PATH"
|
||
PATH=$PWD/Y xxxscript
|
||
exit $?
|
||
expected-stdout:
|
||
hi
|
||
---
|
||
name: regression-6
|
||
description:
|
||
Parsing of $(..) expressions is non-optimal. It is
|
||
impossible to have any parentheses inside the expression.
|
||
I.e.,
|
||
$ ksh -c 'echo $(echo \( )'
|
||
no closing quote
|
||
$ ksh -c 'echo $(echo "(" )'
|
||
no closing quote
|
||
$
|
||
The solution is to hack the parsing clode in lex.c, the
|
||
question is how to hack it: should any parentheses be
|
||
escaped by a backslash, or should recursive parsing be done
|
||
(so quotes could also be used to hide hem). The former is
|
||
easier, the later better...
|
||
stdin:
|
||
echo $(echo \( )
|
||
echo $(echo "(" )
|
||
expected-stdout:
|
||
(
|
||
(
|
||
---
|
||
name: regression-9
|
||
description:
|
||
Continue in a for loop does not work right:
|
||
for i in a b c ; do
|
||
if [ $i = b ] ; then
|
||
continue
|
||
fi
|
||
echo $i
|
||
done
|
||
Prints a forever...
|
||
stdin:
|
||
first=yes
|
||
for i in a b c ; do
|
||
if [ $i = b ] ; then
|
||
if [ $first = no ] ; then
|
||
echo 'continue in for loop broken'
|
||
break # hope break isn't broken too :-)
|
||
fi
|
||
first=no
|
||
continue
|
||
fi
|
||
done
|
||
echo bye
|
||
expected-stdout:
|
||
bye
|
||
---
|
||
name: regression-10
|
||
description:
|
||
The following:
|
||
set -- `false`
|
||
echo $?
|
||
should print 0 according to POSIX (dash, bash, ksh93, posh)
|
||
but not 0 according to the getopt(1) manual page, ksh88, and
|
||
Bourne sh (such as /bin/sh on Solaris).
|
||
We honour POSIX except when -o sh is set.
|
||
category: shell:legacy-no
|
||
stdin:
|
||
showf() {
|
||
[[ -o posix ]]; FPOSIX=$((1-$?))
|
||
[[ -o sh ]]; FSH=$((1-$?))
|
||
echo -n "FPOSIX=$FPOSIX FSH=$FSH "
|
||
}
|
||
set +o posix +o sh
|
||
showf
|
||
set -- `false`
|
||
echo rv=$?
|
||
set -o sh
|
||
showf
|
||
set -- `false`
|
||
echo rv=$?
|
||
set -o posix
|
||
showf
|
||
set -- `false`
|
||
echo rv=$?
|
||
set -o posix -o sh
|
||
showf
|
||
set -- `false`
|
||
echo rv=$?
|
||
expected-stdout:
|
||
FPOSIX=0 FSH=0 rv=0
|
||
FPOSIX=0 FSH=1 rv=1
|
||
FPOSIX=1 FSH=0 rv=0
|
||
FPOSIX=1 FSH=1 rv=0
|
||
---
|
||
name: regression-10-legacy
|
||
description:
|
||
The following:
|
||
set -- `false`
|
||
echo $?
|
||
should print 0 according to POSIX (dash, bash, ksh93, posh)
|
||
but not 0 according to the getopt(1) manual page, ksh88, and
|
||
Bourne sh (such as /bin/sh on Solaris).
|
||
category: shell:legacy-yes
|
||
stdin:
|
||
showf() {
|
||
[[ -o posix ]]; FPOSIX=$((1-$?))
|
||
[[ -o sh ]]; FSH=$((1-$?))
|
||
echo -n "FPOSIX=$FPOSIX FSH=$FSH "
|
||
}
|
||
set +o posix +o sh
|
||
showf
|
||
set -- `false`
|
||
echo rv=$?
|
||
set -o sh
|
||
showf
|
||
set -- `false`
|
||
echo rv=$?
|
||
set -o posix
|
||
showf
|
||
set -- `false`
|
||
echo rv=$?
|
||
set -o posix -o sh
|
||
showf
|
||
set -- `false`
|
||
echo rv=$?
|
||
expected-stdout:
|
||
FPOSIX=0 FSH=0 rv=1
|
||
FPOSIX=0 FSH=1 rv=1
|
||
FPOSIX=1 FSH=0 rv=0
|
||
FPOSIX=1 FSH=1 rv=0
|
||
---
|
||
name: regression-11
|
||
description:
|
||
The following:
|
||
x=/foo/bar/blah
|
||
echo ${x##*/}
|
||
should echo blah but on some machines echos /foo/bar/blah.
|
||
stdin:
|
||
x=/foo/bar/blah
|
||
echo ${x##*/}
|
||
expected-stdout:
|
||
blah
|
||
---
|
||
name: regression-12
|
||
description:
|
||
Both of the following echos produce the same output under sh/ksh.att:
|
||
#!/bin/sh
|
||
x="foo bar"
|
||
echo "`echo \"$x\"`"
|
||
echo "`echo "$x"`"
|
||
pdksh produces different output for the former (foo instead of foo\tbar)
|
||
stdin:
|
||
x="foo bar"
|
||
echo "`echo \"$x\"`"
|
||
echo "`echo "$x"`"
|
||
expected-stdout:
|
||
foo bar
|
||
foo bar
|
||
---
|
||
name: regression-13
|
||
description:
|
||
The following command hangs forever:
|
||
$ (: ; cat /etc/termcap) | sleep 2
|
||
This is because the shell forks a shell to run the (..) command
|
||
and this shell has the pipe open. When the sleep dies, the cat
|
||
doesn't get a SIGPIPE 'cause a process (ie, the second shell)
|
||
still has the pipe open.
|
||
|
||
NOTE: this test provokes a bizarre bug in ksh93 (shell starts reading
|
||
commands from /etc/termcap..)
|
||
time-limit: 10
|
||
stdin:
|
||
echo A line of text that will be duplicated quite a number of times.> t1
|
||
cat t1 t1 t1 t1 t1 t1 t1 t1 t1 t1 t1 t1 t1 t1 t1 t1 > t2
|
||
cat t2 t2 t2 t2 t2 t2 t2 t2 t2 t2 t2 t2 t2 t2 t2 t2 > t1
|
||
cat t1 t1 t1 t1 > t2
|
||
(: ; cat t2 2>/dev/null) | sleep 1
|
||
---
|
||
name: regression-14
|
||
description:
|
||
The command
|
||
$ (foobar) 2> /dev/null
|
||
generates no output under /bin/sh, but pdksh produces the error
|
||
foobar: not found
|
||
Also, the command
|
||
$ foobar 2> /dev/null
|
||
generates an error under /bin/sh and pdksh, but AT&T ksh88 produces
|
||
no error (redirected to /dev/null).
|
||
stdin:
|
||
(you/should/not/see/this/error/1) 2> /dev/null
|
||
you/should/not/see/this/error/2 2> /dev/null
|
||
true
|
||
---
|
||
name: regression-15
|
||
description:
|
||
The command
|
||
$ whence foobar
|
||
generates a blank line under pdksh and sets the exit status to 0.
|
||
AT&T ksh88 generates no output and sets the exit status to 1. Also,
|
||
the command
|
||
$ whence foobar cat
|
||
generates no output under AT&T ksh88 (pdksh generates a blank line
|
||
and /bin/cat).
|
||
stdin:
|
||
whence does/not/exist > /dev/null
|
||
echo 1: $?
|
||
echo 2: $(whence does/not/exist | wc -l)
|
||
echo 3: $(whence does/not/exist cat | wc -l)
|
||
expected-stdout:
|
||
1: 1
|
||
2: 0
|
||
3: 0
|
||
---
|
||
name: regression-16
|
||
description:
|
||
${var%%expr} seems to be broken in many places. On the mips
|
||
the commands
|
||
$ read line < /etc/passwd
|
||
$ echo $line
|
||
root:0:1:...
|
||
$ echo ${line%%:*}
|
||
root
|
||
$ echo $line
|
||
root
|
||
$
|
||
change the value of line. On sun4s & pas, the echo ${line%%:*} doesn't
|
||
work. Haven't checked elsewhere...
|
||
script:
|
||
read x
|
||
y=$x
|
||
echo ${x%%:*}
|
||
echo $x
|
||
stdin:
|
||
root:asdjhasdasjhs:0:1:Root:/:/bin/sh
|
||
expected-stdout:
|
||
root
|
||
root:asdjhasdasjhs:0:1:Root:/:/bin/sh
|
||
---
|
||
name: regression-17
|
||
description:
|
||
The command
|
||
. /foo/bar
|
||
should set the exit status to non-zero (sh and AT&T ksh88 do).
|
||
XXX doting a non existent file is a fatal error for a script
|
||
stdin:
|
||
. does/not/exist
|
||
expected-exit: e != 0
|
||
expected-stderr-pattern: /.?/
|
||
---
|
||
name: regression-19
|
||
description:
|
||
Both of the following echos should produce the same thing, but don't:
|
||
$ x=foo/bar
|
||
$ echo ${x%/*}
|
||
foo
|
||
$ echo "${x%/*}"
|
||
foo/bar
|
||
stdin:
|
||
x=foo/bar
|
||
echo "${x%/*}"
|
||
expected-stdout:
|
||
foo
|
||
---
|
||
name: regression-21
|
||
description:
|
||
backslash does not work as expected in case labels:
|
||
$ x='-x'
|
||
$ case $x in
|
||
-\?) echo hi
|
||
esac
|
||
hi
|
||
$ x='-?'
|
||
$ case $x in
|
||
-\\?) echo hi
|
||
esac
|
||
hi
|
||
$
|
||
stdin:
|
||
case -x in
|
||
-\?) echo fail
|
||
esac
|
||
---
|
||
name: regression-22
|
||
description:
|
||
Quoting backquotes inside backquotes doesn't work:
|
||
$ echo `echo hi \`echo there\` folks`
|
||
asks for more info. sh and AT&T ksh88 both echo
|
||
hi there folks
|
||
stdin:
|
||
echo `echo hi \`echo there\` folks`
|
||
expected-stdout:
|
||
hi there folks
|
||
---
|
||
name: regression-23
|
||
description:
|
||
)) is not treated `correctly':
|
||
$ (echo hi ; (echo there ; echo folks))
|
||
missing ((
|
||
$
|
||
instead of (as sh and ksh.att)
|
||
$ (echo hi ; (echo there ; echo folks))
|
||
hi
|
||
there
|
||
folks
|
||
$
|
||
stdin:
|
||
( : ; ( : ; echo hi))
|
||
expected-stdout:
|
||
hi
|
||
---
|
||
name: regression-25
|
||
description:
|
||
Check reading stdin in a while loop. The read should only read
|
||
a single line, not a whole stdio buffer; the cat should get
|
||
the rest.
|
||
stdin:
|
||
(echo a; echo b) | while read x ; do
|
||
echo $x
|
||
cat > /dev/null
|
||
done
|
||
expected-stdout:
|
||
a
|
||
---
|
||
name: regression-26
|
||
description:
|
||
Check reading stdin in a while loop. The read should read both
|
||
lines, not just the first.
|
||
script:
|
||
a=
|
||
while [ "$a" != xxx ] ; do
|
||
last=$x
|
||
read x
|
||
cat /dev/null | sed 's/x/y/'
|
||
a=x$a
|
||
done
|
||
echo $last
|
||
stdin:
|
||
a
|
||
b
|
||
expected-stdout:
|
||
b
|
||
---
|
||
name: regression-27
|
||
description:
|
||
The command
|
||
. /does/not/exist
|
||
should cause a script to exit.
|
||
stdin:
|
||
. does/not/exist
|
||
echo hi
|
||
expected-exit: e != 0
|
||
expected-stderr-pattern: /does\/not\/exist/
|
||
---
|
||
name: regression-28
|
||
description:
|
||
variable assignements not detected well
|
||
stdin:
|
||
a.x=1 echo hi
|
||
expected-exit: e != 0
|
||
expected-stderr-pattern: /a\.x=1/
|
||
---
|
||
name: regression-29
|
||
description:
|
||
alias expansion different from AT&T ksh88
|
||
stdin:
|
||
alias a='for ' b='i in'
|
||
a b hi ; do echo $i ; done
|
||
expected-stdout:
|
||
hi
|
||
---
|
||
name: regression-30
|
||
description:
|
||
strange characters allowed inside ${...}
|
||
stdin:
|
||
echo ${a{b}}
|
||
expected-exit: e != 0
|
||
expected-stderr-pattern: /.?/
|
||
---
|
||
name: regression-31
|
||
description:
|
||
Does read handle partial lines correctly
|
||
script:
|
||
a= ret=
|
||
while [ "$a" != xxx ] ; do
|
||
read x y z
|
||
ret=$?
|
||
a=x$a
|
||
done
|
||
echo "[$x]"
|
||
echo $ret
|
||
stdin: !
|
||
a A aA
|
||
b B Bb
|
||
c
|
||
expected-stdout:
|
||
[c]
|
||
1
|
||
---
|
||
name: regression-32
|
||
description:
|
||
Does read set variables to null at eof?
|
||
script:
|
||
a=
|
||
while [ "$a" != xxx ] ; do
|
||
read x y z
|
||
a=x$a
|
||
done
|
||
echo 1: ${x-x not set} ${y-y not set} ${z-z not set}
|
||
echo 2: ${x:+x not null} ${y:+y not null} ${z:+z not null}
|
||
stdin:
|
||
a A Aa
|
||
b B Bb
|
||
expected-stdout:
|
||
1:
|
||
2:
|
||
---
|
||
name: regression-33
|
||
description:
|
||
Does umask print a leading 0 when umask is 3 digits?
|
||
stdin:
|
||
# on MiNT, the first umask call seems to fail
|
||
umask 022
|
||
# now, the test proper
|
||
umask 222
|
||
umask
|
||
expected-stdout:
|
||
0222
|
||
---
|
||
name: regression-35
|
||
description:
|
||
Tempory files used for here-docs in functions get trashed after
|
||
the function is parsed (before it is executed)
|
||
stdin:
|
||
f1() {
|
||
cat <<- EOF
|
||
F1
|
||
EOF
|
||
f2() {
|
||
cat <<- EOF
|
||
F2
|
||
EOF
|
||
}
|
||
}
|
||
f1
|
||
f2
|
||
unset -f f1
|
||
f2
|
||
expected-stdout:
|
||
F1
|
||
F2
|
||
F2
|
||
---
|
||
name: regression-36
|
||
description:
|
||
Command substitution breaks reading in while loop
|
||
(test from <sjg@void.zen.oz.au>)
|
||
stdin:
|
||
(echo abcdef; echo; echo 123) |
|
||
while read line
|
||
do
|
||
# the following line breaks it
|
||
c=`echo $line | wc -c`
|
||
echo $c
|
||
done
|
||
expected-stdout:
|
||
7
|
||
1
|
||
4
|
||
---
|
||
name: regression-37
|
||
description:
|
||
Machines with broken times() (reported by <sjg@void.zen.oz.au>)
|
||
time does not report correct real time
|
||
stdin:
|
||
time sleep 1
|
||
expected-stderr-pattern: !/^\s*0\.0[\s\d]+real|^\s*real[\s]+0+\.0/
|
||
---
|
||
name: regression-38
|
||
description:
|
||
set -e doesn't ignore exit codes for if/while/until/&&/||/!.
|
||
arguments: !-e!
|
||
stdin:
|
||
if false; then echo hi ; fi
|
||
false || true
|
||
false && true
|
||
while false; do echo hi; done
|
||
echo ok
|
||
expected-stdout:
|
||
ok
|
||
---
|
||
name: regression-39
|
||
description:
|
||
Only posh and oksh(2013-07) say “hi” below; FreeBSD sh,
|
||
GNU bash in POSIX mode, dash, ksh93, mksh don’t. All of
|
||
them exit 0. The POSIX behaviour is needed by BSD make.
|
||
stdin:
|
||
set -e
|
||
echo `false; echo hi` $(<this-file-does-not-exist)
|
||
echo $?
|
||
expected-stdout:
|
||
|
||
0
|
||
expected-stderr-pattern: /this-file-does-not-exist/
|
||
---
|
||
name: regression-40
|
||
description:
|
||
This used to cause a core dump
|
||
env-setup: !RANDOM=12!
|
||
stdin:
|
||
echo hi
|
||
expected-stdout:
|
||
hi
|
||
---
|
||
name: regression-41
|
||
description:
|
||
foo should be set to bar (should not be empty)
|
||
stdin:
|
||
foo=`
|
||
echo bar`
|
||
echo "($foo)"
|
||
expected-stdout:
|
||
(bar)
|
||
---
|
||
name: regression-42
|
||
description:
|
||
Can't use command line assignments to assign readonly parameters.
|
||
stdin:
|
||
print '#!'"$__progname"'\nunset RANDOM\nexport | while IFS= read -r' \
|
||
'RANDOM; do eval '\''print -r -- "$RANDOM=$'\''"$RANDOM"'\'\"\'\; \
|
||
done >env; chmod +x env; PATH=.$PATHSEP$PATH
|
||
foo=bar
|
||
readonly foo
|
||
foo=stuff env | grep '^foo'
|
||
expected-exit: e != 0
|
||
expected-stderr-pattern:
|
||
/read-only/
|
||
---
|
||
name: regression-43
|
||
description:
|
||
Can subshells be prefixed by redirections (historical shells allow
|
||
this)
|
||
stdin:
|
||
< /dev/null (sed 's/^/X/')
|
||
---
|
||
name: regression-45
|
||
description:
|
||
Parameter assignments with [] recognised correctly
|
||
stdin:
|
||
FOO=*[12]
|
||
BAR=abc[
|
||
MORE=[abc]
|
||
JUNK=a[bc
|
||
echo "<$FOO>"
|
||
echo "<$BAR>"
|
||
echo "<$MORE>"
|
||
echo "<$JUNK>"
|
||
expected-stdout:
|
||
<*[12]>
|
||
<abc[>
|
||
<[abc]>
|
||
<a[bc>
|
||
---
|
||
name: regression-46
|
||
description:
|
||
Check that alias expansion works in command substitutions and
|
||
at the end of file.
|
||
stdin:
|
||
alias x='echo hi'
|
||
FOO="`x` "
|
||
echo "[$FOO]"
|
||
x
|
||
expected-stdout:
|
||
[hi ]
|
||
hi
|
||
---
|
||
name: regression-47
|
||
description:
|
||
Check that aliases are fully read.
|
||
stdin:
|
||
alias x='echo hi;
|
||
echo there'
|
||
x
|
||
echo done
|
||
expected-stdout:
|
||
hi
|
||
there
|
||
done
|
||
---
|
||
name: regression-48
|
||
description:
|
||
Check that (here doc) temp files are not left behind after an exec.
|
||
stdin:
|
||
mkdir foo || exit 1
|
||
TMPDIR=$PWD/foo "$__progname" <<- 'EOF'
|
||
x() {
|
||
sed 's/^/X /' << E_O_F
|
||
hi
|
||
there
|
||
folks
|
||
E_O_F
|
||
echo "done ($?)"
|
||
}
|
||
echo=echo; [ -x /bin/echo ] && echo=/bin/echo
|
||
exec $echo subtest-1 hi
|
||
EOF
|
||
echo subtest-1 foo/*
|
||
TMPDIR=$PWD/foo "$__progname" <<- 'EOF'
|
||
echo=echo; [ -x /bin/echo ] && echo=/bin/echo
|
||
sed 's/^/X /' << E_O_F; exec $echo subtest-2 hi
|
||
a
|
||
few
|
||
lines
|
||
E_O_F
|
||
EOF
|
||
echo subtest-2 foo/*
|
||
expected-stdout:
|
||
subtest-1 hi
|
||
subtest-1 foo/*
|
||
X a
|
||
X few
|
||
X lines
|
||
subtest-2 hi
|
||
subtest-2 foo/*
|
||
---
|
||
name: regression-49
|
||
description:
|
||
Check that unset params with attributes are reported by set, those
|
||
sans attributes are not.
|
||
stdin:
|
||
unset FOO BAR
|
||
echo X$FOO
|
||
export BAR
|
||
typeset -i BLAH
|
||
set | grep FOO
|
||
set | grep BAR
|
||
set | grep BLAH
|
||
expected-stdout:
|
||
X
|
||
BAR
|
||
BLAH
|
||
---
|
||
name: regression-50
|
||
description:
|
||
Check that aliases do not use continuation prompt after trailing
|
||
semi-colon.
|
||
file-setup: file 644 "envf"
|
||
PS1=Y
|
||
PS2=X
|
||
env-setup: !ENV=./envf!
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
stdin:
|
||
alias foo='echo hi ; '
|
||
foo
|
||
foo echo there
|
||
expected-stdout:
|
||
hi
|
||
hi
|
||
there
|
||
expected-stderr: !
|
||
YYYY
|
||
---
|
||
name: regression-51
|
||
description:
|
||
Check that set allows both +o and -o options on same command line.
|
||
stdin:
|
||
set a b c
|
||
set -o noglob +o allexport
|
||
echo A: $*, *
|
||
expected-stdout:
|
||
A: a b c, *
|
||
---
|
||
name: regression-52
|
||
description:
|
||
Check that globbing works in pipelined commands
|
||
file-setup: file 644 "envf"
|
||
PS1=P
|
||
file-setup: file 644 "abc"
|
||
stuff
|
||
env-setup: !ENV=./envf!
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
stdin:
|
||
sed 's/^/X /' < ab*
|
||
echo mark 1
|
||
sed 's/^/X /' < ab* | sed 's/^/Y /'
|
||
echo mark 2
|
||
expected-stdout:
|
||
X stuff
|
||
mark 1
|
||
Y X stuff
|
||
mark 2
|
||
expected-stderr: !
|
||
PPPPP
|
||
---
|
||
name: regression-53
|
||
description:
|
||
Check that getopts works in functions
|
||
stdin:
|
||
bfunc() {
|
||
echo bfunc: enter "(args: $*; OPTIND=$OPTIND)"
|
||
while getopts B oc; do
|
||
case $oc in
|
||
(B)
|
||
echo bfunc: B option
|
||
;;
|
||
(*)
|
||
echo bfunc: odd option "($oc)"
|
||
;;
|
||
esac
|
||
done
|
||
echo bfunc: leave
|
||
}
|
||
|
||
function kfunc {
|
||
echo kfunc: enter "(args: $*; OPTIND=$OPTIND)"
|
||
while getopts K oc; do
|
||
case $oc in
|
||
(K)
|
||
echo kfunc: K option
|
||
;;
|
||
(*)
|
||
echo bfunc: odd option "($oc)"
|
||
;;
|
||
esac
|
||
done
|
||
echo kfunc: leave
|
||
}
|
||
|
||
set -- -f -b -k -l
|
||
echo "line 1: OPTIND=$OPTIND"
|
||
getopts kbfl optc
|
||
echo "line 2: ret=$?, optc=$optc, OPTIND=$OPTIND"
|
||
bfunc -BBB blah
|
||
echo "line 3: OPTIND=$OPTIND"
|
||
getopts kbfl optc
|
||
echo "line 4: ret=$?, optc=$optc, OPTIND=$OPTIND"
|
||
kfunc -KKK blah
|
||
echo "line 5: OPTIND=$OPTIND"
|
||
getopts kbfl optc
|
||
echo "line 6: ret=$?, optc=$optc, OPTIND=$OPTIND"
|
||
echo
|
||
|
||
OPTIND=1
|
||
set -- -fbkl
|
||
echo "line 10: OPTIND=$OPTIND"
|
||
getopts kbfl optc
|
||
echo "line 20: ret=$?, optc=$optc, OPTIND=$OPTIND"
|
||
bfunc -BBB blah
|
||
echo "line 30: OPTIND=$OPTIND"
|
||
getopts kbfl optc
|
||
echo "line 40: ret=$?, optc=$optc, OPTIND=$OPTIND"
|
||
kfunc -KKK blah
|
||
echo "line 50: OPTIND=$OPTIND"
|
||
getopts kbfl optc
|
||
echo "line 60: ret=$?, optc=$optc, OPTIND=$OPTIND"
|
||
expected-stdout:
|
||
line 1: OPTIND=1
|
||
line 2: ret=0, optc=f, OPTIND=2
|
||
bfunc: enter (args: -BBB blah; OPTIND=2)
|
||
bfunc: B option
|
||
bfunc: B option
|
||
bfunc: leave
|
||
line 3: OPTIND=2
|
||
line 4: ret=0, optc=b, OPTIND=3
|
||
kfunc: enter (args: -KKK blah; OPTIND=1)
|
||
kfunc: K option
|
||
kfunc: K option
|
||
kfunc: K option
|
||
kfunc: leave
|
||
line 5: OPTIND=3
|
||
line 6: ret=0, optc=k, OPTIND=4
|
||
|
||
line 10: OPTIND=1
|
||
line 20: ret=0, optc=f, OPTIND=2
|
||
bfunc: enter (args: -BBB blah; OPTIND=2)
|
||
bfunc: B option
|
||
bfunc: B option
|
||
bfunc: leave
|
||
line 30: OPTIND=2
|
||
line 40: ret=1, optc=?, OPTIND=2
|
||
kfunc: enter (args: -KKK blah; OPTIND=1)
|
||
kfunc: K option
|
||
kfunc: K option
|
||
kfunc: K option
|
||
kfunc: leave
|
||
line 50: OPTIND=2
|
||
line 60: ret=1, optc=?, OPTIND=2
|
||
---
|
||
name: regression-54
|
||
description:
|
||
Check that ; is not required before the then in if (( ... )) then ...
|
||
stdin:
|
||
if (( 1 )) then
|
||
echo ok dparen
|
||
fi
|
||
if [[ -n 1 ]] then
|
||
echo ok dbrackets
|
||
fi
|
||
expected-stdout:
|
||
ok dparen
|
||
ok dbrackets
|
||
---
|
||
name: regression-55
|
||
description:
|
||
Check ${foo:%bar} is allowed (ksh88 allows it...)
|
||
stdin:
|
||
x=fooXbarXblah
|
||
echo 1 ${x%X*}
|
||
echo 2 ${x:%X*}
|
||
echo 3 ${x%%X*}
|
||
echo 4 ${x:%%X*}
|
||
echo 5 ${x#*X}
|
||
echo 6 ${x:#*X}
|
||
echo 7 ${x##*X}
|
||
echo 8 ${x:##*X}
|
||
expected-stdout:
|
||
1 fooXbar
|
||
2 fooXbar
|
||
3 foo
|
||
4 foo
|
||
5 barXblah
|
||
6 barXblah
|
||
7 blah
|
||
8 blah
|
||
---
|
||
name: regression-57
|
||
description:
|
||
Check if typeset output is correct for
|
||
uninitialised array elements.
|
||
stdin:
|
||
typeset -i xxx[4]
|
||
echo A
|
||
typeset -i | grep xxx | sed 's/^/ /'
|
||
echo B
|
||
typeset | grep xxx | sed 's/^/ /'
|
||
|
||
xxx[1]=2+5
|
||
echo M
|
||
typeset -i | grep xxx | sed 's/^/ /'
|
||
echo N
|
||
typeset | grep xxx | sed 's/^/ /'
|
||
expected-stdout:
|
||
A
|
||
xxx
|
||
B
|
||
typeset -i xxx
|
||
M
|
||
xxx[1]=7
|
||
N
|
||
set -A xxx
|
||
typeset -i xxx[1]
|
||
---
|
||
name: regression-58
|
||
description:
|
||
Check if trap exit is ok (exit not mistaken for signal name)
|
||
stdin:
|
||
trap 'echo hi' exit
|
||
trap exit 1
|
||
expected-stdout:
|
||
hi
|
||
---
|
||
name: regression-59
|
||
description:
|
||
Check if ${#array[*]} is calculated correctly.
|
||
stdin:
|
||
a[12]=hi
|
||
a[8]=there
|
||
echo ${#a[*]}
|
||
expected-stdout:
|
||
2
|
||
---
|
||
name: regression-60
|
||
description:
|
||
Check if default exit status is previous command
|
||
stdin:
|
||
(true; exit)
|
||
echo A $?
|
||
(false; exit)
|
||
echo B $?
|
||
( (exit 103) ; exit)
|
||
echo C $?
|
||
expected-stdout:
|
||
A 0
|
||
B 1
|
||
C 103
|
||
---
|
||
name: regression-61
|
||
description:
|
||
Check if EXIT trap is executed for sub shells.
|
||
stdin:
|
||
trap 'echo parent exit' EXIT
|
||
echo start
|
||
(echo A; echo A last)
|
||
echo B
|
||
(echo C; trap 'echo sub exit' EXIT; echo C last)
|
||
echo parent last
|
||
expected-stdout:
|
||
start
|
||
A
|
||
A last
|
||
B
|
||
C
|
||
C last
|
||
sub exit
|
||
parent last
|
||
parent exit
|
||
---
|
||
name: regression-62
|
||
description:
|
||
Check if test -nt/-ot succeeds if second(first) file is missing.
|
||
stdin:
|
||
:>a
|
||
test a -nt b && echo nt OK || echo nt BAD
|
||
test b -ot a && echo ot OK || echo ot BAD
|
||
expected-stdout:
|
||
nt OK
|
||
ot OK
|
||
---
|
||
name: regression-63
|
||
description:
|
||
Check if typeset, export, and readonly work
|
||
stdin:
|
||
{
|
||
echo FNORD-0
|
||
FNORD_A=1
|
||
FNORD_B=2
|
||
FNORD_C=3
|
||
FNORD_D=4
|
||
FNORD_E=5
|
||
FNORD_F=6
|
||
FNORD_G=7
|
||
FNORD_H=8
|
||
integer FNORD_E FNORD_F FNORD_G FNORD_H
|
||
export FNORD_C FNORD_D FNORD_G FNORD_H
|
||
readonly FNORD_B FNORD_D FNORD_F FNORD_H
|
||
echo FNORD-1
|
||
export
|
||
echo FNORD-2
|
||
export -p
|
||
echo FNORD-3
|
||
readonly
|
||
echo FNORD-4
|
||
readonly -p
|
||
echo FNORD-5
|
||
typeset
|
||
echo FNORD-6
|
||
typeset -p
|
||
echo FNORD-7
|
||
typeset -
|
||
echo FNORD-8
|
||
} | fgrep FNORD
|
||
fnord=(42 23)
|
||
typeset -p fnord
|
||
echo FNORD-9
|
||
expected-stdout:
|
||
FNORD-0
|
||
FNORD-1
|
||
FNORD_C
|
||
FNORD_D
|
||
FNORD_G
|
||
FNORD_H
|
||
FNORD-2
|
||
export FNORD_C=3
|
||
export FNORD_D=4
|
||
export FNORD_G=7
|
||
export FNORD_H=8
|
||
FNORD-3
|
||
FNORD_B
|
||
FNORD_D
|
||
FNORD_F
|
||
FNORD_H
|
||
FNORD-4
|
||
readonly FNORD_B=2
|
||
readonly FNORD_D=4
|
||
readonly FNORD_F=6
|
||
readonly FNORD_H=8
|
||
FNORD-5
|
||
typeset FNORD_A
|
||
typeset -r FNORD_B
|
||
typeset -x FNORD_C
|
||
typeset -x -r FNORD_D
|
||
typeset -i FNORD_E
|
||
typeset -i -r FNORD_F
|
||
typeset -i -x FNORD_G
|
||
typeset -i -x -r FNORD_H
|
||
FNORD-6
|
||
typeset FNORD_A=1
|
||
typeset -r FNORD_B=2
|
||
typeset -x FNORD_C=3
|
||
typeset -x -r FNORD_D=4
|
||
typeset -i FNORD_E=5
|
||
typeset -i -r FNORD_F=6
|
||
typeset -i -x FNORD_G=7
|
||
typeset -i -x -r FNORD_H=8
|
||
FNORD-7
|
||
FNORD_A=1
|
||
FNORD_B=2
|
||
FNORD_C=3
|
||
FNORD_D=4
|
||
FNORD_E=5
|
||
FNORD_F=6
|
||
FNORD_G=7
|
||
FNORD_H=8
|
||
FNORD-8
|
||
set -A fnord
|
||
typeset fnord[0]=42
|
||
typeset fnord[1]=23
|
||
FNORD-9
|
||
---
|
||
name: regression-64
|
||
description:
|
||
Check that we can redefine functions calling time builtin
|
||
stdin:
|
||
t() {
|
||
time >/dev/null
|
||
}
|
||
t 2>/dev/null
|
||
t() {
|
||
time
|
||
}
|
||
---
|
||
name: regression-65
|
||
description:
|
||
check for a regression with sleep builtin and signal mask
|
||
category: !nojsig
|
||
time-limit: 3
|
||
stdin:
|
||
sleep 1
|
||
echo blub |&
|
||
while read -p line; do :; done
|
||
echo ok
|
||
expected-stdout:
|
||
ok
|
||
---
|
||
name: regression-66
|
||
description:
|
||
Check that quoting is sane
|
||
category: !nojsig
|
||
stdin:
|
||
ac_space=' '
|
||
ac_newline='
|
||
'
|
||
set | grep ^ac_ |&
|
||
set -A lines
|
||
while IFS= read -pr line; do
|
||
if [[ $line = *space* ]]; then
|
||
lines[0]=$line
|
||
else
|
||
lines[1]=$line
|
||
fi
|
||
done
|
||
for line in "${lines[@]}"; do
|
||
print -r -- "$line"
|
||
done
|
||
expected-stdout:
|
||
ac_space=' '
|
||
ac_newline=$'\n'
|
||
---
|
||
name: regression-67
|
||
description:
|
||
Check that we can both break and use source on the same line
|
||
stdin:
|
||
for s in s; do break; done; print -s s
|
||
---
|
||
name: regression-68
|
||
description:
|
||
Check that all common arithmetic operators work as expected
|
||
stdin:
|
||
echo 1 $(( a = 5 )) .
|
||
echo 2 $(( ++a )) , $(( a++ )) , $(( a )) .
|
||
echo 3 $(( --a )) , $(( a-- )) , $(( a )) .
|
||
echo 4 $(( a == 5 )) , $(( a == 6 )) .
|
||
echo 5 $(( a != 5 )) , $(( a != 6 )) .
|
||
echo 6 $(( a *= 3 )) .
|
||
echo 7 $(( a /= 5 )) .
|
||
echo 8 $(( a %= 2 )) .
|
||
echo 9 $(( a += 9 )) .
|
||
echo 10 $(( a -= 4 )) .
|
||
echo 11 $(( a <<= 1 )) .
|
||
echo 12 $(( a >>= 1 )) .
|
||
echo 13 $(( a &= 4 )) .
|
||
echo 14 $(( a ^= a )) .
|
||
echo 15 $(( a |= 5 )) .
|
||
echo 16 $(( 5 << 1 )) .
|
||
echo 17 $(( 5 >> 1 )) .
|
||
echo 18 $(( 5 <= 6 )) , $(( 5 <= 5 )) , $(( 5 <= 4 )) .
|
||
echo 19 $(( 5 >= 6 )) , $(( 5 >= 5 )) , $(( 5 >= 4 )) .
|
||
echo 20 $(( 5 < 6 )) , $(( 5 < 5 )) , $(( 5 < 4 )) .
|
||
echo 21 $(( 5 > 6 )) , $(( 5 > 5 )) , $(( 5 > 4 )) .
|
||
echo 22 $(( 0 && 0 )) , $(( 0 && 1 )) , $(( 1 && 0 )) , $(( 1 && 1 )) .
|
||
echo 23 $(( 0 || 0 )) , $(( 0 || 1 )) , $(( 1 || 0 )) , $(( 1 || 1 )) .
|
||
echo 24 $(( 5 * 3 )) .
|
||
echo 25 $(( 7 / 2 )) .
|
||
echo 26 $(( 5 % 5 )) , $(( 5 % 4 )) , $(( 5 % 1 )) , $(( 5 % -1 )) , $(( 5 % -2 )) .
|
||
echo 27 $(( 5 + 2 )) , $(( 5 + 0 )) , $(( 5 + -2 )) .
|
||
echo 28 $(( 5 - 2 )) , $(( 5 - 0 )) , $(( 5 - -2 )) .
|
||
echo 29 $(( 6 & 4 )) , $(( 6 & 8 )) .
|
||
echo 30 $(( 4 ^ 2 )) , $(( 4 ^ 4 )) .
|
||
echo 31 $(( 4 | 2 )) , $(( 4 | 4 )) , $(( 4 | 0 )) .
|
||
echo 32 $(( 0 ? 1 : 2 )) , $(( 3 ? 4 : 5 )) .
|
||
echo 33 $(( 5 , 2 , 3 )) .
|
||
echo 34 $(( ~0 )) , $(( ~1 )) , $(( ~~1 )) , $(( ~~2 )) .
|
||
echo 35 $(( !0 )) , $(( !1 )) , $(( !!1 )) , $(( !!2 )) .
|
||
echo 36 $(( (5) )) .
|
||
expected-stdout:
|
||
1 5 .
|
||
2 6 , 6 , 7 .
|
||
3 6 , 6 , 5 .
|
||
4 1 , 0 .
|
||
5 0 , 1 .
|
||
6 15 .
|
||
7 3 .
|
||
8 1 .
|
||
9 10 .
|
||
10 6 .
|
||
11 12 .
|
||
12 6 .
|
||
13 4 .
|
||
14 0 .
|
||
15 5 .
|
||
16 10 .
|
||
17 2 .
|
||
18 1 , 1 , 0 .
|
||
19 0 , 1 , 1 .
|
||
20 1 , 0 , 0 .
|
||
21 0 , 0 , 1 .
|
||
22 0 , 0 , 0 , 1 .
|
||
23 0 , 1 , 1 , 1 .
|
||
24 15 .
|
||
25 3 .
|
||
26 0 , 1 , 0 , 0 , 1 .
|
||
27 7 , 5 , 3 .
|
||
28 3 , 5 , 7 .
|
||
29 4 , 0 .
|
||
30 6 , 0 .
|
||
31 6 , 4 , 4 .
|
||
32 2 , 4 .
|
||
33 3 .
|
||
34 -1 , -2 , 1 , 2 .
|
||
35 1 , 0 , 1 , 1 .
|
||
36 5 .
|
||
---
|
||
name: regression-69
|
||
description:
|
||
Check that all non-lksh arithmetic operators work as expected
|
||
category: shell:legacy-no
|
||
stdin:
|
||
a=5 b=0x80000005
|
||
echo 1 $(( a ^<= 1 )) , $(( b ^<= 1 )) .
|
||
echo 2 $(( a ^>= 2 )) , $(( b ^>= 2 )) .
|
||
echo 3 $(( 5 ^< 1 )) .
|
||
echo 4 $(( 5 ^> 1 )) .
|
||
expected-stdout:
|
||
1 10 , 11 .
|
||
2 -2147483646 , -1073741822 .
|
||
3 10 .
|
||
4 -2147483646 .
|
||
---
|
||
name: readonly-0
|
||
description:
|
||
Ensure readonly is honoured for assignments and unset
|
||
stdin:
|
||
"$__progname" -c 'u=x; echo $? $u .' || echo aborted, $?
|
||
echo =
|
||
"$__progname" -c 'readonly u; u=x; echo $? $u .' || echo aborted, $?
|
||
echo =
|
||
"$__progname" -c 'u=x; readonly u; unset u; echo $? $u .' || echo aborted, $?
|
||
expected-stdout:
|
||
0 x .
|
||
=
|
||
aborted, 2
|
||
=
|
||
1 x .
|
||
expected-stderr-pattern:
|
||
/read-only/
|
||
---
|
||
name: readonly-1
|
||
description:
|
||
http://austingroupbugs.net/view.php?id=367 for export
|
||
stdin:
|
||
"$__progname" -c 'readonly foo; export foo=a; echo $?' || echo aborted, $?
|
||
expected-stdout:
|
||
aborted, 2
|
||
expected-stderr-pattern:
|
||
/read-only/
|
||
---
|
||
name: readonly-2a
|
||
description:
|
||
Check that getopts works as intended, for readonly-2b to be valid
|
||
stdin:
|
||
"$__progname" -c 'set -- -a b; getopts a c; echo $? $c .; getopts a c; echo $? $c .' || echo aborted, $?
|
||
expected-stdout:
|
||
0 a .
|
||
1 ? .
|
||
---
|
||
name: readonly-2b
|
||
description:
|
||
http://austingroupbugs.net/view.php?id=367 for getopts
|
||
stdin:
|
||
"$__progname" -c 'readonly c; set -- -a b; getopts a c; echo $? $c .' || echo aborted, $?
|
||
expected-stdout:
|
||
2 .
|
||
expected-stderr-pattern:
|
||
/read-only/
|
||
---
|
||
name: readonly-3
|
||
description:
|
||
http://austingroupbugs.net/view.php?id=367 for read
|
||
stdin:
|
||
echo x | "$__progname" -c 'read s; echo $? $s .' || echo aborted, $?
|
||
echo y | "$__progname" -c 'readonly s; read s; echo $? $s .' || echo aborted, $?
|
||
expected-stdout:
|
||
0 x .
|
||
2 .
|
||
expected-stderr-pattern:
|
||
/read-only/
|
||
---
|
||
name: readonly-4
|
||
description:
|
||
Do not permit bypassing readonly for first array item
|
||
stdin:
|
||
set -A arr -- foo bar
|
||
readonly arr
|
||
arr=baz
|
||
print -r -- "${arr[@]}"
|
||
expected-exit: e != 0
|
||
expected-stderr-pattern:
|
||
/read[ -]?only/
|
||
---
|
||
name: readonly-5
|
||
description:
|
||
Ensure readonly is idempotent
|
||
stdin:
|
||
readonly x=1
|
||
readonly x
|
||
---
|
||
name: syntax-1
|
||
description:
|
||
Check that lone ampersand is a syntax error
|
||
stdin:
|
||
&
|
||
expected-exit: e != 0
|
||
expected-stderr-pattern:
|
||
/syntax error/
|
||
---
|
||
name: xxx-quoted-newline-1
|
||
description:
|
||
Check that \<newline> works inside of ${}
|
||
stdin:
|
||
abc=2
|
||
echo ${ab\
|
||
c}
|
||
expected-stdout:
|
||
2
|
||
---
|
||
name: xxx-quoted-newline-2
|
||
description:
|
||
Check that \<newline> works at the start of a here document
|
||
stdin:
|
||
cat << EO\
|
||
F
|
||
hi
|
||
EOF
|
||
expected-stdout:
|
||
hi
|
||
---
|
||
name: xxx-quoted-newline-3
|
||
description:
|
||
Check that \<newline> works at the end of a here document
|
||
stdin:
|
||
cat << EOF
|
||
hi
|
||
EO\
|
||
F
|
||
expected-stdout:
|
||
hi
|
||
---
|
||
name: xxx-multi-assignment-cmd
|
||
description:
|
||
Check that assignments in a command affect subsequent assignments
|
||
in the same command
|
||
stdin:
|
||
FOO=abc
|
||
FOO=123 BAR=$FOO
|
||
echo $BAR
|
||
expected-stdout:
|
||
123
|
||
---
|
||
name: xxx-multi-assignment-posix-cmd
|
||
description:
|
||
Check that the behaviour for multiple assignments with a
|
||
command name matches POSIX. See:
|
||
http://thread.gmane.org/gmane.comp.standards.posix.austin.general/1925
|
||
stdin:
|
||
X=a Y=b; X=$Y Y=$X "$__progname" -c 'echo 1 $X $Y .'; echo 2 $X $Y .
|
||
unset X Y Z
|
||
X=a Y=${X=b} Z=$X "$__progname" -c 'echo 3 $Z .'
|
||
unset X Y Z
|
||
X=a Y=${X=b} Z=$X; echo 4 $Z .
|
||
expected-stdout:
|
||
1 b a .
|
||
2 a b .
|
||
3 b .
|
||
4 a .
|
||
---
|
||
name: xxx-multi-assignment-posix-nocmd
|
||
description:
|
||
Check that the behaviour for multiple assignments with no
|
||
command name matches POSIX (Debian #334182). See:
|
||
http://thread.gmane.org/gmane.comp.standards.posix.austin.general/1925
|
||
stdin:
|
||
X=a Y=b; X=$Y Y=$X; echo 1 $X $Y .
|
||
expected-stdout:
|
||
1 b b .
|
||
---
|
||
name: xxx-multi-assignment-posix-subassign
|
||
description:
|
||
Check that the behaviour for multiple assignments matches POSIX:
|
||
- The assignment words shall be expanded in the current execution
|
||
environment.
|
||
- The assignments happen in the temporary execution environment.
|
||
stdin:
|
||
unset X Y Z
|
||
Z=a Y=${X:=b} sh -c 'echo +$X+ +$Y+ +$Z+'
|
||
echo /$X/
|
||
# Now for the special case:
|
||
unset X Y Z
|
||
X= Y=${X:=b} sh -c 'echo +$X+ +$Y+'
|
||
echo /$X/
|
||
expected-stdout:
|
||
++ +b+ +a+
|
||
/b/
|
||
++ +b+
|
||
/b/
|
||
---
|
||
name: xxx-exec-environment-1
|
||
description:
|
||
Check to see if exec sets it's environment correctly
|
||
stdin:
|
||
print '#!'"$__progname"'\nunset RANDOM\nexport | while IFS= read -r' \
|
||
'RANDOM; do eval '\''print -r -- "$RANDOM=$'\''"$RANDOM"'\'\"\'\; \
|
||
done >env; chmod +x env; PATH=.$PATHSEP$PATH
|
||
FOO=bar exec env
|
||
expected-stdout-pattern:
|
||
/(^|.*\n)FOO=bar\n/
|
||
---
|
||
name: xxx-exec-environment-2
|
||
description:
|
||
Check to make sure exec doesn't change environment if a program
|
||
isn't exec-ed
|
||
stdin:
|
||
print '#!'"$__progname"'\nunset RANDOM\nexport | while IFS= read -r' \
|
||
'RANDOM; do eval '\''print -r -- "$RANDOM=$'\''"$RANDOM"'\'\"\'\; \
|
||
done >env; chmod +x env; PATH=.$PATHSEP$PATH
|
||
env >bar1
|
||
FOO=bar exec; env >bar2
|
||
cmp -s bar1 bar2
|
||
---
|
||
name: exec-function-environment-1
|
||
description:
|
||
Check assignments in function calls and whether they affect
|
||
the current execution environment (ksh93, SUSv4)
|
||
stdin:
|
||
f() { a=2; }; g() { b=3; echo y$c-; }; a=1 f; b=2; c=1 g
|
||
echo x$a-$b- z$c-
|
||
expected-stdout:
|
||
y1-
|
||
x2-3- z1-
|
||
---
|
||
name: exec-modern-korn-shell
|
||
description:
|
||
Check that exec can execute any command that makes it
|
||
through syntax and parser
|
||
stdin:
|
||
print '#!'"$__progname"'\necho tf' >lq
|
||
chmod +x lq
|
||
PATH=$PWD
|
||
exec 2>&1
|
||
foo() { print two; }
|
||
print =1
|
||
(exec print one)
|
||
print =2
|
||
(exec foo)
|
||
print =3
|
||
(exec ls)
|
||
print =4
|
||
(exec lq)
|
||
expected-stdout-pattern:
|
||
/=1\none\n=2\ntwo\n=3\n.*: ls: not found\n=4\ntf\n/
|
||
---
|
||
name: exec-ksh88
|
||
description:
|
||
Check that exec only executes after a PATH search
|
||
arguments: !-o!posix!
|
||
stdin:
|
||
print '#!'"$__progname"'\necho tf' >lq
|
||
chmod +x lq
|
||
PATH=$PWD
|
||
exec 2>&1
|
||
foo() { print two; }
|
||
print =1
|
||
(exec print one)
|
||
print =2
|
||
(exec foo)
|
||
print =3
|
||
(exec ls)
|
||
print =4
|
||
(exec lq)
|
||
expected-stdout-pattern:
|
||
/=1\n.*: print: not found\n=2\n.*: foo: not found\n=3\n.*: ls: not found\n=4\ntf\n/
|
||
---
|
||
name: xxx-what-do-you-call-this-1
|
||
stdin:
|
||
echo "${foo:-"a"}*"
|
||
expected-stdout:
|
||
a*
|
||
---
|
||
name: xxx-prefix-strip-1
|
||
stdin:
|
||
foo='a cdef'
|
||
echo ${foo#a c}
|
||
expected-stdout:
|
||
def
|
||
---
|
||
name: xxx-prefix-strip-2
|
||
stdin:
|
||
set a c
|
||
x='a cdef'
|
||
echo ${x#$*}
|
||
expected-stdout:
|
||
def
|
||
---
|
||
name: xxx-variable-syntax-1
|
||
stdin:
|
||
echo ${:}
|
||
expected-stderr-pattern:
|
||
/bad substitution/
|
||
expected-exit: 1
|
||
---
|
||
name: xxx-variable-syntax-2
|
||
stdin:
|
||
set 0
|
||
echo ${*:0}
|
||
expected-stderr-pattern:
|
||
/bad substitution/
|
||
expected-exit: 1
|
||
---
|
||
name: xxx-variable-syntax-3
|
||
stdin:
|
||
set -A foo 0
|
||
echo ${foo[*]:0}
|
||
expected-stderr-pattern:
|
||
/bad substitution/
|
||
expected-exit: 1
|
||
---
|
||
name: xxx-variable-syntax-4
|
||
description:
|
||
Not all kinds of trims are currently impossible, check those who do
|
||
stdin:
|
||
foo() {
|
||
echo "<$*> X${*:+ }X"
|
||
}
|
||
foo a b
|
||
foo "" c
|
||
foo ""
|
||
foo "" ""
|
||
IFS=:
|
||
foo a b
|
||
foo "" c
|
||
foo ""
|
||
foo "" ""
|
||
IFS=
|
||
foo a b
|
||
foo "" c
|
||
foo ""
|
||
foo "" ""
|
||
expected-stdout:
|
||
<a b> X X
|
||
< c> X X
|
||
<> XX
|
||
< > X X
|
||
<a:b> X X
|
||
<:c> X X
|
||
<> XX
|
||
<:> X X
|
||
<ab> X X
|
||
<c> X X
|
||
<> XX
|
||
<> XX
|
||
---
|
||
name: xxx-substitution-eval-order
|
||
description:
|
||
Check order of evaluation of expressions
|
||
stdin:
|
||
i=1 x= y=
|
||
set -A A abc def GHI j G k
|
||
echo ${A[x=(i+=1)]#${A[y=(i+=2)]}}
|
||
echo $x $y
|
||
expected-stdout:
|
||
HI
|
||
2 4
|
||
---
|
||
name: xxx-set-option-1
|
||
description:
|
||
Check option parsing in set
|
||
stdin:
|
||
set -vsA foo -- A 1 3 2
|
||
echo ${foo[*]}
|
||
expected-stderr:
|
||
echo ${foo[*]}
|
||
expected-stdout:
|
||
1 2 3 A
|
||
---
|
||
name: xxx-exec-1
|
||
description:
|
||
Check that exec exits for built-ins
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
stdin:
|
||
exec echo hi
|
||
echo still herre
|
||
expected-stdout:
|
||
hi
|
||
expected-stderr-pattern: /.*/
|
||
---
|
||
name: xxx-while-1
|
||
description:
|
||
Check the return value of while loops
|
||
XXX need to do same for for/select/until loops
|
||
stdin:
|
||
i=x
|
||
while [ $i != xxx ] ; do
|
||
i=x$i
|
||
if [ $i = xxx ] ; then
|
||
false
|
||
continue
|
||
fi
|
||
done
|
||
echo loop1=$?
|
||
|
||
i=x
|
||
while [ $i != xxx ] ; do
|
||
i=x$i
|
||
if [ $i = xxx ] ; then
|
||
false
|
||
break
|
||
fi
|
||
done
|
||
echo loop2=$?
|
||
|
||
i=x
|
||
while [ $i != xxx ] ; do
|
||
i=x$i
|
||
false
|
||
done
|
||
echo loop3=$?
|
||
expected-stdout:
|
||
loop1=0
|
||
loop2=0
|
||
loop3=1
|
||
---
|
||
name: xxx-status-1
|
||
description:
|
||
Check that blank lines don't clear $?
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
stdin:
|
||
(exit 1)
|
||
echo $?
|
||
(exit 1)
|
||
|
||
echo $?
|
||
true
|
||
expected-stdout:
|
||
1
|
||
1
|
||
expected-stderr-pattern: /.*/
|
||
---
|
||
name: xxx-status-2
|
||
description:
|
||
Check that $? is preserved in subshells, includes, traps.
|
||
stdin:
|
||
(exit 1)
|
||
|
||
echo blank: $?
|
||
|
||
(exit 2)
|
||
(echo subshell: $?)
|
||
|
||
echo 'echo include: $?' > foo
|
||
(exit 3)
|
||
. ./foo
|
||
|
||
trap 'echo trap: $?' ERR
|
||
(exit 4)
|
||
echo exit: $?
|
||
expected-stdout:
|
||
blank: 1
|
||
subshell: 2
|
||
include: 3
|
||
trap: 4
|
||
exit: 4
|
||
---
|
||
name: xxx-clean-chars-1
|
||
description:
|
||
Check MAGIC character is stuffed correctly
|
||
stdin:
|
||
echo `echo [<5B>`
|
||
expected-stdout:
|
||
[<5B>
|
||
---
|
||
name: xxx-param-subst-qmark-1
|
||
description:
|
||
Check suppresion of error message with null string. According to
|
||
POSIX, it shouldn't print the error as 'word' isn't ommitted.
|
||
ksh88/93, Solaris /bin/sh and /usr/xpg4/bin/sh all print the error.
|
||
stdin:
|
||
unset foo
|
||
x=
|
||
echo x${foo?$x}
|
||
expected-exit: 1
|
||
expected-stderr-pattern: !/not set/
|
||
---
|
||
name: xxx-param-subst-qmark-namespec
|
||
description:
|
||
Check special names are output correctly
|
||
stdin:
|
||
doit() {
|
||
"$__progname" -c "$@" >o1 2>o2
|
||
rv=$?
|
||
echo RETVAL: $rv
|
||
sed -e "s^${__progname%.exe}\.*e*x*e*: PROG: " -e 's/^/STDOUT: /g' <o1
|
||
sed -e "s^${__progname%.exe}\.*e*x*e*: PROG: " -e 's/^/STDERR: /g' <o2
|
||
}
|
||
doit 'echo ${1x}'
|
||
doit 'echo "${1x}"'
|
||
doit 'echo ${1?}'
|
||
doit 'echo ${19?}'
|
||
doit 'echo ${!:?}'
|
||
doit -u 'echo ${*:?}' foo ""
|
||
expected-stdout:
|
||
RETVAL: 1
|
||
STDERR: PROG: ${1x}: bad substitution
|
||
RETVAL: 1
|
||
STDERR: PROG: ${1x}: bad substitution
|
||
RETVAL: 1
|
||
STDERR: PROG: 1: parameter null or not set
|
||
RETVAL: 1
|
||
STDERR: PROG: 19: parameter null or not set
|
||
RETVAL: 1
|
||
STDERR: PROG: !: parameter null or not set
|
||
RETVAL: 1
|
||
STDERR: foo: ${*:?}: bad substitution
|
||
---
|
||
name: xxx-param-_-1
|
||
# fails due to weirdness of execv stuff
|
||
category: !os:uwin-nt
|
||
description:
|
||
Check c flag is set.
|
||
arguments: !-c!echo "[$-]"!
|
||
expected-stdout-pattern: /^\[.*c.*\]$/
|
||
---
|
||
name: tilde-expand-1
|
||
description:
|
||
Check tilde expansion after equal signs
|
||
env-setup: !HOME=/sweet!
|
||
stdin:
|
||
echo ${A=a=}~ b=~ c=d~ ~
|
||
export e=~ f=d~
|
||
command command export g=~ h=d~
|
||
echo ". $e . $f ."
|
||
echo ". $g . $h ."
|
||
set -o posix
|
||
unset A e f g h
|
||
echo ${A=a=}~ b=~ c=d~ ~
|
||
export e=~ f=d~
|
||
command command export g=~ h=d~
|
||
echo ". $e . $f ."
|
||
echo ". $g . $h ."
|
||
expected-stdout:
|
||
a=/sweet b=/sweet c=d~ /sweet
|
||
. /sweet . d~ .
|
||
. /sweet . d~ .
|
||
a=~ b=~ c=d~ /sweet
|
||
. /sweet . d~ .
|
||
. /sweet . d~ .
|
||
---
|
||
name: tilde-expand-2
|
||
description:
|
||
Check tilde expansion works
|
||
env-setup: !HOME=/sweet!
|
||
stdin:
|
||
:>'c=a'
|
||
typeset c=[ab]
|
||
:>'d=a'
|
||
x=typeset; $x d=[ab]
|
||
echo "<$c>" "<$d>"
|
||
wd=$PWD
|
||
cd /
|
||
plus=$(print -r -- ~+)
|
||
minus=$(print -r -- ~-)
|
||
nix=$(print -r -- ~)
|
||
[[ $plus = / ]]; echo one $? .
|
||
[[ $minus = "$wd" ]]; echo two $? .
|
||
[[ $nix = /sweet ]]; echo nix $? .
|
||
expected-stdout:
|
||
<[ab]> <a>
|
||
one 0 .
|
||
two 0 .
|
||
nix 0 .
|
||
---
|
||
name: tilde-expand-3
|
||
description:
|
||
Check mostly Austin 351 stuff
|
||
stdin:
|
||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||
set "1 b=2" "3 d=4"
|
||
export a=$1 \c=$2
|
||
showargs 1 "$a" "$b" "$c" "$d"
|
||
unset a b c d
|
||
HOME=/tmp
|
||
export \a=~ b=~
|
||
command export c=~
|
||
builtin export d=~
|
||
\\builtin export e=~
|
||
showargs 2 "$a" "$b" "$c" "$d" "$e" ksh
|
||
unset a b c d e
|
||
set -o posix
|
||
export \a=~ b=~
|
||
command export c=~
|
||
builtin export d=~
|
||
\\builtin export e=~
|
||
showargs 3 "$a" "$b" "$c" "$d" "$e" posix
|
||
unset a b c d e
|
||
set +o posix
|
||
export a=$1
|
||
showargs 4 "$a" "$b" ksh
|
||
unset a b
|
||
showargs 5 a=$1 ksh
|
||
export \a=$1
|
||
showargs 6 "$a" "$b" ksh
|
||
unset a b
|
||
set -o posix
|
||
export a=$1
|
||
showargs 7 "$a" "$b" posix
|
||
unset a b
|
||
showargs 8 a=$1 posix
|
||
export \a=$1
|
||
showargs 9 "$a" "$b" posix
|
||
unset a b
|
||
set +o posix
|
||
command echo 10 ksh a=~
|
||
command command export a=~
|
||
showargs 11 "$a"
|
||
unset a
|
||
set -o posix
|
||
command echo 12 posix a=~
|
||
command command export a=~
|
||
showargs 13 "$a"
|
||
unset a
|
||
# unspecified whether /tmp or ~
|
||
var=export; command $var a=~
|
||
showargs 14 "$a"
|
||
echo 'echo "<$foo>"' >bar
|
||
"$__progname" bar
|
||
var=foo
|
||
export $var=1
|
||
"$__progname" bar
|
||
export $var=~
|
||
"$__progname" bar
|
||
# unspecified
|
||
command -- export a=~
|
||
showargs 18 "$a"
|
||
set -A bla
|
||
typeset bla[1]=~:~
|
||
global gbl=~ g2=$1
|
||
local lcl=~ l2=$1
|
||
readonly ro=~ r2=$1
|
||
showargs 19 "${bla[1]}" a=~ "$gbl" "$lcl" "$ro" "$g2" "$l2" "$r2"
|
||
set +o posix
|
||
echo "20 some arbitrary stuff "=~
|
||
set -o posix
|
||
echo "21 some arbitrary stuff "=~
|
||
expected-stdout:
|
||
<1> <1 b=2> <> <3> <4> .
|
||
<2> </tmp> </tmp> </tmp> </tmp> </tmp> <ksh> .
|
||
<3> <~> </tmp> </tmp> <~> </tmp> <posix> .
|
||
<4> <1 b=2> <> <ksh> .
|
||
<5> <a=1> <b=2> <ksh> .
|
||
<6> <1> <2> <ksh> .
|
||
<7> <1 b=2> <> <posix> .
|
||
<8> <a=1> <b=2> <posix> .
|
||
<9> <1> <2> <posix> .
|
||
10 ksh a=/tmp
|
||
<11> </tmp> .
|
||
12 posix a=~
|
||
<13> </tmp> .
|
||
<14> <~> .
|
||
<>
|
||
<1>
|
||
<~>
|
||
<18> <~> .
|
||
<19> </tmp:/tmp> <a=~> </tmp> </tmp> </tmp> <1 b=2> <1 b=2> <1 b=2> .
|
||
20 some arbitrary stuff =/tmp
|
||
21 some arbitrary stuff =~
|
||
---
|
||
name: exit-err-1
|
||
description:
|
||
Check some "exit on error" conditions
|
||
stdin:
|
||
print '#!'"$__progname"'\nexec "$1"' >env
|
||
print '#!'"$__progname"'\nexit 1' >false
|
||
chmod +x env false
|
||
PATH=.$PATHSEP$PATH
|
||
set -ex
|
||
env false && echo something
|
||
echo END
|
||
expected-stdout:
|
||
END
|
||
expected-stderr:
|
||
+ env false
|
||
+ echo END
|
||
---
|
||
name: exit-err-2
|
||
description:
|
||
Check some "exit on error" edge conditions (POSIXly)
|
||
stdin:
|
||
print '#!'"$__progname"'\nexec "$1"' >env
|
||
print '#!'"$__progname"'\nexit 1' >false
|
||
print '#!'"$__progname"'\nexit 0' >true
|
||
chmod +x env false
|
||
PATH=.$PATHSEP$PATH
|
||
set -ex
|
||
if env true; then
|
||
env false && echo something
|
||
fi
|
||
echo END
|
||
expected-stdout:
|
||
END
|
||
expected-stderr:
|
||
+ env true
|
||
+ env false
|
||
+ echo END
|
||
---
|
||
name: exit-err-3
|
||
description:
|
||
pdksh regression which AT&T ksh does right
|
||
TFM says: [set] -e | errexit
|
||
Exit (after executing the ERR trap) ...
|
||
stdin:
|
||
trap 'echo EXIT' EXIT
|
||
trap 'echo ERR' ERR
|
||
set -e
|
||
cd /XXXXX 2>/dev/null
|
||
echo DONE
|
||
exit 0
|
||
expected-stdout:
|
||
ERR
|
||
EXIT
|
||
expected-exit: e != 0
|
||
---
|
||
name: exit-err-4
|
||
description:
|
||
"set -e" test suite (POSIX)
|
||
stdin:
|
||
set -e
|
||
echo pre
|
||
if true ; then
|
||
false && echo foo
|
||
fi
|
||
echo bar
|
||
expected-stdout:
|
||
pre
|
||
bar
|
||
---
|
||
name: exit-err-5
|
||
description:
|
||
"set -e" test suite (POSIX)
|
||
stdin:
|
||
set -e
|
||
foo() {
|
||
while [ "$1" ]; do
|
||
for E in $x; do
|
||
[ "$1" = "$E" ] && { shift ; continue 2 ; }
|
||
done
|
||
x="$x $1"
|
||
shift
|
||
done
|
||
echo $x
|
||
}
|
||
echo pre
|
||
foo a b b c
|
||
echo post
|
||
expected-stdout:
|
||
pre
|
||
a b c
|
||
post
|
||
---
|
||
name: exit-err-6
|
||
description:
|
||
"set -e" test suite (BSD make)
|
||
category: os:mirbsd
|
||
stdin:
|
||
mkdir zd zd/a zd/b
|
||
print 'all:\n\t@echo eins\n\t@exit 42\n' >zd/a/Makefile
|
||
print 'all:\n\t@echo zwei\n' >zd/b/Makefile
|
||
wd=$(pwd)
|
||
set -e
|
||
for entry in a b; do ( set -e; if [[ -d $wd/zd/$entry.i386 ]]; then _newdir_="$entry.i386"; else _newdir_="$entry"; fi; if [[ -z $_THISDIR_ ]]; then _nextdir_="$_newdir_"; else _nextdir_="$_THISDIR_/$_newdir_"; fi; _makefile_spec_=; [[ ! -f $wd/zd/$_newdir_/Makefile.bsd-wrapper ]] || _makefile_spec_="-f Makefile.bsd-wrapper"; subskipdir=; for skipdir in ; do subentry=${skipdir#$entry}; if [[ $subentry != $skipdir ]]; then if [[ -z $subentry ]]; then echo "($_nextdir_ skipped)"; break; fi; subskipdir="$subskipdir ${subentry#/}"; fi; done; if [[ -z $skipdir || -n $subentry ]]; then echo "===> $_nextdir_"; cd $wd/zd/$_newdir_; make SKIPDIR="$subskipdir" $_makefile_spec_ _THISDIR_="$_nextdir_" all; fi; ) done 2>&1 | sed "s!$wd!WD!g"
|
||
expected-stdout:
|
||
===> a
|
||
eins
|
||
*** Error code 42
|
||
|
||
Stop in WD/zd/a (line 2 of Makefile).
|
||
---
|
||
name: exit-err-7
|
||
description:
|
||
"set -e" regression (LP#1104543)
|
||
stdin:
|
||
set -e
|
||
bla() {
|
||
[ -x $PWD/nonexistant ] && $PWD/nonexistant
|
||
}
|
||
echo x
|
||
bla
|
||
echo y$?
|
||
expected-stdout:
|
||
x
|
||
expected-exit: 1
|
||
---
|
||
name: exit-err-8
|
||
description:
|
||
"set -e" regression (Debian #700526)
|
||
stdin:
|
||
set -e
|
||
_db_cmd() { return $1; }
|
||
db_input() { _db_cmd 30; }
|
||
db_go() { _db_cmd 0; }
|
||
db_input || :
|
||
db_go
|
||
exit 0
|
||
---
|
||
name: exit-err-9
|
||
description:
|
||
"set -e" versus bang pipelines
|
||
stdin:
|
||
set -e
|
||
! false | false
|
||
echo 1 ok
|
||
! false && false
|
||
echo 2 wrong
|
||
expected-stdout:
|
||
1 ok
|
||
expected-exit: 1
|
||
---
|
||
name: exit-enoent-1
|
||
description:
|
||
SUSv4 says that the shell should exit with 126/127 in some situations
|
||
stdin:
|
||
i=0
|
||
(echo; echo :) >x
|
||
"$__progname" ./x >/dev/null 2>&1; r=$?; echo $((i++)) $r .
|
||
"$__progname" -c ./x >/dev/null 2>&1; r=$?; echo $((i++)) $r .
|
||
echo exit 42 >x
|
||
"$__progname" ./x >/dev/null 2>&1; r=$?; echo $((i++)) $r .
|
||
"$__progname" -c ./x >/dev/null 2>&1; r=$?; echo $((i++)) $r .
|
||
rm -f x
|
||
"$__progname" ./x >/dev/null 2>&1; r=$?; echo $((i++)) $r .
|
||
"$__progname" -c ./x >/dev/null 2>&1; r=$?; echo $((i++)) $r .
|
||
expected-stdout:
|
||
0 0 .
|
||
1 126 .
|
||
2 42 .
|
||
3 126 .
|
||
4 127 .
|
||
5 127 .
|
||
---
|
||
name: exit-eval-1
|
||
description:
|
||
Check eval vs substitution exit codes (ksh93 alike)
|
||
stdin:
|
||
(exit 12)
|
||
eval $(false)
|
||
echo A $?
|
||
(exit 12)
|
||
eval ' $(false)'
|
||
echo B $?
|
||
(exit 12)
|
||
eval " $(false)"
|
||
echo C $?
|
||
(exit 12)
|
||
eval "eval $(false)"
|
||
echo D $?
|
||
(exit 12)
|
||
eval 'eval '"$(false)"
|
||
echo E $?
|
||
IFS="$IFS:"
|
||
(exit 12)
|
||
eval $(echo :; false)
|
||
echo F $?
|
||
echo -n "G "
|
||
(exit 12)
|
||
eval 'echo $?'
|
||
echo H $?
|
||
expected-stdout:
|
||
A 0
|
||
B 1
|
||
C 0
|
||
D 0
|
||
E 0
|
||
F 0
|
||
G 12
|
||
H 0
|
||
---
|
||
name: exit-trap-1
|
||
description:
|
||
Check that "exit" with no arguments behaves SUSv4 conformant.
|
||
stdin:
|
||
trap 'echo hi; exit' EXIT
|
||
exit 9
|
||
expected-stdout:
|
||
hi
|
||
expected-exit: 9
|
||
---
|
||
name: exit-trap-2
|
||
description:
|
||
Check that ERR and EXIT traps are run just like ksh93 does.
|
||
GNU bash does not run ERtrap in ±e eval-undef but runs it
|
||
twice (bug?) in +e eval-false, so does ksh93 (bug?), which
|
||
also has a bug to continue execution (echoing "and out" and
|
||
returning 0) in +e eval-undef.
|
||
file-setup: file 644 "x"
|
||
v=; unset v
|
||
trap 'echo EXtrap' EXIT
|
||
trap 'echo ERtrap' ERR
|
||
set $1
|
||
echo "and run $2"
|
||
eval $2
|
||
echo and out
|
||
file-setup: file 644 "xt"
|
||
v=; unset v
|
||
trap 'echo EXtrap' EXIT
|
||
trap 'echo ERtrap' ERR
|
||
set $1
|
||
echo 'and run true'
|
||
true
|
||
echo and out
|
||
file-setup: file 644 "xf"
|
||
v=; unset v
|
||
trap 'echo EXtrap' EXIT
|
||
trap 'echo ERtrap' ERR
|
||
set $1
|
||
echo 'and run false'
|
||
false
|
||
echo and out
|
||
file-setup: file 644 "xu"
|
||
v=; unset v
|
||
trap 'echo EXtrap' EXIT
|
||
trap 'echo ERtrap' ERR
|
||
set $1
|
||
echo 'and run ${v?}'
|
||
${v?}
|
||
echo and out
|
||
stdin:
|
||
runtest() {
|
||
rm -f rc
|
||
(
|
||
"$__progname" "$@"
|
||
echo $? >rc
|
||
) 2>&1 | sed \
|
||
-e 's/parameter not set/parameter null or not set/' \
|
||
-e 's/[[]6]//' -e 's/: eval: line 1//' -e 's/: line 6//' \
|
||
-e "s^${__progname%.exe}\.*e*x*e*: <stdin>\[[0-9]*]PROG"
|
||
}
|
||
xe=-e
|
||
echo : $xe
|
||
runtest x $xe true
|
||
echo = eval-true $(<rc) .
|
||
runtest x $xe false
|
||
echo = eval-false $(<rc) .
|
||
runtest x $xe '${v?}'
|
||
echo = eval-undef $(<rc) .
|
||
runtest xt $xe
|
||
echo = noeval-true $(<rc) .
|
||
runtest xf $xe
|
||
echo = noeval-false $(<rc) .
|
||
runtest xu $xe
|
||
echo = noeval-undef $(<rc) .
|
||
xe=+e
|
||
echo : $xe
|
||
runtest x $xe true
|
||
echo = eval-true $(<rc) .
|
||
runtest x $xe false
|
||
echo = eval-false $(<rc) .
|
||
runtest x $xe '${v?}'
|
||
echo = eval-undef $(<rc) .
|
||
runtest xt $xe
|
||
echo = noeval-true $(<rc) .
|
||
runtest xf $xe
|
||
echo = noeval-false $(<rc) .
|
||
runtest xu $xe
|
||
echo = noeval-undef $(<rc) .
|
||
expected-stdout:
|
||
: -e
|
||
and run true
|
||
and out
|
||
EXtrap
|
||
= eval-true 0 .
|
||
and run false
|
||
ERtrap
|
||
EXtrap
|
||
= eval-false 1 .
|
||
and run ${v?}
|
||
x: v: parameter null or not set
|
||
ERtrap
|
||
EXtrap
|
||
= eval-undef 1 .
|
||
and run true
|
||
and out
|
||
EXtrap
|
||
= noeval-true 0 .
|
||
and run false
|
||
ERtrap
|
||
EXtrap
|
||
= noeval-false 1 .
|
||
and run ${v?}
|
||
xu: v: parameter null or not set
|
||
EXtrap
|
||
= noeval-undef 1 .
|
||
: +e
|
||
and run true
|
||
and out
|
||
EXtrap
|
||
= eval-true 0 .
|
||
and run false
|
||
ERtrap
|
||
and out
|
||
EXtrap
|
||
= eval-false 0 .
|
||
and run ${v?}
|
||
x: v: parameter null or not set
|
||
ERtrap
|
||
EXtrap
|
||
= eval-undef 1 .
|
||
and run true
|
||
and out
|
||
EXtrap
|
||
= noeval-true 0 .
|
||
and run false
|
||
ERtrap
|
||
and out
|
||
EXtrap
|
||
= noeval-false 0 .
|
||
and run ${v?}
|
||
xu: v: parameter null or not set
|
||
EXtrap
|
||
= noeval-undef 1 .
|
||
---
|
||
name: exit-trap-interactive
|
||
description:
|
||
Check that interactive shell doesn't exit via EXIT trap on syntax error
|
||
arguments: !-i!
|
||
stdin:
|
||
trap -- EXIT
|
||
echo Syntax error <
|
||
echo 'After error 1'
|
||
trap 'echo Exit trap' EXIT
|
||
echo Syntax error <
|
||
echo 'After error 2'
|
||
trap 'echo Exit trap' EXIT
|
||
exit
|
||
echo 'After exit'
|
||
expected-stdout:
|
||
After error 1
|
||
After error 2
|
||
Exit trap
|
||
expected-stderr-pattern:
|
||
/syntax error: unexpected 'newline'/
|
||
---
|
||
name: test-stlt-1
|
||
description:
|
||
Check that test also can handle string1 < string2 etc.
|
||
stdin:
|
||
test 2005/10/08 '<' 2005/08/21 && echo ja || echo nein
|
||
test 2005/08/21 \< 2005/10/08 && echo ja || echo nein
|
||
test 2005/10/08 '>' 2005/08/21 && echo ja || echo nein
|
||
test 2005/08/21 \> 2005/10/08 && echo ja || echo nein
|
||
expected-stdout:
|
||
nein
|
||
ja
|
||
ja
|
||
nein
|
||
expected-stderr-pattern: !/unexpected op/
|
||
---
|
||
name: test-precedence-1
|
||
description:
|
||
Check a weird precedence case (and POSIX echo)
|
||
stdin:
|
||
test \( -f = -f \)
|
||
rv=$?
|
||
echo $rv
|
||
expected-stdout:
|
||
0
|
||
---
|
||
name: test-option-1
|
||
description:
|
||
Test the test -o operator
|
||
stdin:
|
||
runtest() {
|
||
test -o $1; echo $?
|
||
[ -o $1 ]; echo $?
|
||
[[ -o $1 ]]; echo $?
|
||
}
|
||
if_test() {
|
||
test -o $1 -o -o !$1; echo $?
|
||
[ -o $1 -o -o !$1 ]; echo $?
|
||
[[ -o $1 || -o !$1 ]]; echo $?
|
||
test -o ?$1; echo $?
|
||
}
|
||
echo 0y $(if_test utf8-mode) =
|
||
echo 0n $(if_test utf8-hack) =
|
||
echo 1= $(runtest utf8-hack) =
|
||
echo 2= $(runtest !utf8-hack) =
|
||
echo 3= $(runtest ?utf8-hack) =
|
||
set +U
|
||
echo 1+ $(runtest utf8-mode) =
|
||
echo 2+ $(runtest !utf8-mode) =
|
||
echo 3+ $(runtest ?utf8-mode) =
|
||
set -U
|
||
echo 1- $(runtest utf8-mode) =
|
||
echo 2- $(runtest !utf8-mode) =
|
||
echo 3- $(runtest ?utf8-mode) =
|
||
echo = short flags =
|
||
echo 0y $(if_test -U) =
|
||
echo 0y $(if_test +U) =
|
||
echo 0n $(if_test -_) =
|
||
echo 0n $(if_test -U-) =
|
||
echo 1= $(runtest -_) =
|
||
echo 2= $(runtest !-_) =
|
||
echo 3= $(runtest ?-_) =
|
||
set +U
|
||
echo 1+ $(runtest -U) =
|
||
echo 2+ $(runtest !-U) =
|
||
echo 3+ $(runtest ?-U) =
|
||
echo 1+ $(runtest +U) =
|
||
echo 2+ $(runtest !+U) =
|
||
echo 3+ $(runtest ?+U) =
|
||
set -U
|
||
echo 1- $(runtest -U) =
|
||
echo 2- $(runtest !-U) =
|
||
echo 3- $(runtest ?-U) =
|
||
echo 1- $(runtest +U) =
|
||
echo 2- $(runtest !+U) =
|
||
echo 3- $(runtest ?+U) =
|
||
expected-stdout:
|
||
0y 0 0 0 0 =
|
||
0n 1 1 1 1 =
|
||
1= 1 1 1 =
|
||
2= 1 1 1 =
|
||
3= 1 1 1 =
|
||
1+ 1 1 1 =
|
||
2+ 0 0 0 =
|
||
3+ 0 0 0 =
|
||
1- 0 0 0 =
|
||
2- 1 1 1 =
|
||
3- 0 0 0 =
|
||
= short flags =
|
||
0y 0 0 0 0 =
|
||
0y 0 0 0 0 =
|
||
0n 1 1 1 1 =
|
||
0n 1 1 1 1 =
|
||
1= 1 1 1 =
|
||
2= 1 1 1 =
|
||
3= 1 1 1 =
|
||
1+ 1 1 1 =
|
||
2+ 0 0 0 =
|
||
3+ 0 0 0 =
|
||
1+ 1 1 1 =
|
||
2+ 0 0 0 =
|
||
3+ 0 0 0 =
|
||
1- 0 0 0 =
|
||
2- 1 1 1 =
|
||
3- 0 0 0 =
|
||
1- 0 0 0 =
|
||
2- 1 1 1 =
|
||
3- 0 0 0 =
|
||
---
|
||
name: test-varset-1
|
||
description:
|
||
Test the test -v operator
|
||
stdin:
|
||
[[ -v a ]]
|
||
rv=$?; echo $((++i)) $rv
|
||
a=
|
||
[[ -v a ]]
|
||
rv=$?; echo $((++i)) $rv
|
||
unset a
|
||
[[ -v a ]]
|
||
rv=$?; echo $((++i)) $rv
|
||
a=x
|
||
[[ -v a ]]
|
||
rv=$?; echo $((++i)) $rv
|
||
nameref b=a
|
||
[[ -v b ]]
|
||
rv=$?; echo $((++i)) $rv
|
||
unset a
|
||
[[ -v b ]]
|
||
rv=$?; echo $((++i)) $rv
|
||
x[1]=y
|
||
[[ -v x ]]
|
||
rv=$?; echo $((++i)) $rv
|
||
[[ -v x[0] ]]
|
||
rv=$?; echo $((++i)) $rv
|
||
[[ -v x[1] ]]
|
||
rv=$?; echo $((++i)) $rv
|
||
[[ -v x[2] ]]
|
||
rv=$?; echo $((++i)) $rv
|
||
expected-stdout:
|
||
1 1
|
||
2 0
|
||
3 1
|
||
4 0
|
||
5 0
|
||
6 1
|
||
7 1
|
||
8 1
|
||
9 0
|
||
10 1
|
||
---
|
||
name: test-varset-2
|
||
description:
|
||
test -v works only on scalars
|
||
stdin:
|
||
[[ -v x[*] ]]
|
||
echo ok
|
||
expected-exit: e != 0
|
||
expected-stderr-pattern:
|
||
/unexpected '\*'/
|
||
---
|
||
name: test-stnze-1
|
||
description:
|
||
Check that the short form [ $x ] works
|
||
stdin:
|
||
i=0
|
||
[ -n $x ]
|
||
rv=$?; echo $((++i)) $rv
|
||
[ $x ]
|
||
rv=$?; echo $((++i)) $rv
|
||
[ -n "$x" ]
|
||
rv=$?; echo $((++i)) $rv
|
||
[ "$x" ]
|
||
rv=$?; echo $((++i)) $rv
|
||
x=0
|
||
[ -n $x ]
|
||
rv=$?; echo $((++i)) $rv
|
||
[ $x ]
|
||
rv=$?; echo $((++i)) $rv
|
||
[ -n "$x" ]
|
||
rv=$?; echo $((++i)) $rv
|
||
[ "$x" ]
|
||
rv=$?; echo $((++i)) $rv
|
||
x='1 -a 1 = 2'
|
||
[ -n $x ]
|
||
rv=$?; echo $((++i)) $rv
|
||
[ $x ]
|
||
rv=$?; echo $((++i)) $rv
|
||
[ -n "$x" ]
|
||
rv=$?; echo $((++i)) $rv
|
||
[ "$x" ]
|
||
rv=$?; echo $((++i)) $rv
|
||
expected-stdout:
|
||
1 0
|
||
2 1
|
||
3 1
|
||
4 1
|
||
5 0
|
||
6 0
|
||
7 0
|
||
8 0
|
||
9 1
|
||
10 1
|
||
11 0
|
||
12 0
|
||
---
|
||
name: test-stnze-2
|
||
description:
|
||
Check that the short form [[ $x ]] works (ksh93 extension)
|
||
stdin:
|
||
i=0
|
||
[[ -n $x ]]
|
||
rv=$?; echo $((++i)) $rv
|
||
[[ $x ]]
|
||
rv=$?; echo $((++i)) $rv
|
||
[[ -n "$x" ]]
|
||
rv=$?; echo $((++i)) $rv
|
||
[[ "$x" ]]
|
||
rv=$?; echo $((++i)) $rv
|
||
x=0
|
||
[[ -n $x ]]
|
||
rv=$?; echo $((++i)) $rv
|
||
[[ $x ]]
|
||
rv=$?; echo $((++i)) $rv
|
||
[[ -n "$x" ]]
|
||
rv=$?; echo $((++i)) $rv
|
||
[[ "$x" ]]
|
||
rv=$?; echo $((++i)) $rv
|
||
x='1 -a 1 = 2'
|
||
[[ -n $x ]]
|
||
rv=$?; echo $((++i)) $rv
|
||
[[ $x ]]
|
||
rv=$?; echo $((++i)) $rv
|
||
[[ -n "$x" ]]
|
||
rv=$?; echo $((++i)) $rv
|
||
[[ "$x" ]]
|
||
rv=$?; echo $((++i)) $rv
|
||
expected-stdout:
|
||
1 1
|
||
2 1
|
||
3 1
|
||
4 1
|
||
5 0
|
||
6 0
|
||
7 0
|
||
8 0
|
||
9 0
|
||
10 0
|
||
11 0
|
||
12 0
|
||
---
|
||
name: test-numeq
|
||
description:
|
||
Check numeric -eq works (R40d regression); spotted by Martijn Dekker
|
||
stdin:
|
||
tst() {
|
||
eval "$2"
|
||
case $? in
|
||
(0) echo yepp 0 \#"$*" ;;
|
||
(1) echo nope 1 \#"$*" ;;
|
||
(2) echo terr 2 \#"$*" ;;
|
||
(*) echo wtf\? $? \#"$*" ;;
|
||
esac
|
||
}
|
||
tst 1 'test 2 -eq 2'
|
||
tst 2 'test 2 -eq 2a'
|
||
tst 3 'test 2 -eq 3'
|
||
tst 4 'test 2 -ne 2'
|
||
tst 5 'test 2 -ne 2a'
|
||
tst 6 'test 2 -ne 3'
|
||
tst 7 'test \! 2 -eq 2'
|
||
tst 8 'test \! 2 -eq 2a'
|
||
tst 9 'test \! 2 -eq 3'
|
||
expected-stdout:
|
||
yepp 0 #1 test 2 -eq 2
|
||
terr 2 #2 test 2 -eq 2a
|
||
nope 1 #3 test 2 -eq 3
|
||
nope 1 #4 test 2 -ne 2
|
||
terr 2 #5 test 2 -ne 2a
|
||
yepp 0 #6 test 2 -ne 3
|
||
nope 1 #7 test \! 2 -eq 2
|
||
terr 2 #8 test \! 2 -eq 2a
|
||
yepp 0 #9 test \! 2 -eq 3
|
||
expected-stderr-pattern:
|
||
/bad number/
|
||
---
|
||
name: mkshrc-1
|
||
description:
|
||
Check that ~/.mkshrc works correctly.
|
||
Part 1: verify user environment is not read (internal)
|
||
stdin:
|
||
echo x $FNORD
|
||
expected-stdout:
|
||
x
|
||
---
|
||
name: mkshrc-2a
|
||
description:
|
||
Check that ~/.mkshrc works correctly.
|
||
Part 2: verify mkshrc is not read (non-interactive shells)
|
||
file-setup: file 644 ".mkshrc"
|
||
FNORD=42
|
||
env-setup: !HOME=.!ENV=!
|
||
stdin:
|
||
echo x $FNORD
|
||
expected-stdout:
|
||
x
|
||
---
|
||
name: mkshrc-2b
|
||
description:
|
||
Check that ~/.mkshrc works correctly.
|
||
Part 2: verify mkshrc can be read (interactive shells)
|
||
file-setup: file 644 ".mkshrc"
|
||
FNORD=42
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
env-setup: !HOME=.!ENV=!PS1=!
|
||
stdin:
|
||
echo x $FNORD
|
||
expected-stdout:
|
||
x 42
|
||
expected-stderr-pattern:
|
||
/(# )*/
|
||
---
|
||
name: mkshrc-3
|
||
description:
|
||
Check that ~/.mkshrc works correctly.
|
||
Part 3: verify mkshrc can be turned off
|
||
file-setup: file 644 ".mkshrc"
|
||
FNORD=42
|
||
env-setup: !HOME=.!ENV=nonexistant!
|
||
stdin:
|
||
echo x $FNORD
|
||
expected-stdout:
|
||
x
|
||
---
|
||
name: sh-mode-1
|
||
description:
|
||
Check that sh mode turns braceexpand off
|
||
and that that works correctly
|
||
stdin:
|
||
set -o braceexpand
|
||
set +o sh
|
||
[[ $(set +o) == *@(-o sh)@(| *) ]] && echo sh || echo nosh
|
||
[[ $(set +o) == *@(-o braceexpand)@(| *) ]] && echo brex || echo nobrex
|
||
echo {a,b,c}
|
||
set +o braceexpand
|
||
echo {a,b,c}
|
||
set -o braceexpand
|
||
echo {a,b,c}
|
||
set -o sh
|
||
echo {a,b,c}
|
||
[[ $(set +o) == *@(-o sh)@(| *) ]] && echo sh || echo nosh
|
||
[[ $(set +o) == *@(-o braceexpand)@(| *) ]] && echo brex || echo nobrex
|
||
set -o braceexpand
|
||
echo {a,b,c}
|
||
[[ $(set +o) == *@(-o sh)@(| *) ]] && echo sh || echo nosh
|
||
[[ $(set +o) == *@(-o braceexpand)@(| *) ]] && echo brex || echo nobrex
|
||
expected-stdout:
|
||
nosh
|
||
brex
|
||
a b c
|
||
{a,b,c}
|
||
a b c
|
||
{a,b,c}
|
||
sh
|
||
nobrex
|
||
a b c
|
||
sh
|
||
brex
|
||
---
|
||
name: sh-mode-2a
|
||
description:
|
||
Check that posix or sh mode is *not* automatically turned on
|
||
category: !binsh
|
||
stdin:
|
||
ln -s "$__progname" ksh || cp "$__progname" ksh
|
||
ln -s "$__progname" sh || cp "$__progname" sh
|
||
ln -s "$__progname" ./-ksh || cp "$__progname" ./-ksh
|
||
ln -s "$__progname" ./-sh || cp "$__progname" ./-sh
|
||
for shell in {,-}{,k}sh; do
|
||
print -- $shell $(./$shell +l -c \
|
||
'[[ $(set +o) == *"-o "@(sh|posix)@(| *) ]] && echo sh || echo nosh')
|
||
done
|
||
expected-stdout:
|
||
sh nosh
|
||
ksh nosh
|
||
-sh nosh
|
||
-ksh nosh
|
||
---
|
||
name: sh-mode-2b
|
||
description:
|
||
Check that posix or sh mode *is* automatically turned on
|
||
category: binsh
|
||
stdin:
|
||
ln -s "$__progname" ksh || cp "$__progname" ksh
|
||
ln -s "$__progname" sh || cp "$__progname" sh
|
||
ln -s "$__progname" ./-ksh || cp "$__progname" ./-ksh
|
||
ln -s "$__progname" ./-sh || cp "$__progname" ./-sh
|
||
for shell in {,-}{,k}sh; do
|
||
print -- $shell $(./$shell +l -c \
|
||
'[[ $(set +o) == *"-o "@(sh|posix)@(| *) ]] && echo sh || echo nosh')
|
||
done
|
||
expected-stdout:
|
||
sh sh
|
||
ksh nosh
|
||
-sh sh
|
||
-ksh nosh
|
||
---
|
||
name: pipeline-1
|
||
description:
|
||
pdksh bug: last command of a pipeline is executed in a
|
||
subshell - make sure it still is, scripts depend on it
|
||
file-setup: file 644 "abcx"
|
||
file-setup: file 644 "abcy"
|
||
stdin:
|
||
echo *
|
||
echo a | while read d; do
|
||
echo $d
|
||
echo $d*
|
||
echo *
|
||
set -o noglob
|
||
echo $d*
|
||
echo *
|
||
done
|
||
echo *
|
||
expected-stdout:
|
||
abcx abcy
|
||
a
|
||
abcx abcy
|
||
abcx abcy
|
||
a*
|
||
*
|
||
abcx abcy
|
||
---
|
||
name: pipeline-2
|
||
description:
|
||
check that co-processes work with TCOMs, TPIPEs and TPARENs
|
||
category: !nojsig
|
||
stdin:
|
||
"$__progname" -c 'i=100; echo hi |& while read -p line; do echo "$((i++)) $line"; done'
|
||
"$__progname" -c 'i=200; echo hi | cat |& while read -p line; do echo "$((i++)) $line"; done'
|
||
"$__progname" -c 'i=300; (echo hi | cat) |& while read -p line; do echo "$((i++)) $line"; done'
|
||
expected-stdout:
|
||
100 hi
|
||
200 hi
|
||
300 hi
|
||
---
|
||
name: pipeline-3
|
||
description:
|
||
Check that PIPESTATUS does what it's supposed to
|
||
stdin:
|
||
echo 1 $PIPESTATUS .
|
||
echo 2 ${PIPESTATUS[0]} .
|
||
echo 3 ${PIPESTATUS[1]} .
|
||
(echo x; exit 12) | (cat; exit 23) | (cat; exit 42)
|
||
echo 5 $? , $PIPESTATUS , ${PIPESTATUS[0]} , ${PIPESTATUS[1]} , ${PIPESTATUS[2]} , ${PIPESTATUS[3]} .
|
||
echo 6 ${PIPESTATUS[0]} .
|
||
set | fgrep PIPESTATUS
|
||
echo 8 $(set | fgrep PIPESTATUS) .
|
||
expected-stdout:
|
||
1 0 .
|
||
2 0 .
|
||
3 .
|
||
x
|
||
5 42 , 12 , 12 , 23 , 42 , .
|
||
6 0 .
|
||
PIPESTATUS[0]=0
|
||
8 PIPESTATUS[0]=0 PIPESTATUS[1]=0 .
|
||
---
|
||
name: pipeline-4
|
||
description:
|
||
Check that "set -o pipefail" does what it's supposed to
|
||
stdin:
|
||
echo 1 "$("$__progname" -c '(exit 12) | (exit 23) | (exit 42); echo $?')" .
|
||
echo 2 "$("$__progname" -c '! (exit 12) | (exit 23) | (exit 42); echo $?')" .
|
||
echo 3 "$("$__progname" -o pipefail -c '(exit 12) | (exit 23) | (exit 42); echo $?')" .
|
||
echo 4 "$("$__progname" -o pipefail -c '! (exit 12) | (exit 23) | (exit 42); echo $?')" .
|
||
echo 5 "$("$__progname" -c '(exit 23) | (exit 42) | :; echo $?')" .
|
||
echo 6 "$("$__progname" -c '! (exit 23) | (exit 42) | :; echo $?')" .
|
||
echo 7 "$("$__progname" -o pipefail -c '(exit 23) | (exit 42) | :; echo $?')" .
|
||
echo 8 "$("$__progname" -o pipefail -c '! (exit 23) | (exit 42) | :; echo $?')" .
|
||
echo 9 "$("$__progname" -o pipefail -c 'x=$( (exit 23) | (exit 42) | :); echo $?')" .
|
||
expected-stdout:
|
||
1 42 .
|
||
2 0 .
|
||
3 42 .
|
||
4 0 .
|
||
5 0 .
|
||
6 1 .
|
||
7 42 .
|
||
8 0 .
|
||
9 42 .
|
||
---
|
||
name: persist-history-1
|
||
description:
|
||
Check if persistent history saving works
|
||
category: !no-histfile
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
env-setup: !ENV=./Env!HISTFILE=hist.file!
|
||
file-setup: file 644 "Env"
|
||
PS1=X
|
||
stdin:
|
||
cat hist.file
|
||
expected-stdout-pattern:
|
||
/cat hist.file/
|
||
expected-stderr-pattern:
|
||
/^X*$/
|
||
---
|
||
name: typeset-1
|
||
description:
|
||
Check that typeset -g works correctly
|
||
stdin:
|
||
set -A arrfoo 65
|
||
foo() {
|
||
typeset -g -Uui16 arrfoo[*]
|
||
}
|
||
echo before ${arrfoo[0]} .
|
||
foo
|
||
echo after ${arrfoo[0]} .
|
||
set -A arrbar 65
|
||
bar() {
|
||
echo inside before ${arrbar[0]} .
|
||
arrbar[0]=97
|
||
echo inside changed ${arrbar[0]} .
|
||
typeset -g -Uui16 arrbar[*]
|
||
echo inside typeset ${arrbar[0]} .
|
||
arrbar[0]=48
|
||
echo inside changed ${arrbar[0]} .
|
||
}
|
||
echo before ${arrbar[0]} .
|
||
bar
|
||
echo after ${arrbar[0]} .
|
||
expected-stdout:
|
||
before 65 .
|
||
after 16#41 .
|
||
before 65 .
|
||
inside before 65 .
|
||
inside changed 97 .
|
||
inside typeset 16#61 .
|
||
inside changed 16#30 .
|
||
after 16#30 .
|
||
---
|
||
name: typeset-2
|
||
description:
|
||
Check that typeset -p on arrays works correctly
|
||
stdin:
|
||
set -A x -- a b c
|
||
echo =
|
||
typeset -p x
|
||
echo =
|
||
typeset -p x[1]
|
||
expected-stdout:
|
||
=
|
||
set -A x
|
||
typeset x[0]=a
|
||
typeset x[1]=b
|
||
typeset x[2]=c
|
||
=
|
||
typeset x[1]=b
|
||
---
|
||
name: typeset-padding-1
|
||
description:
|
||
Check if left/right justification works as per TFM
|
||
stdin:
|
||
typeset -L10 ln=0hall0
|
||
typeset -R10 rn=0hall0
|
||
typeset -ZL10 lz=0hall0
|
||
typeset -ZR10 rz=0hall0
|
||
typeset -Z10 rx=" hallo "
|
||
echo "<$ln> <$rn> <$lz> <$rz> <$rx>"
|
||
expected-stdout:
|
||
<0hall0 > < 0hall0> <hall0 > <00000hall0> <0000 hallo>
|
||
---
|
||
name: typeset-padding-2
|
||
description:
|
||
Check if base-!10 integers are padded right
|
||
stdin:
|
||
typeset -Uui16 -L9 ln=16#1
|
||
typeset -Uui16 -R9 rn=16#1
|
||
typeset -Uui16 -Z9 zn=16#1
|
||
typeset -L9 ls=16#1
|
||
typeset -R9 rs=16#1
|
||
typeset -Z9 zs=16#1
|
||
echo "<$ln> <$rn> <$zn> <$ls> <$rs> <$zs>"
|
||
expected-stdout:
|
||
<16#1 > < 16#1> <16#000001> <16#1 > < 16#1> <0000016#1>
|
||
---
|
||
name: utf8bom-1
|
||
description:
|
||
Check that the UTF-8 Byte Order Mark is ignored as the first
|
||
multibyte character of the shell input (with -c, from standard
|
||
input, as file, or as eval argument), but nowhere else
|
||
# breaks on Mac OSX (HFS+ non-standard Unicode canonical decomposition)
|
||
category: !os:darwin,!shell:ebcdic-yes
|
||
stdin:
|
||
mkdir foo
|
||
print '#!/bin/sh\necho ohne' >foo/fnord
|
||
print '#!/bin/sh\necho mit' >foo/fnord
|
||
print 'fnord\nfnord\nfnord\nfnord' >foo/bar
|
||
print eval \''fnord\nfnord\nfnord\nfnord'\' >foo/zoo
|
||
set -A anzahl -- foo/*
|
||
echo got ${#anzahl[*]} files
|
||
chmod +x foo/*
|
||
export PATH=$(pwd)/foo$PATHSEP$PATH
|
||
"$__progname" -c 'fnord'
|
||
echo =
|
||
"$__progname" -c 'fnord; fnord; fnord; fnord'
|
||
echo =
|
||
"$__progname" foo/bar
|
||
echo =
|
||
"$__progname" <foo/bar
|
||
echo =
|
||
"$__progname" foo/zoo
|
||
echo =
|
||
"$__progname" -c 'echo : $(fnord)'
|
||
rm -rf foo
|
||
expected-stdout:
|
||
got 4 files
|
||
ohne
|
||
=
|
||
ohne
|
||
ohne
|
||
mit
|
||
ohne
|
||
=
|
||
ohne
|
||
ohne
|
||
mit
|
||
ohne
|
||
=
|
||
ohne
|
||
ohne
|
||
mit
|
||
ohne
|
||
=
|
||
ohne
|
||
ohne
|
||
mit
|
||
ohne
|
||
=
|
||
: ohne
|
||
---
|
||
name: utf8bom-2
|
||
description:
|
||
Check that we can execute BOM-shebangs (failures not fatal)
|
||
XXX if the OS can already execute them, we lose
|
||
note: cygwin execve(2) doesn't return to us with ENOEXEC, we lose
|
||
note: Ultrix perl5 t4 returns 65280 (exit-code 255) and no text
|
||
XXX fails when LD_PRELOAD is set with -e and Perl chokes it (ASan)
|
||
need-pass: no
|
||
category: !os:cygwin,!os:msys,!os:ultrix,!os:uwin-nt,!smksh
|
||
env-setup: !FOO=BAR!
|
||
stdin:
|
||
print '#!'"$__progname"'\nprint "1 a=$ENV{FOO}";' >t1
|
||
print '#!'"$__progname"'\nprint "2 a=$ENV{FOO}";' >t2
|
||
print '#!'"$__perlname"'\nprint "3 a=$ENV{FOO}\n";' >t3
|
||
print '#!'"$__perlname"'\nprint "4 a=$ENV{FOO}\n";' >t4
|
||
chmod +x t?
|
||
./t1
|
||
./t2
|
||
./t3
|
||
./t4
|
||
expected-stdout:
|
||
1 a=/nonexistant{FOO}
|
||
2 a=/nonexistant{FOO}
|
||
3 a=BAR
|
||
4 a=BAR
|
||
expected-stderr-pattern:
|
||
/(Unrecognized character .... ignored at \..t4 line 1)*/
|
||
---
|
||
name: utf8opt-1
|
||
description:
|
||
Check that the utf8-mode flag is not set at non-interactive startup
|
||
env-setup: !PS1=!PS2=!LC_CTYPE=@utflocale@!
|
||
stdin:
|
||
if [[ $- = *U* ]]; then
|
||
echo is set
|
||
else
|
||
echo is not set
|
||
fi
|
||
expected-stdout:
|
||
is not set
|
||
---
|
||
name: utf8opt-2
|
||
description:
|
||
Check that the utf8-mode flag is set at interactive startup.
|
||
If your OS is old, try passing HAVE_SETLOCALE_CTYPE=0 to Build.sh
|
||
need-pass: no
|
||
category: !noutf8
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
env-setup: !PS1=!PS2=!LC_CTYPE=@utflocale@!
|
||
stdin:
|
||
if [[ $- = *U* ]]; then
|
||
echo is set
|
||
else
|
||
echo is not set
|
||
fi
|
||
expected-stdout:
|
||
is set
|
||
expected-stderr-pattern:
|
||
/(# )*/
|
||
---
|
||
name: utf8opt-3a
|
||
description:
|
||
Ensure ±U on the command line is honoured
|
||
(these two tests may pass falsely depending on CPPFLAGS)
|
||
stdin:
|
||
export i=0
|
||
code='if [[ $- = *U* ]]; then echo $i on; else echo $i off; fi'
|
||
let i++; "$__progname" -U -c "$code"
|
||
let i++; "$__progname" +U -c "$code"
|
||
echo $((++i)) done
|
||
expected-stdout:
|
||
1 on
|
||
2 off
|
||
3 done
|
||
---
|
||
name: utf8opt-3b
|
||
description:
|
||
Ensure ±U on the command line is honoured, interactive shells
|
||
need-ctty: yes
|
||
stdin:
|
||
export i=0
|
||
code='if [[ $- = *U* ]]; then echo $i on; else echo $i off; fi'
|
||
let i++; "$__progname" -U -ic "$code"
|
||
let i++; "$__progname" +U -ic "$code"
|
||
echo $((++i)) done
|
||
expected-stdout:
|
||
1 on
|
||
2 off
|
||
3 done
|
||
---
|
||
name: utf8bug-1
|
||
description:
|
||
Ensure trailing combining characters are not lost
|
||
stdin:
|
||
set -U
|
||
a=a
|
||
b=$'\u0301'
|
||
x=$a$b
|
||
print -r -- "<e$x>"
|
||
x=$a
|
||
x+=$b
|
||
print -r -- "<e$x>"
|
||
b=$'\u0301'b
|
||
x=$a
|
||
x+=$b
|
||
print -r -- "<e$x>"
|
||
expected-stdout:
|
||
<eá>
|
||
<eá>
|
||
<eáb>
|
||
---
|
||
name: aliases-1
|
||
description:
|
||
Check if built-in shell aliases are okay
|
||
stdin:
|
||
alias
|
||
typeset -f
|
||
expected-stdout:
|
||
autoload='\\builtin typeset -fu'
|
||
functions='\\builtin typeset -f'
|
||
hash='\\builtin alias -t'
|
||
history='\\builtin fc -l'
|
||
integer='\\builtin typeset -i'
|
||
local='\\builtin typeset'
|
||
login='\\builtin exec login'
|
||
nameref='\\builtin typeset -n'
|
||
nohup='nohup '
|
||
r='\\builtin fc -e -'
|
||
type='\\builtin whence -v'
|
||
---
|
||
name: aliases-2b
|
||
description:
|
||
Check if “set -o sh” does not influence built-in aliases
|
||
arguments: !-o!sh!
|
||
stdin:
|
||
alias
|
||
typeset -f
|
||
expected-stdout:
|
||
autoload='\\builtin typeset -fu'
|
||
functions='\\builtin typeset -f'
|
||
hash='\\builtin alias -t'
|
||
history='\\builtin fc -l'
|
||
integer='\\builtin typeset -i'
|
||
local='\\builtin typeset'
|
||
login='\\builtin exec login'
|
||
nameref='\\builtin typeset -n'
|
||
nohup='nohup '
|
||
r='\\builtin fc -e -'
|
||
type='\\builtin whence -v'
|
||
---
|
||
name: aliases-3b
|
||
description:
|
||
Check if running as sh does not influence built-in aliases
|
||
stdin:
|
||
cp "$__progname" sh
|
||
./sh -c 'alias; typeset -f'
|
||
rm -f sh
|
||
expected-stdout:
|
||
autoload='\\builtin typeset -fu'
|
||
functions='\\builtin typeset -f'
|
||
hash='\\builtin alias -t'
|
||
history='\\builtin fc -l'
|
||
integer='\\builtin typeset -i'
|
||
local='\\builtin typeset'
|
||
login='\\builtin exec login'
|
||
nameref='\\builtin typeset -n'
|
||
nohup='nohup '
|
||
r='\\builtin fc -e -'
|
||
type='\\builtin whence -v'
|
||
---
|
||
name: aliases-cmdline
|
||
description:
|
||
Check that aliases work from the command line (Debian #517009)
|
||
Note that due to the nature of the lexing process, defining
|
||
aliases in COMSUBs then immediately using them, and things
|
||
like 'alias foo=bar && foo', still fail.
|
||
stdin:
|
||
"$__progname" -c $'alias a="echo OK"\na'
|
||
expected-stdout:
|
||
OK
|
||
---
|
||
name: aliases-funcdef-1
|
||
description:
|
||
Check if POSIX functions take precedences over aliases
|
||
stdin:
|
||
alias foo='echo makro'
|
||
foo() {
|
||
echo funktion
|
||
}
|
||
foo
|
||
expected-stdout:
|
||
makro
|
||
---
|
||
name: aliases-funcdef-2
|
||
description:
|
||
Check if POSIX functions take precedences over aliases
|
||
stdin:
|
||
alias foo='echo makro'
|
||
foo () {
|
||
echo funktion
|
||
}
|
||
foo
|
||
expected-stdout:
|
||
makro
|
||
---
|
||
name: aliases-funcdef-3
|
||
description:
|
||
Check if aliases take precedences over Korn functions
|
||
stdin:
|
||
alias foo='echo makro'
|
||
function foo {
|
||
echo funktion
|
||
}
|
||
foo
|
||
expected-stdout:
|
||
makro
|
||
---
|
||
name: aliases-funcdef-4
|
||
description:
|
||
Functions should only take over if actually being defined
|
||
stdin:
|
||
alias local
|
||
:|| local() { :; }
|
||
alias local
|
||
expected-stdout:
|
||
local='\\builtin typeset'
|
||
local='\\builtin typeset'
|
||
---
|
||
name: arrays-1
|
||
description:
|
||
Check if Korn Shell arrays work as expected
|
||
stdin:
|
||
v="c d"
|
||
set -A foo -- a \$v "$v" '$v' b
|
||
echo "${#foo[*]}|${foo[0]}|${foo[1]}|${foo[2]}|${foo[3]}|${foo[4]}|"
|
||
expected-stdout:
|
||
5|a|$v|c d|$v|b|
|
||
---
|
||
name: arrays-2a
|
||
description:
|
||
Check if bash-style arrays work as expected
|
||
stdin:
|
||
v="c d"
|
||
foo=(a \$v "$v" '$v' b)
|
||
echo "${#foo[*]}|${foo[0]}|${foo[1]}|${foo[2]}|${foo[3]}|${foo[4]}|"
|
||
expected-stdout:
|
||
5|a|$v|c d|$v|b|
|
||
---
|
||
name: arrays-2b
|
||
description:
|
||
Check if bash-style arrays work as expected, with newlines
|
||
stdin:
|
||
print '#!'"$__progname"'\nfor x in "$@"; do print -nr -- "$x|"; done' >pfp
|
||
chmod +x pfp
|
||
test -n "$ZSH_VERSION" && setopt KSH_ARRAYS
|
||
v="e f"
|
||
foo=(a
|
||
bc
|
||
d \$v "$v" '$v' g
|
||
)
|
||
./pfp "${#foo[*]}" "${foo[0]}" "${foo[1]}" "${foo[2]}" "${foo[3]}" "${foo[4]}" "${foo[5]}" "${foo[6]}"; echo
|
||
foo=(a\
|
||
bc
|
||
d \$v "$v" '$v' g
|
||
)
|
||
./pfp "${#foo[*]}" "${foo[0]}" "${foo[1]}" "${foo[2]}" "${foo[3]}" "${foo[4]}" "${foo[5]}" "${foo[6]}"; echo
|
||
foo=(a\
|
||
bc\\
|
||
d \$v "$v" '$v'
|
||
g)
|
||
./pfp "${#foo[*]}" "${foo[0]}" "${foo[1]}" "${foo[2]}" "${foo[3]}" "${foo[4]}" "${foo[5]}" "${foo[6]}"; echo
|
||
expected-stdout:
|
||
7|a|bc|d|$v|e f|$v|g|
|
||
7|a|bc|d|$v|e f|$v|g|
|
||
6|abc\|d|$v|e f|$v|g||
|
||
---
|
||
name: arrays-3
|
||
description:
|
||
Check if array bounds are uint32_t
|
||
stdin:
|
||
set -A foo a b c
|
||
foo[4097]=d
|
||
foo[2147483637]=e
|
||
echo ${foo[*]}
|
||
foo[-1]=f
|
||
echo ${foo[4294967295]} g ${foo[*]}
|
||
expected-stdout:
|
||
a b c d e
|
||
f g a b c d e f
|
||
---
|
||
name: arrays-4
|
||
description:
|
||
Check if Korn Shell arrays with specified indices work as expected
|
||
stdin:
|
||
v="c d"
|
||
set -A foo -- [1]=\$v [2]="$v" [4]='$v' [0]=a [5]=b
|
||
echo "${#foo[*]}|${foo[0]}|${foo[1]}|${foo[2]}|${foo[3]}|${foo[4]}|${foo[5]}|"
|
||
# we don't want this at all:
|
||
# 5|a|$v|c d||$v|b|
|
||
set -A arr "[5]=meh"
|
||
echo "<${arr[0]}><${arr[5]}>"
|
||
expected-stdout:
|
||
5|[1]=$v|[2]=c d|[4]=$v|[0]=a|[5]=b||
|
||
<[5]=meh><>
|
||
---
|
||
name: arrays-5
|
||
description:
|
||
Check if bash-style arrays with specified indices work as expected
|
||
(taken out temporarily to fix arrays-4; see also arrays-9a comment)
|
||
category: disabled
|
||
stdin:
|
||
v="c d"
|
||
foo=([1]=\$v [2]="$v" [4]='$v' [0]=a [5]=b)
|
||
echo "${#foo[*]}|${foo[0]}|${foo[1]}|${foo[2]}|${foo[3]}|${foo[4]}|${foo[5]}|"
|
||
x=([128]=foo bar baz)
|
||
echo k= ${!x[*]} .
|
||
echo v= ${x[*]} .
|
||
# Check that we do not break this by globbing
|
||
:>b=blah
|
||
bleh=5
|
||
typeset -a arr
|
||
arr+=([bleh]=blah)
|
||
echo "<${arr[0]}><${arr[5]}>"
|
||
expected-stdout:
|
||
5|a|$v|c d||$v|b|
|
||
k= 128 129 130 .
|
||
v= foo bar baz .
|
||
<><blah>
|
||
---
|
||
name: arrays-6
|
||
description:
|
||
Check if we can get the array keys (indices) for indexed arrays,
|
||
Korn shell style
|
||
stdin:
|
||
of() {
|
||
i=0
|
||
for x in "$@"; do
|
||
echo -n "$((i++))<$x>"
|
||
done
|
||
echo
|
||
}
|
||
foo[1]=eins
|
||
set | grep '^foo'
|
||
echo =
|
||
foo[0]=zwei
|
||
foo[4]=drei
|
||
set | grep '^foo'
|
||
echo =
|
||
echo a $(of ${foo[*]}) = $(of ${bar[*]}) a
|
||
echo b $(of "${foo[*]}") = $(of "${bar[*]}") b
|
||
echo c $(of ${foo[@]}) = $(of ${bar[@]}) c
|
||
echo d $(of "${foo[@]}") = $(of "${bar[@]}") d
|
||
echo e $(of ${!foo[*]}) = $(of ${!bar[*]}) e
|
||
echo f $(of "${!foo[*]}") = $(of "${!bar[*]}") f
|
||
echo g $(of ${!foo[@]}) = $(of ${!bar[@]}) g
|
||
echo h $(of "${!foo[@]}") = $(of "${!bar[@]}") h
|
||
expected-stdout:
|
||
foo[1]=eins
|
||
=
|
||
foo[0]=zwei
|
||
foo[1]=eins
|
||
foo[4]=drei
|
||
=
|
||
a 0<zwei>1<eins>2<drei> = a
|
||
b 0<zwei eins drei> = 0<> b
|
||
c 0<zwei>1<eins>2<drei> = c
|
||
d 0<zwei>1<eins>2<drei> = d
|
||
e 0<0>1<1>2<4> = e
|
||
f 0<0 1 4> = 0<> f
|
||
g 0<0>1<1>2<4> = g
|
||
h 0<0>1<1>2<4> = h
|
||
---
|
||
name: arrays-7
|
||
description:
|
||
Check if we can get the array keys (indices) for indexed arrays,
|
||
Korn shell style, in some corner cases
|
||
stdin:
|
||
echo !arz: ${!arz}
|
||
echo !arz[0]: ${!arz[0]}
|
||
echo !arz[1]: ${!arz[1]}
|
||
arz=foo
|
||
echo !arz: ${!arz}
|
||
echo !arz[0]: ${!arz[0]}
|
||
echo !arz[1]: ${!arz[1]}
|
||
unset arz
|
||
echo !arz: ${!arz}
|
||
echo !arz[0]: ${!arz[0]}
|
||
echo !arz[1]: ${!arz[1]}
|
||
expected-stdout:
|
||
!arz: arz
|
||
!arz[0]: arz[0]
|
||
!arz[1]: arz[1]
|
||
!arz: arz
|
||
!arz[0]: arz[0]
|
||
!arz[1]: arz[1]
|
||
!arz: arz
|
||
!arz[0]: arz[0]
|
||
!arz[1]: arz[1]
|
||
---
|
||
name: arrays-8
|
||
description:
|
||
Check some behavioural rules for arrays.
|
||
stdin:
|
||
fna() {
|
||
set -A aa 9
|
||
}
|
||
fnb() {
|
||
typeset ab
|
||
set -A ab 9
|
||
}
|
||
fnc() {
|
||
typeset ac
|
||
set -A ac 91
|
||
unset ac
|
||
set -A ac 92
|
||
}
|
||
fnd() {
|
||
set +A ad 9
|
||
}
|
||
fne() {
|
||
unset ae
|
||
set +A ae 9
|
||
}
|
||
fnf() {
|
||
unset af[0]
|
||
set +A af 9
|
||
}
|
||
fng() {
|
||
unset ag[*]
|
||
set +A ag 9
|
||
}
|
||
set -A aa 1 2
|
||
set -A ab 1 2
|
||
set -A ac 1 2
|
||
set -A ad 1 2
|
||
set -A ae 1 2
|
||
set -A af 1 2
|
||
set -A ag 1 2
|
||
set -A ah 1 2
|
||
typeset -Z3 aa ab ac ad ae af ag
|
||
print 1a ${aa[*]} .
|
||
print 1b ${ab[*]} .
|
||
print 1c ${ac[*]} .
|
||
print 1d ${ad[*]} .
|
||
print 1e ${ae[*]} .
|
||
print 1f ${af[*]} .
|
||
print 1g ${ag[*]} .
|
||
print 1h ${ah[*]} .
|
||
fna
|
||
fnb
|
||
fnc
|
||
fnd
|
||
fne
|
||
fnf
|
||
fng
|
||
typeset -Z5 ah[*]
|
||
print 2a ${aa[*]} .
|
||
print 2b ${ab[*]} .
|
||
print 2c ${ac[*]} .
|
||
print 2d ${ad[*]} .
|
||
print 2e ${ae[*]} .
|
||
print 2f ${af[*]} .
|
||
print 2g ${ag[*]} .
|
||
print 2h ${ah[*]} .
|
||
expected-stdout:
|
||
1a 001 002 .
|
||
1b 001 002 .
|
||
1c 001 002 .
|
||
1d 001 002 .
|
||
1e 001 002 .
|
||
1f 001 002 .
|
||
1g 001 002 .
|
||
1h 1 2 .
|
||
2a 9 .
|
||
2b 001 002 .
|
||
2c 92 .
|
||
2d 009 002 .
|
||
2e 9 .
|
||
2f 9 002 .
|
||
2g 009 .
|
||
2h 00001 00002 .
|
||
---
|
||
name: arrays-9a
|
||
description:
|
||
Check that we can concatenate arrays
|
||
stdin:
|
||
unset foo; foo=(bar); foo+=(baz); echo 1 ${!foo[*]} : ${foo[*]} .
|
||
unset foo; foo=(foo bar); foo+=(baz); echo 2 ${!foo[*]} : ${foo[*]} .
|
||
# unset foo; foo=([2]=foo [0]=bar); foo+=(baz [5]=quux); echo 3 ${!foo[*]} : ${foo[*]} .
|
||
expected-stdout:
|
||
1 0 1 : bar baz .
|
||
2 0 1 2 : foo bar baz .
|
||
# 3 0 2 3 5 : bar foo baz quux .
|
||
---
|
||
name: arrays-9b
|
||
description:
|
||
Check that we can concatenate parameters too
|
||
stdin:
|
||
unset foo; foo=bar; foo+=baz; echo 1 $foo .
|
||
unset foo; typeset -i16 foo=10; foo+=20; echo 2 $foo .
|
||
expected-stdout:
|
||
1 barbaz .
|
||
2 16#a20 .
|
||
---
|
||
name: arrassign-basic
|
||
description:
|
||
Check basic whitespace conserving properties of wdarrassign
|
||
stdin:
|
||
a=($(echo a b))
|
||
b=($(echo "a b"))
|
||
c=("$(echo "a b")")
|
||
d=("$(echo a b)")
|
||
a+=($(echo c d))
|
||
b+=($(echo "c d"))
|
||
c+=("$(echo "c d")")
|
||
d+=("$(echo c d)")
|
||
echo ".a:${a[0]}.${a[1]}.${a[2]}.${a[3]}:"
|
||
echo ".b:${b[0]}.${b[1]}.${b[2]}.${b[3]}:"
|
||
echo ".c:${c[0]}.${c[1]}.${c[2]}.${c[3]}:"
|
||
echo ".d:${d[0]}.${d[1]}.${d[2]}.${d[3]}:"
|
||
expected-stdout:
|
||
.a:a.b.c.d:
|
||
.b:a.b.c.d:
|
||
.c:a b.c d..:
|
||
.d:a b.c d..:
|
||
---
|
||
name: arrassign-fnc-none
|
||
description:
|
||
Check locality of array access inside a function
|
||
stdin:
|
||
function fn {
|
||
x+=(f)
|
||
echo ".fn:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
|
||
}
|
||
function rfn {
|
||
if [[ -n $BASH_VERSION ]]; then
|
||
y=()
|
||
else
|
||
set -A y
|
||
fi
|
||
y+=(f)
|
||
echo ".rfn:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
|
||
}
|
||
x=(m m)
|
||
y=(m m)
|
||
echo ".f0:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
|
||
fn
|
||
echo ".f1:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
|
||
fn
|
||
echo ".f2:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
|
||
echo ".rf0:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
|
||
rfn
|
||
echo ".rf1:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
|
||
rfn
|
||
echo ".rf2:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
|
||
expected-stdout:
|
||
.f0:m.m..:
|
||
.fn:m.m.f.:
|
||
.f1:m.m.f.:
|
||
.fn:m.m.f.f:
|
||
.f2:m.m.f.f:
|
||
.rf0:m.m..:
|
||
.rfn:f...:
|
||
.rf1:f...:
|
||
.rfn:f...:
|
||
.rf2:f...:
|
||
---
|
||
name: arrassign-fnc-local
|
||
description:
|
||
Check locality of array access inside a function
|
||
with the bash/mksh/ksh93 local/typeset keyword
|
||
(note: ksh93 has no local; typeset works only in FKSH)
|
||
stdin:
|
||
function fn {
|
||
typeset x
|
||
x+=(f)
|
||
echo ".fn:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
|
||
}
|
||
function rfn {
|
||
if [[ -n $BASH_VERSION ]]; then
|
||
y=()
|
||
else
|
||
set -A y
|
||
fi
|
||
typeset y
|
||
y+=(f)
|
||
echo ".rfn:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
|
||
}
|
||
function fnr {
|
||
typeset z
|
||
if [[ -n $BASH_VERSION ]]; then
|
||
z=()
|
||
else
|
||
set -A z
|
||
fi
|
||
z+=(f)
|
||
echo ".fnr:${z[0]}.${z[1]}.${z[2]}.${z[3]}:"
|
||
}
|
||
x=(m m)
|
||
y=(m m)
|
||
z=(m m)
|
||
echo ".f0:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
|
||
fn
|
||
echo ".f1:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
|
||
fn
|
||
echo ".f2:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
|
||
echo ".rf0:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
|
||
rfn
|
||
echo ".rf1:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
|
||
rfn
|
||
echo ".rf2:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
|
||
echo ".f0r:${z[0]}.${z[1]}.${z[2]}.${z[3]}:"
|
||
fnr
|
||
echo ".f1r:${z[0]}.${z[1]}.${z[2]}.${z[3]}:"
|
||
fnr
|
||
echo ".f2r:${z[0]}.${z[1]}.${z[2]}.${z[3]}:"
|
||
expected-stdout:
|
||
.f0:m.m..:
|
||
.fn:f...:
|
||
.f1:m.m..:
|
||
.fn:f...:
|
||
.f2:m.m..:
|
||
.rf0:m.m..:
|
||
.rfn:f...:
|
||
.rf1:...:
|
||
.rfn:f...:
|
||
.rf2:...:
|
||
.f0r:m.m..:
|
||
.fnr:f...:
|
||
.f1r:m.m..:
|
||
.fnr:f...:
|
||
.f2r:m.m..:
|
||
---
|
||
name: arrassign-fnc-global
|
||
description:
|
||
Check locality of array access inside a function
|
||
with the bash4/mksh/yash/zsh typeset -g keyword
|
||
stdin:
|
||
function fn {
|
||
typeset -g x
|
||
x+=(f)
|
||
echo ".fn:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
|
||
}
|
||
function rfn {
|
||
set -A y
|
||
typeset -g y
|
||
y+=(f)
|
||
echo ".rfn:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
|
||
}
|
||
function fnr {
|
||
typeset -g z
|
||
set -A z
|
||
z+=(f)
|
||
echo ".fnr:${z[0]}.${z[1]}.${z[2]}.${z[3]}:"
|
||
}
|
||
x=(m m)
|
||
y=(m m)
|
||
z=(m m)
|
||
echo ".f0:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
|
||
fn
|
||
echo ".f1:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
|
||
fn
|
||
echo ".f2:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
|
||
echo ".rf0:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
|
||
rfn
|
||
echo ".rf1:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
|
||
rfn
|
||
echo ".rf2:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
|
||
echo ".f0r:${z[0]}.${z[1]}.${z[2]}.${z[3]}:"
|
||
fnr
|
||
echo ".f1r:${z[0]}.${z[1]}.${z[2]}.${z[3]}:"
|
||
fnr
|
||
echo ".f2r:${z[0]}.${z[1]}.${z[2]}.${z[3]}:"
|
||
expected-stdout:
|
||
.f0:m.m..:
|
||
.fn:m.m.f.:
|
||
.f1:m.m.f.:
|
||
.fn:m.m.f.f:
|
||
.f2:m.m.f.f:
|
||
.rf0:m.m..:
|
||
.rfn:f...:
|
||
.rf1:f...:
|
||
.rfn:f...:
|
||
.rf2:f...:
|
||
.f0r:m.m..:
|
||
.fnr:f...:
|
||
.f1r:f...:
|
||
.fnr:f...:
|
||
.f2r:f...:
|
||
---
|
||
name: strassign-fnc-none
|
||
description:
|
||
Check locality of string access inside a function
|
||
stdin:
|
||
function fn {
|
||
x+=f
|
||
echo ".fn:$x:"
|
||
}
|
||
function rfn {
|
||
y=
|
||
y+=f
|
||
echo ".rfn:$y:"
|
||
}
|
||
x=m
|
||
y=m
|
||
echo ".f0:$x:"
|
||
fn
|
||
echo ".f1:$x:"
|
||
fn
|
||
echo ".f2:$x:"
|
||
echo ".rf0:$y:"
|
||
rfn
|
||
echo ".rf1:$y:"
|
||
rfn
|
||
echo ".rf2:$y:"
|
||
expected-stdout:
|
||
.f0:m:
|
||
.fn:mf:
|
||
.f1:mf:
|
||
.fn:mff:
|
||
.f2:mff:
|
||
.rf0:m:
|
||
.rfn:f:
|
||
.rf1:f:
|
||
.rfn:f:
|
||
.rf2:f:
|
||
---
|
||
name: strassign-fnc-local
|
||
description:
|
||
Check locality of string access inside a function
|
||
with the bash/mksh/ksh93 local/typeset keyword
|
||
(note: ksh93 has no local; typeset works only in FKSH)
|
||
stdin:
|
||
function fn {
|
||
typeset x
|
||
x+=f
|
||
echo ".fn:$x:"
|
||
}
|
||
function rfn {
|
||
y=
|
||
typeset y
|
||
y+=f
|
||
echo ".rfn:$y:"
|
||
}
|
||
function fnr {
|
||
typeset z
|
||
z=
|
||
z+=f
|
||
echo ".fnr:$z:"
|
||
}
|
||
x=m
|
||
y=m
|
||
z=m
|
||
echo ".f0:$x:"
|
||
fn
|
||
echo ".f1:$x:"
|
||
fn
|
||
echo ".f2:$x:"
|
||
echo ".rf0:$y:"
|
||
rfn
|
||
echo ".rf1:$y:"
|
||
rfn
|
||
echo ".rf2:$y:"
|
||
echo ".f0r:$z:"
|
||
fnr
|
||
echo ".f1r:$z:"
|
||
fnr
|
||
echo ".f2r:$z:"
|
||
expected-stdout:
|
||
.f0:m:
|
||
.fn:f:
|
||
.f1:m:
|
||
.fn:f:
|
||
.f2:m:
|
||
.rf0:m:
|
||
.rfn:f:
|
||
.rf1::
|
||
.rfn:f:
|
||
.rf2::
|
||
.f0r:m:
|
||
.fnr:f:
|
||
.f1r:m:
|
||
.fnr:f:
|
||
.f2r:m:
|
||
---
|
||
name: strassign-fnc-global
|
||
description:
|
||
Check locality of string access inside a function
|
||
with the bash4/mksh/yash/zsh typeset -g keyword
|
||
stdin:
|
||
function fn {
|
||
typeset -g x
|
||
x+=f
|
||
echo ".fn:$x:"
|
||
}
|
||
function rfn {
|
||
y=
|
||
typeset -g y
|
||
y+=f
|
||
echo ".rfn:$y:"
|
||
}
|
||
function fnr {
|
||
typeset -g z
|
||
z=
|
||
z+=f
|
||
echo ".fnr:$z:"
|
||
}
|
||
x=m
|
||
y=m
|
||
z=m
|
||
echo ".f0:$x:"
|
||
fn
|
||
echo ".f1:$x:"
|
||
fn
|
||
echo ".f2:$x:"
|
||
echo ".rf0:$y:"
|
||
rfn
|
||
echo ".rf1:$y:"
|
||
rfn
|
||
echo ".rf2:$y:"
|
||
echo ".f0r:$z:"
|
||
fnr
|
||
echo ".f1r:$z:"
|
||
fnr
|
||
echo ".f2r:$z:"
|
||
expected-stdout:
|
||
.f0:m:
|
||
.fn:mf:
|
||
.f1:mf:
|
||
.fn:mff:
|
||
.f2:mff:
|
||
.rf0:m:
|
||
.rfn:f:
|
||
.rf1:f:
|
||
.rfn:f:
|
||
.rf2:f:
|
||
.f0r:m:
|
||
.fnr:f:
|
||
.f1r:f:
|
||
.fnr:f:
|
||
.f2r:f:
|
||
---
|
||
name: unset-fnc-local-ksh
|
||
description:
|
||
Check that “unset” removes a previous “local”
|
||
(ksh93 syntax compatible version); apparently,
|
||
there are shells which fail this?
|
||
stdin:
|
||
function f {
|
||
echo f0: $x
|
||
typeset x
|
||
echo f1: $x
|
||
x=fa
|
||
echo f2: $x
|
||
unset x
|
||
echo f3: $x
|
||
x=fb
|
||
echo f4: $x
|
||
}
|
||
x=o
|
||
echo before: $x
|
||
f
|
||
echo after: $x
|
||
expected-stdout:
|
||
before: o
|
||
f0: o
|
||
f1:
|
||
f2: fa
|
||
f3: o
|
||
f4: fb
|
||
after: fb
|
||
---
|
||
name: unset-fnc-local-sh
|
||
description:
|
||
Check that “unset” removes a previous “local”
|
||
(Debian Policy §10.4 sh version); apparently,
|
||
there are shells which fail this?
|
||
stdin:
|
||
f() {
|
||
echo f0: $x
|
||
local x
|
||
echo f1: $x
|
||
x=fa
|
||
echo f2: $x
|
||
unset x
|
||
echo f3: $x
|
||
x=fb
|
||
echo f4: $x
|
||
}
|
||
x=o
|
||
echo before: $x
|
||
f
|
||
echo after: $x
|
||
expected-stdout:
|
||
before: o
|
||
f0: o
|
||
f1:
|
||
f2: fa
|
||
f3: o
|
||
f4: fb
|
||
after: fb
|
||
---
|
||
name: varexpand-substr-1
|
||
description:
|
||
Check if bash-style substring expansion works
|
||
when using positive numerics
|
||
stdin:
|
||
x=abcdefghi
|
||
typeset -i y=123456789
|
||
typeset -i 16 z=123456789 # 16#75bcd15
|
||
echo a t${x:2:2} ${y:2:3} ${z:2:3} a
|
||
echo b ${x::3} ${y::3} ${z::3} b
|
||
echo c ${x:2:} ${y:2:} ${z:2:} c
|
||
echo d ${x:2} ${y:2} ${z:2} d
|
||
echo e ${x:2:6} ${y:2:6} ${z:2:7} e
|
||
echo f ${x:2:7} ${y:2:7} ${z:2:8} f
|
||
echo g ${x:2:8} ${y:2:8} ${z:2:9} g
|
||
expected-stdout:
|
||
a tcd 345 #75 a
|
||
b abc 123 16# b
|
||
c c
|
||
d cdefghi 3456789 #75bcd15 d
|
||
e cdefgh 345678 #75bcd1 e
|
||
f cdefghi 3456789 #75bcd15 f
|
||
g cdefghi 3456789 #75bcd15 g
|
||
---
|
||
name: varexpand-substr-2
|
||
description:
|
||
Check if bash-style substring expansion works
|
||
when using negative numerics or expressions
|
||
stdin:
|
||
x=abcdefghi
|
||
typeset -i y=123456789
|
||
typeset -i 16 z=123456789 # 16#75bcd15
|
||
n=2
|
||
echo a ${x:$n:3} ${y:$n:3} ${z:$n:3} a
|
||
echo b ${x:(n):3} ${y:(n):3} ${z:(n):3} b
|
||
echo c ${x:(-2):1} ${y:(-2):1} ${z:(-2):1} c
|
||
echo d t${x: n:2} ${y: n:3} ${z: n:3} d
|
||
expected-stdout:
|
||
a cde 345 #75 a
|
||
b cde 345 #75 b
|
||
c h 8 1 c
|
||
d tcd 345 #75 d
|
||
---
|
||
name: varexpand-substr-3
|
||
description:
|
||
Check that some things that work in bash fail.
|
||
This is by design. Oh and vice versa, nowadays.
|
||
stdin:
|
||
export x=abcdefghi n=2
|
||
"$__progname" -c 'echo v${x:(n)}x'
|
||
"$__progname" -c 'echo w${x: n}x'
|
||
"$__progname" -c 'echo x${x:n}x'
|
||
"$__progname" -c 'echo y${x:}x'
|
||
"$__progname" -c 'echo z${x}x'
|
||
# next fails only in bash
|
||
"$__progname" -c 'x=abcdef;y=123;echo ${x:${y:2:1}:2}' >/dev/null 2>&1; echo $?
|
||
expected-stdout:
|
||
vcdefghix
|
||
wcdefghix
|
||
zabcdefghix
|
||
0
|
||
expected-stderr-pattern:
|
||
/x:n.*bad substitution.*\n.*bad substitution/
|
||
---
|
||
name: varexpand-substr-4
|
||
description:
|
||
Check corner cases for substring expansion
|
||
stdin:
|
||
x=abcdefghi
|
||
integer y=2
|
||
echo a ${x:(y == 1 ? 2 : 3):4} a
|
||
expected-stdout:
|
||
a defg a
|
||
---
|
||
name: varexpand-substr-5A
|
||
description:
|
||
Check that substring expansions work on characters
|
||
stdin:
|
||
set +U
|
||
x=mäh
|
||
echo a ${x::1} ${x: -1} a
|
||
echo b ${x::3} ${x: -3} b
|
||
echo c ${x:1:2} ${x: -3:2} c
|
||
echo d ${#x} d
|
||
expected-stdout:
|
||
a m h a
|
||
b mä äh b
|
||
c ä ä c
|
||
d 4 d
|
||
---
|
||
name: varexpand-substr-5W
|
||
description:
|
||
Check that substring expansions work on characters
|
||
stdin:
|
||
set -U
|
||
x=mäh
|
||
echo a ${x::1} ${x: -1} a
|
||
echo b ${x::2} ${x: -2} b
|
||
echo c ${x:1:1} ${x: -2:1} c
|
||
echo d ${#x} d
|
||
expected-stdout:
|
||
a m h a
|
||
b mä äh b
|
||
c ä ä c
|
||
d 3 d
|
||
---
|
||
name: varexpand-substr-6
|
||
description:
|
||
Check that string substitution works correctly
|
||
stdin:
|
||
foo=1
|
||
bar=2
|
||
baz=qwertyuiop
|
||
echo a ${baz: foo: bar}
|
||
echo b ${baz: foo: $bar}
|
||
echo c ${baz: $foo: bar}
|
||
echo d ${baz: $foo: $bar}
|
||
expected-stdout:
|
||
a we
|
||
b we
|
||
c we
|
||
d we
|
||
---
|
||
name: varexpand-special-hash
|
||
description:
|
||
Check special ${var@x} expansion for x=hash
|
||
category: !shell:ebcdic-yes
|
||
stdin:
|
||
typeset -i8 foo=10
|
||
bar=baz
|
||
unset baz
|
||
print ${foo@#} ${bar@#} ${baz@#} .
|
||
expected-stdout:
|
||
9B15FBFB CFBDD32B 00000000 .
|
||
---
|
||
name: varexpand-special-hash-ebcdic
|
||
description:
|
||
Check special ${var@x} expansion for x=hash
|
||
category: !shell:ebcdic-no
|
||
stdin:
|
||
typeset -i8 foo=10
|
||
bar=baz
|
||
unset baz
|
||
print ${foo@#} ${bar@#} ${baz@#} .
|
||
expected-stdout:
|
||
016AE33D 9769C4AF 00000000 .
|
||
---
|
||
name: varexpand-special-quote
|
||
description:
|
||
Check special ${var@Q} expansion for quoted strings
|
||
category: !shell:faux-ebcdic
|
||
stdin:
|
||
set +U
|
||
i=x
|
||
j=a\ b
|
||
k=$'c
|
||
d\xA0''e€f'
|
||
print -r -- "<i=$i j=$j k=$k>"
|
||
s="u=${i@Q} v=${j@Q} w=${k@Q}"
|
||
print -r -- "s=\"$s\""
|
||
eval "$s"
|
||
typeset -p u v w
|
||
expected-stdout:
|
||
<i=x j=a b k=c
|
||
d<>e€f>
|
||
s="u=x v='a b' w=$'c\nd\240e\u20ACf'"
|
||
typeset u=x
|
||
typeset v='a b'
|
||
typeset w=$'c\nd\240e\u20ACf'
|
||
---
|
||
name: varexpand-special-quote-faux-EBCDIC
|
||
description:
|
||
Check special ${var@Q} expansion for quoted strings
|
||
category: shell:faux-ebcdic
|
||
stdin:
|
||
set +U
|
||
i=x
|
||
j=a\ b
|
||
k=$'c
|
||
d\xA0''e€f'
|
||
print -r -- "<i=$i j=$j k=$k>"
|
||
s="u=${i@Q} v=${j@Q} w=${k@Q}"
|
||
print -r -- "s=\"$s\""
|
||
eval "$s"
|
||
typeset -p u v w
|
||
expected-stdout:
|
||
<i=x j=a b k=c
|
||
d<>e€f>
|
||
s="u=x v='a b' w=$'c\nd<6E>e\u20ACf'"
|
||
typeset u=x
|
||
typeset v='a b'
|
||
typeset w=$'c\nd<6E>e\u20ACf'
|
||
---
|
||
name: varexpand-null-1
|
||
description:
|
||
Ensure empty strings expand emptily
|
||
stdin:
|
||
print s ${a} . ${b} S
|
||
print t ${a#?} . ${b%?} T
|
||
print r ${a=} . ${b/c/d} R
|
||
print q
|
||
print s "${a}" . "${b}" S
|
||
print t "${a#?}" . "${b%?}" T
|
||
print r "${a=}" . "${b/c/d}" R
|
||
expected-stdout:
|
||
s . S
|
||
t . T
|
||
r . R
|
||
q
|
||
s . S
|
||
t . T
|
||
r . R
|
||
---
|
||
name: varexpand-null-2
|
||
description:
|
||
Ensure empty strings, when quoted, are expanded as empty strings
|
||
stdin:
|
||
print '#!'"$__progname"'\nfor x in "$@"; do print -nr -- "<$x> "; done' >pfs
|
||
chmod +x pfs
|
||
./pfs 1 "${a}" 2 "${a#?}" + "${b%?}" 3 "${a=}" + "${b/c/d}"
|
||
echo .
|
||
expected-stdout:
|
||
<1> <> <2> <> <+> <> <3> <> <+> <> .
|
||
---
|
||
name: varexpand-null-3
|
||
description:
|
||
Ensure concatenating behaviour matches other shells
|
||
stdin:
|
||
showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
|
||
showargs 0 ""$@
|
||
x=; showargs 1 "$x"$@
|
||
set A; showargs 2 "${@:+}"
|
||
n() { echo "$#"; }
|
||
unset e
|
||
set -- a b
|
||
n """$@"
|
||
n "$@"
|
||
n "$@"""
|
||
n "$e""$@"
|
||
n "$@"
|
||
n "$@""$e"
|
||
set --
|
||
n """$@"
|
||
n "$@"
|
||
n "$@"""
|
||
n "$e""$@"
|
||
n "$@"
|
||
n "$@""$e"
|
||
expected-stdout:
|
||
<0> <> .
|
||
<1> <> .
|
||
<2> <> .
|
||
2
|
||
2
|
||
2
|
||
2
|
||
2
|
||
2
|
||
1
|
||
0
|
||
1
|
||
1
|
||
0
|
||
1
|
||
---
|
||
name: varexpand-funny-chars
|
||
description:
|
||
Check some characters
|
||
XXX \uEF80 is asymmetric, possibly buggy so we don’t check this
|
||
stdin:
|
||
x=$'<\x00>'; typeset -p x
|
||
x=$'<\x01>'; typeset -p x
|
||
x=$'<\u0000>'; typeset -p x
|
||
x=$'<\u0001>'; typeset -p x
|
||
expected-stdout:
|
||
typeset x='<'
|
||
typeset x=$'<\001>'
|
||
typeset x='<'
|
||
typeset x=$'<\001>'
|
||
---
|
||
name: print-funny-chars
|
||
description:
|
||
Check print builtin's capability to output designated characters
|
||
stdin:
|
||
{
|
||
print '<\0144\0344\xDB\u00DB\u20AC\uDB\x40>'
|
||
print '<\x00>'
|
||
print '<\x01>'
|
||
print '<\u0000>'
|
||
print '<\u0001>'
|
||
} | {
|
||
# integer-base-one-3Ar
|
||
typeset -Uui16 -Z11 pos=0
|
||
typeset -Uui16 -Z5 hv=2147483647
|
||
dasc=
|
||
if read -arN -1 line; then
|
||
typeset -i1 line
|
||
i=0
|
||
while (( i < ${#line[*]} )); do
|
||
hv=${line[i++]}
|
||
if (( (pos & 15) == 0 )); then
|
||
(( pos )) && print -r -- "$dasc|"
|
||
print -n "${pos#16#} "
|
||
dasc=' |'
|
||
fi
|
||
print -n "${hv#16#} "
|
||
if (( (hv < 32) || (hv > 126) )); then
|
||
dasc=$dasc.
|
||
else
|
||
dasc=$dasc${line[i-1]#1#}
|
||
fi
|
||
(( (pos++ & 15) == 7 )) && print -n -- '- '
|
||
done
|
||
fi
|
||
while (( pos & 15 )); do
|
||
print -n ' '
|
||
(( (pos++ & 15) == 7 )) && print -n -- '- '
|
||
done
|
||
(( hv == 2147483647 )) || print -r -- "$dasc|"
|
||
}
|
||
expected-stdout:
|
||
00000000 3C 64 E4 DB C3 9B E2 82 - AC C3 9B 40 3E 0A 3C 00 |<d.........@>.<.|
|
||
00000010 3E 0A 3C 01 3E 0A 3C 00 - 3E 0A 3C 01 3E 0A |>.<.>.<.>.<.>.|
|
||
---
|
||
name: print-bksl-c
|
||
description:
|
||
Check print builtin's \c escape
|
||
stdin:
|
||
print '\ca'; print b
|
||
expected-stdout:
|
||
ab
|
||
---
|
||
name: print-cr
|
||
description:
|
||
Check that CR+LF is not collapsed into LF as some MSYS shells wrongly do
|
||
stdin:
|
||
echo '#!'"$__progname" >foo
|
||
cat >>foo <<-'EOF'
|
||
print -n -- '220-blau.mirbsd.org ESMTP ready at Thu, 25 Jul 2013 15:57:57 GMT\r\n220->> Bitte keine Werbung einwerfen! <<\r\r\n220 Who do you wanna pretend to be today'
|
||
print \?
|
||
EOF
|
||
chmod +x foo
|
||
echo "[$(./foo)]"
|
||
./foo | while IFS= read -r line; do
|
||
print -r -- "{$line}"
|
||
done
|
||
expected-stdout:
|
||
[220-blau.mirbsd.org ESMTP ready at Thu, 25 Jul 2013 15:57:57 GMT
|
||
220->> Bitte keine Werbung einwerfen! <<
|
||
|
||
220 Who do you wanna pretend to be today?
|
||
]
|
||
{220-blau.mirbsd.org ESMTP ready at Thu, 25 Jul 2013 15:57:57 GMT
|
||
}
|
||
{220->> Bitte keine Werbung einwerfen! <<
|
||
|
||
}
|
||
{220 Who do you wanna pretend to be today?
|
||
}
|
||
---
|
||
name: print-crlf
|
||
description:
|
||
Check that CR+LF is shown and read as-is
|
||
category: shell:textmode-no
|
||
stdin:
|
||
cat >foo <<-'EOF'
|
||
x='bar
|
||
' #
|
||
echo .${#x} #
|
||
if test x"$KSH_VERSION" = x""; then #
|
||
printf '<%s>' "$x" #
|
||
else #
|
||
print -nr -- "<$x>" #
|
||
fi #
|
||
EOF
|
||
echo "[$("$__progname" foo)]"
|
||
"$__progname" foo | while IFS= read -r line; do
|
||
print -r -- "{$line}"
|
||
done
|
||
expected-stdout:
|
||
[.5
|
||
<bar
|
||
>]
|
||
{.5}
|
||
{<bar
|
||
}
|
||
---
|
||
name: print-crlf-textmode
|
||
description:
|
||
Check that CR+LF is treated as newline
|
||
category: shell:textmode-yes
|
||
stdin:
|
||
cat >foo <<-'EOF'
|
||
x='bar
|
||
' #
|
||
echo .${#x} #
|
||
if test x"$KSH_VERSION" = x""; then #
|
||
printf '<%s>' "$x" #
|
||
else #
|
||
print -nr -- "<$x>" #
|
||
fi #
|
||
EOF
|
||
echo "[$("$__progname" foo)]"
|
||
"$__progname" foo | while IFS= read -r line; do
|
||
print -r -- "{$line}"
|
||
done
|
||
expected-stdout:
|
||
[.4
|
||
<bar
|
||
>]
|
||
{.4}
|
||
{<bar}
|
||
---
|
||
name: print-lf
|
||
description:
|
||
Check that LF-only is shown and read as-is
|
||
stdin:
|
||
cat >foo <<-'EOF'
|
||
x='bar
|
||
' #
|
||
echo .${#x} #
|
||
if test x"$KSH_VERSION" = x""; then #
|
||
printf '<%s>' "$x" #
|
||
else #
|
||
print -nr -- "<$x>" #
|
||
fi #
|
||
EOF
|
||
echo "[$("$__progname" foo)]"
|
||
"$__progname" foo | while IFS= read -r line; do
|
||
print -r -- "{$line}"
|
||
done
|
||
expected-stdout:
|
||
[.4
|
||
<bar
|
||
>]
|
||
{.4}
|
||
{<bar}
|
||
---
|
||
name: print-nul-chars
|
||
description:
|
||
Check handling of NUL characters for print and COMSUB
|
||
stdin:
|
||
x=$(print '<\0>')
|
||
print $(($(print '<\0>' | wc -c))) $(($(print "$x" | wc -c))) \
|
||
${#x} "$x" '<\0>'
|
||
expected-stdout-pattern:
|
||
/^4 3 2 <> <\0>$/
|
||
---
|
||
name: print-array
|
||
description:
|
||
Check that print -A works as expected
|
||
stdin:
|
||
print -An 0x20AC 0xC3 0xBC 8#101
|
||
set -U
|
||
print -A 0x20AC 0xC3 0xBC 8#102
|
||
expected-stdout:
|
||
<09>üA€Ã¼B
|
||
---
|
||
name: print-escapes
|
||
description:
|
||
Check backslash expansion by the print builtin
|
||
stdin:
|
||
print '\ \!\"\#\$\%\&'\\\''\(\)\*\+\,\-\.\/\0\1\2\3\4\5\6\7\8' \
|
||
'\9\:\;\<\=\>\?\@\A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T' \
|
||
'\U\V\W\X\Y\Z\[\\\]\^\_\`\a\b \d\e\f\g\h\i\j\k\l\m\n\o\p' \
|
||
'\q\r\s\t\u\v\w\x\y\z\{\|\}\~' '\u20acd' '\U20acd' '\x123' \
|
||
'\0x' '\0123' '\01234' | {
|
||
# integer-base-one-3As
|
||
typeset -Uui16 -Z11 pos=0
|
||
typeset -Uui16 -Z5 hv=2147483647
|
||
typeset -i1 wc=0x0A
|
||
dasc=
|
||
nl=${wc#1#}
|
||
while IFS= read -r line; do
|
||
line=$line$nl
|
||
while [[ -n $line ]]; do
|
||
hv=1#${line::1}
|
||
if (( (pos & 15) == 0 )); then
|
||
(( pos )) && print -r -- "$dasc|"
|
||
print -n "${pos#16#} "
|
||
dasc=' |'
|
||
fi
|
||
print -n "${hv#16#} "
|
||
if (( (hv < 32) || (hv > 126) )); then
|
||
dasc=$dasc.
|
||
else
|
||
dasc=$dasc${line::1}
|
||
fi
|
||
(( (pos++ & 15) == 7 )) && print -n -- '- '
|
||
line=${line:1}
|
||
done
|
||
done
|
||
while (( pos & 15 )); do
|
||
print -n ' '
|
||
(( (pos++ & 15) == 7 )) && print -n -- '- '
|
||
done
|
||
(( hv == 2147483647 )) || print -r -- "$dasc|"
|
||
}
|
||
expected-stdout:
|
||
00000000 5C 20 5C 21 5C 22 5C 23 - 5C 24 5C 25 5C 26 5C 27 |\ \!\"\#\$\%\&\'|
|
||
00000010 5C 28 5C 29 5C 2A 5C 2B - 5C 2C 5C 2D 5C 2E 5C 2F |\(\)\*\+\,\-\.\/|
|
||
00000020 5C 31 5C 32 5C 33 5C 34 - 5C 35 5C 36 5C 37 5C 38 |\1\2\3\4\5\6\7\8|
|
||
00000030 20 5C 39 5C 3A 5C 3B 5C - 3C 5C 3D 5C 3E 5C 3F 5C | \9\:\;\<\=\>\?\|
|
||
00000040 40 5C 41 5C 42 5C 43 5C - 44 1B 5C 46 5C 47 5C 48 |@\A\B\C\D.\F\G\H|
|
||
00000050 5C 49 5C 4A 5C 4B 5C 4C - 5C 4D 5C 4E 5C 4F 5C 50 |\I\J\K\L\M\N\O\P|
|
||
00000060 5C 51 5C 52 5C 53 5C 54 - 20 5C 55 5C 56 5C 57 5C |\Q\R\S\T \U\V\W\|
|
||
00000070 58 5C 59 5C 5A 5C 5B 5C - 5C 5D 5C 5E 5C 5F 5C 60 |X\Y\Z\[\\]\^\_\`|
|
||
00000080 07 08 20 20 5C 64 1B 0C - 5C 67 5C 68 5C 69 5C 6A |.. \d..\g\h\i\j|
|
||
00000090 5C 6B 5C 6C 5C 6D 0A 5C - 6F 5C 70 20 5C 71 0D 5C |\k\l\m.\o\p \q.\|
|
||
000000A0 73 09 5C 75 0B 5C 77 5C - 78 5C 79 5C 7A 5C 7B 5C |s.\u.\w\x\y\z\{\|
|
||
000000B0 7C 5C 7D 5C 7E 20 E2 82 - AC 64 20 EF BF BD 20 12 ||\}\~ ...d ... .|
|
||
000000C0 33 20 78 20 53 20 53 34 - 0A |3 x S S4.|
|
||
---
|
||
name: dollar-doublequoted-strings
|
||
description:
|
||
Check that a $ preceding "…" is ignored
|
||
stdin:
|
||
echo $"Localise me!"
|
||
cat <<<$"Me too!"
|
||
V=X
|
||
aol=aol
|
||
cat <<-$"aol"
|
||
I do not take a $V for a V!
|
||
aol
|
||
expected-stdout:
|
||
Localise me!
|
||
Me too!
|
||
I do not take a $V for a V!
|
||
---
|
||
name: dollar-quoted-strings
|
||
description:
|
||
Check backslash expansion by $'…' strings
|
||
stdin:
|
||
print '#!'"$__progname"'\nfor x in "$@"; do print -r -- "$x"; done' >pfn
|
||
chmod +x pfn
|
||
./pfn $'\ \!\"\#\$\%\&\'\(\)\*\+\,\-\.\/ \1\2\3\4\5\6' \
|
||
$'a\0b' $'a\01b' $'\7\8\9\:\;\<\=\>\?\@\A\B\C\D\E\F\G\H\I' \
|
||
$'\J\K\L\M\N\O\P\Q\R\S\T\U1\V\W\X\Y\Z\[\\\]\^\_\`\a\b\d\e' \
|
||
$'\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u1\v\w\x1\y\z\{\|\}\~ $x' \
|
||
$'\u20acd' $'\U20acd' $'\x123' $'fn\x0rd' $'\0234' $'\234' \
|
||
$'\2345' $'\ca' $'\c!' $'\c?' $'\c…' $'a\
|
||
b' | {
|
||
# integer-base-one-3As
|
||
typeset -Uui16 -Z11 pos=0
|
||
typeset -Uui16 -Z5 hv=2147483647
|
||
typeset -i1 wc=0x0A
|
||
dasc=
|
||
nl=${wc#1#}
|
||
while IFS= read -r line; do
|
||
line=$line$nl
|
||
while [[ -n $line ]]; do
|
||
hv=1#${line::1}
|
||
if (( (pos & 15) == 0 )); then
|
||
(( pos )) && print -r -- "$dasc|"
|
||
print -n "${pos#16#} "
|
||
dasc=' |'
|
||
fi
|
||
print -n "${hv#16#} "
|
||
if (( (hv < 32) || (hv > 126) )); then
|
||
dasc=$dasc.
|
||
else
|
||
dasc=$dasc${line::1}
|
||
fi
|
||
(( (pos++ & 15) == 7 )) && print -n -- '- '
|
||
line=${line:1}
|
||
done
|
||
done
|
||
while (( pos & 15 )); do
|
||
print -n ' '
|
||
(( (pos++ & 15) == 7 )) && print -n -- '- '
|
||
done
|
||
(( hv == 2147483647 )) || print -r -- "$dasc|"
|
||
}
|
||
expected-stdout:
|
||
00000000 20 21 22 23 24 25 26 27 - 28 29 2A 2B 2C 2D 2E 2F | !"#$%&'()*+,-./|
|
||
00000010 20 01 02 03 04 05 06 0A - 61 0A 61 01 62 0A 07 38 | .......a.a.b..8|
|
||
00000020 39 3A 3B 3C 3D 3E 3F 40 - 41 42 43 44 1B 46 47 48 |9:;<=>?@ABCD.FGH|
|
||
00000030 49 0A 4A 4B 4C 4D 4E 4F - 50 51 52 53 54 01 56 57 |I.JKLMNOPQRST.VW|
|
||
00000040 58 59 5A 5B 5C 5D 5E 5F - 60 07 08 64 1B 0A 0C 67 |XYZ[\]^_`..d...g|
|
||
00000050 68 69 6A 6B 6C 6D 0A 6F - 70 71 0D 73 09 01 0B 77 |hijklm.opq.s...w|
|
||
00000060 01 79 7A 7B 7C 7D 7E 20 - 24 78 0A E2 82 AC 64 0A |.yz{|}~ $x....d.|
|
||
00000070 EF BF BD 0A C4 A3 0A 66 - 6E 0A 13 34 0A 9C 0A 9C |.......fn..4....|
|
||
00000080 35 0A 01 0A 01 0A 7F 0A - 82 80 A6 0A 61 0A 62 0A |5...........a.b.|
|
||
---
|
||
name: dollar-quotes-in-heredocs-strings
|
||
description:
|
||
They are, however, not parsed in here documents, here strings
|
||
(outside of string delimiters) or regular strings, but in
|
||
parameter substitutions.
|
||
stdin:
|
||
cat <<EOF
|
||
dollar = strchr(s, '$'); /* ' */
|
||
foo " bar \" baz
|
||
EOF
|
||
cat <<$'a\tb'
|
||
a\tb
|
||
a b
|
||
cat <<<"dollar = strchr(s, '$'); /* ' */"
|
||
cat <<<'dollar = strchr(s, '\''$'\''); /* '\'' */'
|
||
x="dollar = strchr(s, '$'); /* ' */"
|
||
cat <<<"$x"
|
||
cat <<<$'a\E[0m\tb'
|
||
unset nl; print -r -- "x${nl:=$'\n'}y"
|
||
echo "1 foo\"bar"
|
||
# cf & HEREDOC
|
||
cat <<EOF
|
||
2 foo\"bar
|
||
EOF
|
||
# probably never reached for here strings?
|
||
cat <<<"3 foo\"bar"
|
||
cat <<<"4 foo\\\"bar"
|
||
cat <<<'5 foo\"bar'
|
||
# old scripts use this (e.g. ncurses)
|
||
echo "^$"
|
||
# make sure this works, outside of quotes
|
||
cat <<<'7'$'\t''.'
|
||
expected-stdout:
|
||
dollar = strchr(s, '$'); /* ' */
|
||
foo " bar \" baz
|
||
a\tb
|
||
dollar = strchr(s, '$'); /* ' */
|
||
dollar = strchr(s, '$'); /* ' */
|
||
dollar = strchr(s, '$'); /* ' */
|
||
a[0m b
|
||
x
|
||
y
|
||
1 foo"bar
|
||
2 foo\"bar
|
||
3 foo"bar
|
||
4 foo\"bar
|
||
5 foo\"bar
|
||
^$
|
||
7 .
|
||
---
|
||
name: dot-needs-argument
|
||
description:
|
||
check Debian #415167 solution: '.' without arguments should fail
|
||
stdin:
|
||
"$__progname" -c .
|
||
"$__progname" -c source
|
||
expected-exit: e != 0
|
||
expected-stderr-pattern:
|
||
/\.: missing argument.*\n.*source: missing argument/
|
||
---
|
||
name: dot-errorlevel
|
||
description:
|
||
Ensure dot resets $?
|
||
stdin:
|
||
:>dotfile
|
||
(exit 42)
|
||
. ./dotfile
|
||
echo 1 $? .
|
||
expected-stdout:
|
||
1 0 .
|
||
---
|
||
name: alias-function-no-conflict
|
||
description:
|
||
make aliases not conflict with function definitions
|
||
stdin:
|
||
# POSIX function can be defined, but alias overrides it
|
||
alias foo='echo bar'
|
||
foo
|
||
foo() {
|
||
echo baz
|
||
}
|
||
foo
|
||
unset -f foo
|
||
foo 2>/dev/null || echo rab
|
||
# alias overrides ksh function
|
||
alias korn='echo bar'
|
||
korn
|
||
function korn {
|
||
echo baz
|
||
}
|
||
korn
|
||
# alias temporarily overrides POSIX function
|
||
bla() {
|
||
echo bfn
|
||
}
|
||
bla
|
||
alias bla='echo bal'
|
||
bla
|
||
unalias bla
|
||
bla
|
||
expected-stdout:
|
||
bar
|
||
bar
|
||
bar
|
||
bar
|
||
bar
|
||
bfn
|
||
bal
|
||
bfn
|
||
---
|
||
name: bash-function-parens
|
||
description:
|
||
ensure the keyword function is ignored when preceding
|
||
POSIX style function declarations (bashism)
|
||
stdin:
|
||
mk() {
|
||
echo '#!'"$__progname"
|
||
echo "$1 {"
|
||
echo ' echo "bar='\''$0'\'\"
|
||
echo '}'
|
||
print -r -- "${2:-foo}"
|
||
}
|
||
mk 'function foo' >f-korn
|
||
mk 'foo ()' >f-dash
|
||
mk 'function foo ()' >f-bash
|
||
print '#!'"$__progname"'\nprint -r -- "${0%/f-argh}"' >f-argh
|
||
chmod +x f-*
|
||
u=$(./f-argh)
|
||
x="korn: $(./f-korn)"; echo "${x/@("$u")/.}"
|
||
x="dash: $(./f-dash)"; echo "${x/@("$u")/.}"
|
||
x="bash: $(./f-bash)"; echo "${x/@("$u")/.}"
|
||
expected-stdout:
|
||
korn: bar='foo'
|
||
dash: bar='./f-dash'
|
||
bash: bar='./f-bash'
|
||
---
|
||
name: integer-base-one-1
|
||
description:
|
||
check if the use of fake integer base 1 works
|
||
stdin:
|
||
set -U
|
||
typeset -Uui16 i0=1#<23> i1=1#€
|
||
typeset -i1 o0a=64
|
||
typeset -i1 o1a=0x263A
|
||
typeset -Uui1 o0b=0x7E
|
||
typeset -Uui1 o1b=0xFDD0
|
||
integer px=0xCAFE 'p0=1# ' p1=1#… pl=1#f
|
||
echo "in <$i0> <$i1>"
|
||
echo "out <${o0a#1#}|${o0b#1#}> <${o1a#1#}|${o1b#1#}>"
|
||
typeset -Uui1 i0 i1
|
||
echo "pass <$px> <$p0> <$p1> <$pl> <${i0#1#}|${i1#1#}>"
|
||
typeset -Uui16 tv1=1#~ tv2=1# tv3=1#<23> tv4=1#<23> tv5=1#<23> tv6=1#<23> tv7=1# tv8=1#
|
||
echo "specX <${tv1#16#}> <${tv2#16#}> <${tv3#16#}> <${tv4#16#}> <${tv5#16#}> <${tv6#16#}> <${tv7#16#}> <${tv8#16#}>"
|
||
typeset -i1 tv1 tv2 tv3 tv4 tv5 tv6 tv7 tv8
|
||
echo "specW <${tv1#1#}> <${tv2#1#}> <${tv3#1#}> <${tv4#1#}> <${tv5#1#}> <${tv6#1#}> <${tv7#1#}> <${tv8#1#}>"
|
||
typeset -i1 xs1=0xEF7F xs2=0xEF80 xs3=0xFDD0
|
||
echo "specU <${xs1#1#}> <${xs2#1#}> <${xs3#1#}>"
|
||
expected-stdout:
|
||
in <16#EFEF> <16#20AC>
|
||
out <@|~> <☺|>
|
||
pass <16#cafe> <1# > <1#…> <1#f> <<3C>|€>
|
||
specX <7E> <7F> <EF80> <EF81> <EFC0> <EFC1> <A0> <80>
|
||
specW <~> <> <<3C>> <<3C>> <<3C>> <<3C>> < > <>
|
||
specU <> <<3C>> <>
|
||
---
|
||
name: integer-base-one-2a
|
||
description:
|
||
check if the use of fake integer base 1 stops at correct characters
|
||
stdin:
|
||
set -U
|
||
integer x=1#foo
|
||
echo /$x/
|
||
expected-stderr-pattern:
|
||
/1#foo: unexpected 'oo'/
|
||
expected-exit: e != 0
|
||
---
|
||
name: integer-base-one-2b
|
||
description:
|
||
check if the use of fake integer base 1 stops at correct characters
|
||
stdin:
|
||
set -U
|
||
integer x=1#<23><>
|
||
echo /$x/
|
||
expected-stderr-pattern:
|
||
/1#<23><>: unexpected '<27>'/
|
||
expected-exit: e != 0
|
||
---
|
||
name: integer-base-one-2c1
|
||
description:
|
||
check if the use of fake integer base 1 stops at correct characters
|
||
stdin:
|
||
set -U
|
||
integer x=1#…
|
||
echo /$x/
|
||
expected-stdout:
|
||
/1#…/
|
||
---
|
||
name: integer-base-one-2c2
|
||
description:
|
||
check if the use of fake integer base 1 stops at correct characters
|
||
stdin:
|
||
set +U
|
||
integer x=1#…
|
||
echo /$x/
|
||
expected-stderr-pattern:
|
||
/1#…: unexpected '<27>'/
|
||
expected-exit: e != 0
|
||
---
|
||
name: integer-base-one-2d1
|
||
description:
|
||
check if the use of fake integer base 1 handles octets okay
|
||
stdin:
|
||
set -U
|
||
typeset -i16 x=1#<23>
|
||
echo /$x/ # invalid utf-8
|
||
expected-stdout:
|
||
/16#efff/
|
||
---
|
||
name: integer-base-one-2d2
|
||
description:
|
||
check if the use of fake integer base 1 handles octets
|
||
stdin:
|
||
set -U
|
||
typeset -i16 x=1#<23>
|
||
echo /$x/ # invalid 2-byte
|
||
expected-stdout:
|
||
/16#efc2/
|
||
---
|
||
name: integer-base-one-2d3
|
||
description:
|
||
check if the use of fake integer base 1 handles octets
|
||
stdin:
|
||
set -U
|
||
typeset -i16 x=1#<23>
|
||
echo /$x/ # invalid 2-byte
|
||
expected-stdout:
|
||
/16#efef/
|
||
---
|
||
name: integer-base-one-2d4
|
||
description:
|
||
check if the use of fake integer base 1 stops at invalid input
|
||
stdin:
|
||
set -U
|
||
typeset -i16 x=1#<23><><EFBFBD>
|
||
echo /$x/ # invalid 3-byte
|
||
expected-stderr-pattern:
|
||
/1#<23><><EFBFBD>: unexpected '<27>'/
|
||
expected-exit: e != 0
|
||
---
|
||
name: integer-base-one-2d5
|
||
description:
|
||
check if the use of fake integer base 1 stops at invalid input
|
||
stdin:
|
||
set -U
|
||
typeset -i16 x=1#<23><>
|
||
echo /$x/ # non-minimalistic
|
||
expected-stderr-pattern:
|
||
/1#<23><>: unexpected '<27>'/
|
||
expected-exit: e != 0
|
||
---
|
||
name: integer-base-one-2d6
|
||
description:
|
||
check if the use of fake integer base 1 stops at invalid input
|
||
stdin:
|
||
set -U
|
||
typeset -i16 x=1#<23><><EFBFBD>
|
||
echo /$x/ # non-minimalistic
|
||
expected-stderr-pattern:
|
||
/1#<23><><EFBFBD>: unexpected '<27>'/
|
||
expected-exit: e != 0
|
||
---
|
||
name: integer-base-one-3As
|
||
description:
|
||
some sample code for hexdumping
|
||
not NUL safe; input lines must be NL terminated
|
||
stdin:
|
||
{
|
||
print 'Hello, World!\\\nこんにちは!'
|
||
typeset -Uui16 i=0x100
|
||
# change that to 0xFF once we can handle embedded
|
||
# NUL characters in strings / here documents
|
||
while (( i++ < 0x1FF )); do
|
||
print -n "\x${i#16#1}"
|
||
done
|
||
print '\0z'
|
||
} | {
|
||
# integer-base-one-3As
|
||
typeset -Uui16 -Z11 pos=0
|
||
typeset -Uui16 -Z5 hv=2147483647
|
||
typeset -i1 wc=0x0A
|
||
dasc=
|
||
nl=${wc#1#}
|
||
while IFS= read -r line; do
|
||
line=$line$nl
|
||
while [[ -n $line ]]; do
|
||
hv=1#${line::1}
|
||
if (( (pos & 15) == 0 )); then
|
||
(( pos )) && print -r -- "$dasc|"
|
||
print -n "${pos#16#} "
|
||
dasc=' |'
|
||
fi
|
||
print -n "${hv#16#} "
|
||
if (( (hv < 32) || (hv > 126) )); then
|
||
dasc=$dasc.
|
||
else
|
||
dasc=$dasc${line::1}
|
||
fi
|
||
(( (pos++ & 15) == 7 )) && print -n -- '- '
|
||
line=${line:1}
|
||
done
|
||
done
|
||
while (( pos & 15 )); do
|
||
print -n ' '
|
||
(( (pos++ & 15) == 7 )) && print -n -- '- '
|
||
done
|
||
(( hv == 2147483647 )) || print -r -- "$dasc|"
|
||
}
|
||
expected-stdout:
|
||
00000000 48 65 6C 6C 6F 2C 20 57 - 6F 72 6C 64 21 5C 0A E3 |Hello, World!\..|
|
||
00000010 81 93 E3 82 93 E3 81 AB - E3 81 A1 E3 81 AF EF BC |................|
|
||
00000020 81 0A 01 02 03 04 05 06 - 07 08 09 0A 0B 0C 0D 0E |................|
|
||
00000030 0F 10 11 12 13 14 15 16 - 17 18 19 1A 1B 1C 1D 1E |................|
|
||
00000040 1F 20 21 22 23 24 25 26 - 27 28 29 2A 2B 2C 2D 2E |. !"#$%&'()*+,-.|
|
||
00000050 2F 30 31 32 33 34 35 36 - 37 38 39 3A 3B 3C 3D 3E |/0123456789:;<=>|
|
||
00000060 3F 40 41 42 43 44 45 46 - 47 48 49 4A 4B 4C 4D 4E |?@ABCDEFGHIJKLMN|
|
||
00000070 4F 50 51 52 53 54 55 56 - 57 58 59 5A 5B 5C 5D 5E |OPQRSTUVWXYZ[\]^|
|
||
00000080 5F 60 61 62 63 64 65 66 - 67 68 69 6A 6B 6C 6D 6E |_`abcdefghijklmn|
|
||
00000090 6F 70 71 72 73 74 75 76 - 77 78 79 7A 7B 7C 7D 7E |opqrstuvwxyz{|}~|
|
||
000000A0 7F 80 81 82 83 84 85 86 - 87 88 89 8A 8B 8C 8D 8E |................|
|
||
000000B0 8F 90 91 92 93 94 95 96 - 97 98 99 9A 9B 9C 9D 9E |................|
|
||
000000C0 9F A0 A1 A2 A3 A4 A5 A6 - A7 A8 A9 AA AB AC AD AE |................|
|
||
000000D0 AF B0 B1 B2 B3 B4 B5 B6 - B7 B8 B9 BA BB BC BD BE |................|
|
||
000000E0 BF C0 C1 C2 C3 C4 C5 C6 - C7 C8 C9 CA CB CC CD CE |................|
|
||
000000F0 CF D0 D1 D2 D3 D4 D5 D6 - D7 D8 D9 DA DB DC DD DE |................|
|
||
00000100 DF E0 E1 E2 E3 E4 E5 E6 - E7 E8 E9 EA EB EC ED EE |................|
|
||
00000110 EF F0 F1 F2 F3 F4 F5 F6 - F7 F8 F9 FA FB FC FD FE |................|
|
||
00000120 FF 7A 0A - |.z.|
|
||
---
|
||
name: integer-base-one-3Ws
|
||
description:
|
||
some sample code for hexdumping Unicode
|
||
not NUL safe; input lines must be NL terminated
|
||
stdin:
|
||
set -U
|
||
{
|
||
print 'Hello, World!\\\nこんにちは!'
|
||
typeset -Uui16 i=0x100
|
||
# change that to 0xFF once we can handle embedded
|
||
# NUL characters in strings / here documents
|
||
while (( i++ < 0x1FF )); do
|
||
print -n "\u${i#16#1}"
|
||
done
|
||
print
|
||
print \\xff # invalid utf-8
|
||
print \\xc2 # invalid 2-byte
|
||
print \\xef\\xbf\\xc0 # invalid 3-byte
|
||
print \\xc0\\x80 # non-minimalistic
|
||
print \\xe0\\x80\\x80 # non-minimalistic
|
||
print '<27>' # end of range
|
||
print '\0z' # embedded NUL
|
||
} | {
|
||
# integer-base-one-3Ws
|
||
typeset -Uui16 -Z11 pos=0
|
||
typeset -Uui16 -Z7 hv
|
||
typeset -i1 wc=0x0A
|
||
typeset -i lpos
|
||
dasc=
|
||
nl=${wc#1#}
|
||
while IFS= read -r line; do
|
||
line=$line$nl
|
||
lpos=0
|
||
while (( lpos < ${#line} )); do
|
||
wc=1#${line:(lpos++):1}
|
||
if (( (wc < 32) || \
|
||
((wc > 126) && (wc < 160)) )); then
|
||
dch=.
|
||
elif (( (wc & 0xFF80) == 0xEF80 )); then
|
||
dch=<3D>
|
||
else
|
||
dch=${wc#1#}
|
||
fi
|
||
if (( (pos & 7) == 7 )); then
|
||
dasc=$dasc$dch
|
||
dch=
|
||
elif (( (pos & 7) == 0 )); then
|
||
(( pos )) && print -r -- "$dasc|"
|
||
print -n "${pos#16#} "
|
||
dasc=' |'
|
||
fi
|
||
let hv=wc
|
||
print -n "${hv#16#} "
|
||
(( (pos++ & 7) == 3 )) && \
|
||
print -n -- '- '
|
||
dasc=$dasc$dch
|
||
done
|
||
done
|
||
while (( pos & 7 )); do
|
||
print -n ' '
|
||
(( (pos++ & 7) == 3 )) && print -n -- '- '
|
||
done
|
||
(( hv == 2147483647 )) || print -r -- "$dasc|"
|
||
}
|
||
expected-stdout:
|
||
00000000 0048 0065 006C 006C - 006F 002C 0020 0057 |Hello, W|
|
||
00000008 006F 0072 006C 0064 - 0021 005C 000A 3053 |orld!\.こ|
|
||
00000010 3093 306B 3061 306F - FF01 000A 0001 0002 |んにちは!...|
|
||
00000018 0003 0004 0005 0006 - 0007 0008 0009 000A |........|
|
||
00000020 000B 000C 000D 000E - 000F 0010 0011 0012 |........|
|
||
00000028 0013 0014 0015 0016 - 0017 0018 0019 001A |........|
|
||
00000030 001B 001C 001D 001E - 001F 0020 0021 0022 |..... !"|
|
||
00000038 0023 0024 0025 0026 - 0027 0028 0029 002A |#$%&'()*|
|
||
00000040 002B 002C 002D 002E - 002F 0030 0031 0032 |+,-./012|
|
||
00000048 0033 0034 0035 0036 - 0037 0038 0039 003A |3456789:|
|
||
00000050 003B 003C 003D 003E - 003F 0040 0041 0042 |;<=>?@AB|
|
||
00000058 0043 0044 0045 0046 - 0047 0048 0049 004A |CDEFGHIJ|
|
||
00000060 004B 004C 004D 004E - 004F 0050 0051 0052 |KLMNOPQR|
|
||
00000068 0053 0054 0055 0056 - 0057 0058 0059 005A |STUVWXYZ|
|
||
00000070 005B 005C 005D 005E - 005F 0060 0061 0062 |[\]^_`ab|
|
||
00000078 0063 0064 0065 0066 - 0067 0068 0069 006A |cdefghij|
|
||
00000080 006B 006C 006D 006E - 006F 0070 0071 0072 |klmnopqr|
|
||
00000088 0073 0074 0075 0076 - 0077 0078 0079 007A |stuvwxyz|
|
||
00000090 007B 007C 007D 007E - 007F 0080 0081 0082 |{|}~....|
|
||
00000098 0083 0084 0085 0086 - 0087 0088 0089 008A |........|
|
||
000000A0 008B 008C 008D 008E - 008F 0090 0091 0092 |........|
|
||
000000A8 0093 0094 0095 0096 - 0097 0098 0099 009A |........|
|
||
000000B0 009B 009C 009D 009E - 009F 00A0 00A1 00A2 |..... ¡¢|
|
||
000000B8 00A3 00A4 00A5 00A6 - 00A7 00A8 00A9 00AA |£¤¥¦§¨©ª|
|
||
000000C0 00AB 00AC 00AD 00AE - 00AF 00B0 00B1 00B2 |«¬®¯°±²|
|
||
000000C8 00B3 00B4 00B5 00B6 - 00B7 00B8 00B9 00BA |³´µ¶·¸¹º|
|
||
000000D0 00BB 00BC 00BD 00BE - 00BF 00C0 00C1 00C2 |»¼½¾¿ÀÁÂ|
|
||
000000D8 00C3 00C4 00C5 00C6 - 00C7 00C8 00C9 00CA |ÃÄÅÆÇÈÉÊ|
|
||
000000E0 00CB 00CC 00CD 00CE - 00CF 00D0 00D1 00D2 |ËÌÍÎÏÐÑÒ|
|
||
000000E8 00D3 00D4 00D5 00D6 - 00D7 00D8 00D9 00DA |ÓÔÕÖ×ØÙÚ|
|
||
000000F0 00DB 00DC 00DD 00DE - 00DF 00E0 00E1 00E2 |ÛÜÝÞßàáâ|
|
||
000000F8 00E3 00E4 00E5 00E6 - 00E7 00E8 00E9 00EA |ãäåæçèéê|
|
||
00000100 00EB 00EC 00ED 00EE - 00EF 00F0 00F1 00F2 |ëìíîïðñò|
|
||
00000108 00F3 00F4 00F5 00F6 - 00F7 00F8 00F9 00FA |óôõö÷øùú|
|
||
00000110 00FB 00FC 00FD 00FE - 00FF 000A EFFF 000A |ûüýþÿ.<2E>.|
|
||
00000118 EFC2 000A EFEF EFBF - EFC0 000A EFC0 EF80 |<EFBFBD>.<2E><><EFBFBD>.<2E><>|
|
||
00000120 000A EFE0 EF80 EF80 - 000A FFFD EFEF EFBF |.<2E><><EFBFBD>.<2E><><EFBFBD>|
|
||
00000128 EFBE EFEF EFBF EFBF - 000A 007A 000A |<EFBFBD><EFBFBD><EFBFBD><EFBFBD>.z.|
|
||
---
|
||
name: integer-base-one-3Ar
|
||
description:
|
||
some sample code for hexdumping; NUL and binary safe
|
||
stdin:
|
||
{
|
||
print 'Hello, World!\\\nこんにちは!'
|
||
typeset -Uui16 i=0x100
|
||
# change that to 0xFF once we can handle embedded
|
||
# NUL characters in strings / here documents
|
||
while (( i++ < 0x1FF )); do
|
||
print -n "\x${i#16#1}"
|
||
done
|
||
print '\0z'
|
||
} | {
|
||
# integer-base-one-3Ar
|
||
typeset -Uui16 -Z11 pos=0
|
||
typeset -Uui16 -Z5 hv=2147483647
|
||
dasc=
|
||
if read -arN -1 line; then
|
||
typeset -i1 line
|
||
i=0
|
||
while (( i < ${#line[*]} )); do
|
||
hv=${line[i++]}
|
||
if (( (pos & 15) == 0 )); then
|
||
(( pos )) && print -r -- "$dasc|"
|
||
print -n "${pos#16#} "
|
||
dasc=' |'
|
||
fi
|
||
print -n "${hv#16#} "
|
||
if (( (hv < 32) || (hv > 126) )); then
|
||
dasc=$dasc.
|
||
else
|
||
dasc=$dasc${line[i-1]#1#}
|
||
fi
|
||
(( (pos++ & 15) == 7 )) && print -n -- '- '
|
||
done
|
||
fi
|
||
while (( pos & 15 )); do
|
||
print -n ' '
|
||
(( (pos++ & 15) == 7 )) && print -n -- '- '
|
||
done
|
||
(( hv == 2147483647 )) || print -r -- "$dasc|"
|
||
}
|
||
expected-stdout:
|
||
00000000 48 65 6C 6C 6F 2C 20 57 - 6F 72 6C 64 21 5C 0A E3 |Hello, World!\..|
|
||
00000010 81 93 E3 82 93 E3 81 AB - E3 81 A1 E3 81 AF EF BC |................|
|
||
00000020 81 0A 01 02 03 04 05 06 - 07 08 09 0A 0B 0C 0D 0E |................|
|
||
00000030 0F 10 11 12 13 14 15 16 - 17 18 19 1A 1B 1C 1D 1E |................|
|
||
00000040 1F 20 21 22 23 24 25 26 - 27 28 29 2A 2B 2C 2D 2E |. !"#$%&'()*+,-.|
|
||
00000050 2F 30 31 32 33 34 35 36 - 37 38 39 3A 3B 3C 3D 3E |/0123456789:;<=>|
|
||
00000060 3F 40 41 42 43 44 45 46 - 47 48 49 4A 4B 4C 4D 4E |?@ABCDEFGHIJKLMN|
|
||
00000070 4F 50 51 52 53 54 55 56 - 57 58 59 5A 5B 5C 5D 5E |OPQRSTUVWXYZ[\]^|
|
||
00000080 5F 60 61 62 63 64 65 66 - 67 68 69 6A 6B 6C 6D 6E |_`abcdefghijklmn|
|
||
00000090 6F 70 71 72 73 74 75 76 - 77 78 79 7A 7B 7C 7D 7E |opqrstuvwxyz{|}~|
|
||
000000A0 7F 80 81 82 83 84 85 86 - 87 88 89 8A 8B 8C 8D 8E |................|
|
||
000000B0 8F 90 91 92 93 94 95 96 - 97 98 99 9A 9B 9C 9D 9E |................|
|
||
000000C0 9F A0 A1 A2 A3 A4 A5 A6 - A7 A8 A9 AA AB AC AD AE |................|
|
||
000000D0 AF B0 B1 B2 B3 B4 B5 B6 - B7 B8 B9 BA BB BC BD BE |................|
|
||
000000E0 BF C0 C1 C2 C3 C4 C5 C6 - C7 C8 C9 CA CB CC CD CE |................|
|
||
000000F0 CF D0 D1 D2 D3 D4 D5 D6 - D7 D8 D9 DA DB DC DD DE |................|
|
||
00000100 DF E0 E1 E2 E3 E4 E5 E6 - E7 E8 E9 EA EB EC ED EE |................|
|
||
00000110 EF F0 F1 F2 F3 F4 F5 F6 - F7 F8 F9 FA FB FC FD FE |................|
|
||
00000120 FF 00 7A 0A - |..z.|
|
||
---
|
||
name: integer-base-one-3Wr
|
||
description:
|
||
some sample code for hexdumping Unicode; NUL and binary safe
|
||
stdin:
|
||
set -U
|
||
{
|
||
print 'Hello, World!\\\nこんにちは!'
|
||
typeset -Uui16 i=0x100
|
||
# change that to 0xFF once we can handle embedded
|
||
# NUL characters in strings / here documents
|
||
while (( i++ < 0x1FF )); do
|
||
print -n "\u${i#16#1}"
|
||
done
|
||
print
|
||
print \\xff # invalid utf-8
|
||
print \\xc2 # invalid 2-byte
|
||
print \\xef\\xbf\\xc0 # invalid 3-byte
|
||
print \\xc0\\x80 # non-minimalistic
|
||
print \\xe0\\x80\\x80 # non-minimalistic
|
||
print '<27>' # end of range
|
||
print '\0z' # embedded NUL
|
||
} | {
|
||
# integer-base-one-3Wr
|
||
typeset -Uui16 -Z11 pos=0
|
||
typeset -Uui16 -Z7 hv=2147483647
|
||
dasc=
|
||
if read -arN -1 line; then
|
||
typeset -i1 line
|
||
i=0
|
||
while (( i < ${#line[*]} )); do
|
||
hv=${line[i++]}
|
||
if (( (hv < 32) || \
|
||
((hv > 126) && (hv < 160)) )); then
|
||
dch=.
|
||
elif (( (hv & 0xFF80) == 0xEF80 )); then
|
||
dch=<EFBFBD>
|
||
else
|
||
dch=${line[i-1]#1#}
|
||
fi
|
||
if (( (pos & 7) == 7 )); then
|
||
dasc=$dasc$dch
|
||
dch=
|
||
elif (( (pos & 7) == 0 )); then
|
||
(( pos )) && print -r -- "$dasc|"
|
||
print -n "${pos#16#} "
|
||
dasc=' |'
|
||
fi
|
||
print -n "${hv#16#} "
|
||
(( (pos++ & 7) == 3 )) && \
|
||
print -n -- '- '
|
||
dasc=$dasc$dch
|
||
done
|
||
fi
|
||
while (( pos & 7 )); do
|
||
print -n ' '
|
||
(( (pos++ & 7) == 3 )) && print -n -- '- '
|
||
done
|
||
(( hv == 2147483647 )) || print -r -- "$dasc|"
|
||
}
|
||
expected-stdout:
|
||
00000000 0048 0065 006C 006C - 006F 002C 0020 0057 |Hello, W|
|
||
00000008 006F 0072 006C 0064 - 0021 005C 000A 3053 |orld!\.こ|
|
||
00000010 3093 306B 3061 306F - FF01 000A 0001 0002 |んにちは!...|
|
||
00000018 0003 0004 0005 0006 - 0007 0008 0009 000A |........|
|
||
00000020 000B 000C 000D 000E - 000F 0010 0011 0012 |........|
|
||
00000028 0013 0014 0015 0016 - 0017 0018 0019 001A |........|
|
||
00000030 001B 001C 001D 001E - 001F 0020 0021 0022 |..... !"|
|
||
00000038 0023 0024 0025 0026 - 0027 0028 0029 002A |#$%&'()*|
|
||
00000040 002B 002C 002D 002E - 002F 0030 0031 0032 |+,-./012|
|
||
00000048 0033 0034 0035 0036 - 0037 0038 0039 003A |3456789:|
|
||
00000050 003B 003C 003D 003E - 003F 0040 0041 0042 |;<=>?@AB|
|
||
00000058 0043 0044 0045 0046 - 0047 0048 0049 004A |CDEFGHIJ|
|
||
00000060 004B 004C 004D 004E - 004F 0050 0051 0052 |KLMNOPQR|
|
||
00000068 0053 0054 0055 0056 - 0057 0058 0059 005A |STUVWXYZ|
|
||
00000070 005B 005C 005D 005E - 005F 0060 0061 0062 |[\]^_`ab|
|
||
00000078 0063 0064 0065 0066 - 0067 0068 0069 006A |cdefghij|
|
||
00000080 006B 006C 006D 006E - 006F 0070 0071 0072 |klmnopqr|
|
||
00000088 0073 0074 0075 0076 - 0077 0078 0079 007A |stuvwxyz|
|
||
00000090 007B 007C 007D 007E - 007F 0080 0081 0082 |{|}~....|
|
||
00000098 0083 0084 0085 0086 - 0087 0088 0089 008A |........|
|
||
000000A0 008B 008C 008D 008E - 008F 0090 0091 0092 |........|
|
||
000000A8 0093 0094 0095 0096 - 0097 0098 0099 009A |........|
|
||
000000B0 009B 009C 009D 009E - 009F 00A0 00A1 00A2 |..... ¡¢|
|
||
000000B8 00A3 00A4 00A5 00A6 - 00A7 00A8 00A9 00AA |£¤¥¦§¨©ª|
|
||
000000C0 00AB 00AC 00AD 00AE - 00AF 00B0 00B1 00B2 |«¬®¯°±²|
|
||
000000C8 00B3 00B4 00B5 00B6 - 00B7 00B8 00B9 00BA |³´µ¶·¸¹º|
|
||
000000D0 00BB 00BC 00BD 00BE - 00BF 00C0 00C1 00C2 |»¼½¾¿ÀÁÂ|
|
||
000000D8 00C3 00C4 00C5 00C6 - 00C7 00C8 00C9 00CA |ÃÄÅÆÇÈÉÊ|
|
||
000000E0 00CB 00CC 00CD 00CE - 00CF 00D0 00D1 00D2 |ËÌÍÎÏÐÑÒ|
|
||
000000E8 00D3 00D4 00D5 00D6 - 00D7 00D8 00D9 00DA |ÓÔÕÖ×ØÙÚ|
|
||
000000F0 00DB 00DC 00DD 00DE - 00DF 00E0 00E1 00E2 |ÛÜÝÞßàáâ|
|
||
000000F8 00E3 00E4 00E5 00E6 - 00E7 00E8 00E9 00EA |ãäåæçèéê|
|
||
00000100 00EB 00EC 00ED 00EE - 00EF 00F0 00F1 00F2 |ëìíîïðñò|
|
||
00000108 00F3 00F4 00F5 00F6 - 00F7 00F8 00F9 00FA |óôõö÷øùú|
|
||
00000110 00FB 00FC 00FD 00FE - 00FF 000A EFFF 000A |ûüýþÿ.<2E>.|
|
||
00000118 EFC2 000A EFEF EFBF - EFC0 000A EFC0 EF80 |<7C>.<2E><><EFBFBD>.<2E><>|
|
||
00000120 000A EFE0 EF80 EF80 - 000A FFFD EFEF EFBF |.<2E><><EFBFBD>.<2E><><EFBFBD>|
|
||
00000128 EFBE EFEF EFBF EFBF - 000A 0000 007A 000A |<7C><><EFBFBD><EFBFBD>..z.|
|
||
---
|
||
name: integer-base-one-4
|
||
description:
|
||
Check if ksh93-style base-one integers work
|
||
category: !smksh
|
||
stdin:
|
||
set -U
|
||
echo 1 $(('a'))
|
||
(echo 2f $(('aa'))) 2>&1 | sed "s/^[^']*'/2p '/"
|
||
echo 3 $(('…'))
|
||
x="'a'"
|
||
echo "4 <$x>"
|
||
echo 5 $(($x))
|
||
echo 6 $((x))
|
||
expected-stdout:
|
||
1 97
|
||
2p 'aa': multi-character character constant
|
||
3 8230
|
||
4 <'a'>
|
||
5 97
|
||
6 97
|
||
---
|
||
name: integer-base-one-5A
|
||
description:
|
||
Check to see that we’re NUL and Unicode safe
|
||
category: !shell:ebcdic-yes
|
||
stdin:
|
||
set +U
|
||
print 'a\0b\xfdz' >x
|
||
read -a y <x
|
||
set -U
|
||
typeset -Uui16 y
|
||
print ${y[*]} .
|
||
expected-stdout:
|
||
16#61 16#0 16#62 16#FD 16#7A .
|
||
---
|
||
name: integer-base-one-5E
|
||
description:
|
||
Check to see that we’re NUL and Unicode safe
|
||
category: !shell:ebcdic-no
|
||
stdin:
|
||
set +U
|
||
print 'a\0b\xfdz' >x
|
||
read -a y <x
|
||
set -U
|
||
typeset -Uui16 y
|
||
print ${y[*]} .
|
||
expected-stdout:
|
||
16#81 16#0 16#82 16#FD 16#A9 .
|
||
---
|
||
name: integer-base-one-5W
|
||
description:
|
||
Check to see that we’re NUL and Unicode safe
|
||
stdin:
|
||
set -U
|
||
print 'a\0b€c' >x
|
||
read -a y <x
|
||
set +U
|
||
typeset -Uui16 y
|
||
print ${y[*]} .
|
||
expected-stdout:
|
||
16#61 16#0 16#62 16#20AC 16#63 .
|
||
---
|
||
name: ulimit-1
|
||
description:
|
||
Check that ulimit as used in dot.mksh works or is stubbed
|
||
stdin:
|
||
ulimit -c 0
|
||
---
|
||
name: ulimit-2
|
||
description:
|
||
Check if we can use a specific syntax idiom for ulimit
|
||
XXX Haiku works, but only for -n and -V
|
||
category: !os:haiku,!os:syllable
|
||
stdin:
|
||
if ! x=$(ulimit -d) || [[ $x = unknown ]]; then
|
||
#echo expected to fail on this OS
|
||
echo okay
|
||
else
|
||
ulimit -dS $x && echo okay
|
||
fi
|
||
expected-stdout:
|
||
okay
|
||
---
|
||
name: redir-1
|
||
description:
|
||
Check some of the most basic invariants of I/O redirection
|
||
stdin:
|
||
i=0
|
||
function d {
|
||
print o$i.
|
||
print -u2 e$((i++)).
|
||
}
|
||
d >a 2>b
|
||
echo =1=
|
||
cat a
|
||
echo =2=
|
||
cat b
|
||
echo =3=
|
||
d 2>&1 >c
|
||
echo =4=
|
||
cat c
|
||
echo =5=
|
||
expected-stdout:
|
||
=1=
|
||
o0.
|
||
=2=
|
||
e0.
|
||
=3=
|
||
e1.
|
||
=4=
|
||
o1.
|
||
=5=
|
||
---
|
||
name: bashiop-1
|
||
description:
|
||
Check if GNU bash-like I/O redirection works
|
||
Part 1: this is also supported by GNU bash
|
||
stdin:
|
||
exec 3>&1
|
||
function threeout {
|
||
echo ras
|
||
echo dwa >&2
|
||
echo tri >&3
|
||
}
|
||
threeout &>foo
|
||
echo ===
|
||
cat foo
|
||
expected-stdout:
|
||
tri
|
||
===
|
||
ras
|
||
dwa
|
||
---
|
||
name: bashiop-2a
|
||
description:
|
||
Check if GNU bash-like I/O redirection works
|
||
Part 2: this is *not* supported by GNU bash
|
||
stdin:
|
||
exec 3>&1
|
||
function threeout {
|
||
echo ras
|
||
echo dwa >&2
|
||
echo tri >&3
|
||
}
|
||
threeout 3&>foo
|
||
echo ===
|
||
cat foo
|
||
expected-stdout:
|
||
ras
|
||
===
|
||
dwa
|
||
tri
|
||
---
|
||
name: bashiop-2b
|
||
description:
|
||
Check if GNU bash-like I/O redirection works
|
||
Part 2: this is *not* supported by GNU bash
|
||
stdin:
|
||
exec 3>&1
|
||
function threeout {
|
||
echo ras
|
||
echo dwa >&2
|
||
echo tri >&3
|
||
}
|
||
threeout 3>foo &>&3
|
||
echo ===
|
||
cat foo
|
||
expected-stdout:
|
||
===
|
||
ras
|
||
dwa
|
||
tri
|
||
---
|
||
name: bashiop-2c
|
||
description:
|
||
Check if GNU bash-like I/O redirection works
|
||
Part 2: this is supported by GNU bash 4 only
|
||
stdin:
|
||
echo mir >foo
|
||
set -o noclobber
|
||
exec 3>&1
|
||
function threeout {
|
||
echo ras
|
||
echo dwa >&2
|
||
echo tri >&3
|
||
}
|
||
threeout &>>foo
|
||
echo ===
|
||
cat foo
|
||
expected-stdout:
|
||
tri
|
||
===
|
||
mir
|
||
ras
|
||
dwa
|
||
---
|
||
name: bashiop-3a
|
||
description:
|
||
Check if GNU bash-like I/O redirection fails correctly
|
||
Part 1: this is also supported by GNU bash
|
||
stdin:
|
||
echo mir >foo
|
||
set -o noclobber
|
||
exec 3>&1
|
||
function threeout {
|
||
echo ras
|
||
echo dwa >&2
|
||
echo tri >&3
|
||
}
|
||
threeout &>foo
|
||
echo ===
|
||
cat foo
|
||
expected-stdout:
|
||
===
|
||
mir
|
||
expected-stderr-pattern: /.*: can't (create|overwrite) .*/
|
||
---
|
||
name: bashiop-3b
|
||
description:
|
||
Check if GNU bash-like I/O redirection fails correctly
|
||
Part 2: this is *not* supported by GNU bash
|
||
stdin:
|
||
echo mir >foo
|
||
set -o noclobber
|
||
exec 3>&1
|
||
function threeout {
|
||
echo ras
|
||
echo dwa >&2
|
||
echo tri >&3
|
||
}
|
||
threeout &>|foo
|
||
echo ===
|
||
cat foo
|
||
expected-stdout:
|
||
tri
|
||
===
|
||
ras
|
||
dwa
|
||
---
|
||
name: bashiop-4
|
||
description:
|
||
Check if GNU bash-like I/O redirection works
|
||
Part 4: this is also supported by GNU bash,
|
||
but failed in some mksh versions
|
||
stdin:
|
||
exec 3>&1
|
||
function threeout {
|
||
echo ras
|
||
echo dwa >&2
|
||
echo tri >&3
|
||
}
|
||
function blubb {
|
||
[[ -e bar ]] && threeout "$bf" &>foo
|
||
}
|
||
blubb
|
||
echo -n >bar
|
||
blubb
|
||
echo ===
|
||
cat foo
|
||
expected-stdout:
|
||
tri
|
||
===
|
||
ras
|
||
dwa
|
||
---
|
||
name: bashiop-5
|
||
description:
|
||
Check if GNU bash-like I/O redirection is only supported
|
||
in !POSIX !sh mode as it breaks existing scripts' syntax
|
||
stdin:
|
||
:>x; echo 1 "$("$__progname" -c 'echo foo>/dev/null&>x echo bar')" = "$(<x)" .
|
||
:>x; echo 2 "$("$__progname" -o posix -c 'echo foo>/dev/null&>x echo bar')" = "$(<x)" .
|
||
:>x; echo 3 "$("$__progname" -o sh -c 'echo foo>/dev/null&>x echo bar')" = "$(<x)" .
|
||
expected-stdout:
|
||
1 = foo echo bar .
|
||
2 = bar .
|
||
3 = bar .
|
||
---
|
||
name: oksh-eval
|
||
description:
|
||
Check expansions.
|
||
stdin:
|
||
a=
|
||
for n in ${a#*=}; do echo 1hu ${n} .; done
|
||
for n in "${a#*=}"; do echo 1hq ${n} .; done
|
||
for n in ${a##*=}; do echo 2hu ${n} .; done
|
||
for n in "${a##*=}"; do echo 2hq ${n} .; done
|
||
for n in ${a%=*}; do echo 1pu ${n} .; done
|
||
for n in "${a%=*}"; do echo 1pq ${n} .; done
|
||
for n in ${a%%=*}; do echo 2pu ${n} .; done
|
||
for n in "${a%%=*}"; do echo 2pq ${n} .; done
|
||
expected-stdout:
|
||
1hq .
|
||
2hq .
|
||
1pq .
|
||
2pq .
|
||
---
|
||
name: oksh-and-list-error-1
|
||
description:
|
||
Test exit status of rightmost element in 2 element && list in -e mode
|
||
stdin:
|
||
true && false
|
||
echo "should not print"
|
||
arguments: !-e!
|
||
expected-exit: e != 0
|
||
---
|
||
name: oksh-and-list-error-2
|
||
description:
|
||
Test exit status of rightmost element in 3 element && list in -e mode
|
||
stdin:
|
||
true && true && false
|
||
echo "should not print"
|
||
arguments: !-e!
|
||
expected-exit: e != 0
|
||
---
|
||
name: oksh-or-list-error-1
|
||
description:
|
||
Test exit status of || list in -e mode
|
||
stdin:
|
||
false || false
|
||
echo "should not print"
|
||
arguments: !-e!
|
||
expected-exit: e != 0
|
||
---
|
||
name: oksh-longline-crash
|
||
description:
|
||
This used to cause a core dump
|
||
stdin:
|
||
ulimit -c 0
|
||
deplibs="-lz -lpng /usr/local/lib/libjpeg.la -ltiff -lm -lX11 -lXext /usr/local/lib/libiconv.la -L/usr/local/lib -L/usr/ports/devel/gettext/w-gettext-0.10.40/gettext-0.10.40/intl/.libs /usr/local/lib/libintl.la /usr/local/lib/libglib.la /usr/local/lib/libgmodule.la -lintl -lm -lX11 -lXext -L/usr/X11R6/lib -lglib -lgmodule -L/usr/local/lib /usr/local/lib/libgdk.la -lintl -lm -lX11 -lXext -L/usr/X11R6/lib -lglib -lgmodule -L/usr/local/lib /usr/local/lib/libgtk.la -ltiff -ljpeg -lz -lpng -lm -lX11 -lXext -lintl -lglib -lgmodule -lgdk -lgtk -L/usr/X11R6/lib -lglib -lgmodule -L/usr/local/lib /usr/local/lib/libgdk_pixbuf.la -lz -lpng /usr/local/lib/libiconv.la -L/usr/local/lib -L/usr/ports/devel/gettext/w-gettext-0.10.40/gettext-0.10.40/intl/.libs /usr/local/lib/libintl.la /usr/local/lib/libglib.la -lm -lm /usr/local/lib/libaudiofile.la -lm -lm -laudiofile -L/usr/local/lib /usr/local/lib/libesd.la -lm -lz -L/usr/local/lib /usr/local/lib/libgnomesupport.la -lm -lz -lm -lglib -L/usr/local/lib /usr/local/lib/libgnome.la -lX11 -lXext /usr/local/lib/libiconv.la -L/usr/local/lib -L/usr/ports/devel/gettext/w-gettext-0.10.40/gettext-0.10.40/intl/.libs /usr/local/lib/libintl.la /usr/local/lib/libgmodule.la -lintl -lm -lX11 -lXext -L/usr/X11R6/lib -lglib -lgmodule -L/usr/local/lib /usr/local/lib/libgdk.la -lintl -lm -lX11 -lXext -L/usr/X11R6/lib -lglib -lgmodule -L/usr/local/lib /usr/local/lib/libgtk.la -lICE -lSM -lz -lpng /usr/local/lib/libungif.la /usr/local/lib/libjpeg.la -ltiff -lm -lz -lpng /usr/local/lib/libungif.la -lz /usr/local/lib/libjpeg.la -ltiff -L/usr/local/lib -L/usr/X11R6/lib /usr/local/lib/libgdk_imlib.la -lm -L/usr/local/lib /usr/local/lib/libart_lgpl.la -lm -lz -lm -lX11 -lXext -lintl -lglib -lgmodule -lgdk -lgtk -lICE -lSM -lm -lX11 -lXext -lintl -lglib -lgmodule -lgdk -lgtk -L/usr/X11R6/lib -lm -lz -lpng -lungif -lz -ljpeg -ltiff -ljpeg -lgdk_imlib -lglib -lm -laudiofile -lm -laudiofile -lesd -L/usr/local/lib /usr/local/lib/libgnomeui.la -lz -lz /usr/local/lib/libxml.la -lz -lz -lz /usr/local/lib/libxml.la -lm -lX11 -lXext /usr/local/lib/libiconv.la -L/usr/ports/devel/gettext/w-gettext-0.10.40/gettext-0.10.40/intl/.libs /usr/local/lib/libintl.la /usr/local/lib/libglib.la /usr/local/lib/libgmodule.la -lintl -lglib -lgmodule /usr/local/lib/libgdk.la /usr/local/lib/libgtk.la -L/usr/X11R6/lib -L/usr/local/lib /usr/local/lib/libglade.la -lz -lz -lz /usr/local/lib/libxml.la /usr/local/lib/libglib.la -lm -lm /usr/local/lib/libaudiofile.la -lm -lm -laudiofile /usr/local/lib/libesd.la -lm -lz /usr/local/lib/libgnomesupport.la -lm -lz -lm -lglib /usr/local/lib/libgnome.la -lX11 -lXext /usr/local/lib/libiconv.la -L/usr/ports/devel/gettext/w-gettext-0.10.40/gettext-0.10.40/intl/.libs /usr/local/lib/libintl.la /usr/local/lib/libgmodule.la -lintl -lm -lX11 -lXext -lglib -lgmodule /usr/local/lib/libgdk.la -lintl -lm -lX11 -lXext -lglib -lgmodule /usr/local/lib/libgtk.la -lICE -lSM -lz -lpng /usr/local/lib/libungif.la /usr/local/lib/libjpeg.la -ltiff -lm -lz -lz /usr/local/lib/libgdk_imlib.la /usr/local/lib/libart_lgpl.la -lm -lz -lm -lX11 -lXext -lintl -lglib -lgmodule -lgdk -lgtk -lm -lX11 -lXext -lintl -lglib -lgmodule -lgdk -lgtk -lm -lz -lungif -lz -ljpeg -ljpeg -lgdk_imlib -lglib -lm -laudiofile -lm -laudiofile -lesd /usr/local/lib/libgnomeui.la -L/usr/X11R6/lib -L/usr/local/lib /usr/local/lib/libglade-gnome.la /usr/local/lib/libglib.la -lm -lm /usr/local/lib/libaudiofile.la -lm -lm -laudiofile -L/usr/local/lib /usr/local/lib/libesd.la -lm -lz -L/usr/local/lib /usr/local/lib/libgnomesupport.la -lm -lz -lm -lglib -L/usr/local/lib /usr/local/lib/libgnome.la -lX11 -lXext /usr/local/lib/libiconv.la -L/usr/local/lib -L/usr/ports/devel/gettext/w-gettext-0.10.40/gettext-0.10.40/intl/.libs /usr/local/lib/libintl.la /usr/local/lib/libgmodule.la -lintl -lm -lX11 -lXext -L/usr/X11R6/lib -lglib -lgmodule -L/usr/local/lib /usr/local/lib/libgdk.la -lintl -lm -lX11 -lXext -L/usr/X11R6/lib -lglib -lgmodule -L/usr/local/lib /usr/local/lib/libgtk.la -lICE -lSM -lz -lpng /usr/local/lib/libungif.la /usr/local/lib/libjpeg.la -ltiff -lm -lz -lpng /usr/local/lib/libungif.la -lz /usr/local/lib/libjpeg.la -ltiff -L/usr/local/lib -L/usr/X11R6/lib /usr/local/lib/libgdk_imlib.la -lm -L/usr/local/lib /usr/local/lib/libart_lgpl.la -lm -lz -lm -lX11 -lXext -lintl -lglib -lgmodule -lgdk -lgtk -lICE -lSM -lm -lX11 -lXext -lintl -lglib -lgmodule -lgdk -lgtk -L/usr/X11R6/lib -lm -lz -lpng -lungif -lz -ljpeg -ltiff -ljpeg -lgdk_imlib -lglib -lm -laudiofile -lm -laudiofile -lesd -L/usr/local/lib /usr/local/lib/libgnomeui.la -L/usr/X11R6/lib -L/usr/local/lib"
|
||
specialdeplibs="-lgnomeui -lart_lgpl -lgdk_imlib -ltiff -ljpeg -lungif -lpng -lz -lSM -lICE -lgtk -lgdk -lgmodule -lintl -lXext -lX11 -lgnome -lgnomesupport -lesd -laudiofile -lm -lglib"
|
||
for deplib in $deplibs; do
|
||
case $deplib in
|
||
-L*)
|
||
new_libs="$deplib $new_libs"
|
||
;;
|
||
*)
|
||
case " $specialdeplibs " in
|
||
*" $deplib "*)
|
||
new_libs="$deplib $new_libs";;
|
||
esac
|
||
;;
|
||
esac
|
||
done
|
||
---
|
||
name: oksh-seterror-1
|
||
description:
|
||
The -e flag should be ignored when executing a compound list
|
||
followed by an if statement.
|
||
stdin:
|
||
if true; then false && false; fi
|
||
true
|
||
arguments: !-e!
|
||
expected-exit: e == 0
|
||
---
|
||
name: oksh-seterror-2
|
||
description:
|
||
The -e flag should be ignored when executing a compound list
|
||
followed by an if statement.
|
||
stdin:
|
||
if true; then if true; then false && false; fi; fi
|
||
true
|
||
arguments: !-e!
|
||
expected-exit: e == 0
|
||
---
|
||
name: oksh-seterror-3
|
||
description:
|
||
The -e flag should be ignored when executing a compound list
|
||
followed by an elif statement.
|
||
stdin:
|
||
if true; then :; elif true; then false && false; fi
|
||
arguments: !-e!
|
||
expected-exit: e == 0
|
||
---
|
||
name: oksh-seterror-4
|
||
description:
|
||
The -e flag should be ignored when executing a pipeline
|
||
beginning with '!'
|
||
stdin:
|
||
for i in 1 2 3
|
||
do
|
||
false && false
|
||
true || false
|
||
done
|
||
arguments: !-e!
|
||
expected-exit: e == 0
|
||
---
|
||
name: oksh-seterror-5
|
||
description:
|
||
The -e flag should be ignored when executing a pipeline
|
||
beginning with '!'
|
||
stdin:
|
||
! true | false
|
||
true
|
||
arguments: !-e!
|
||
expected-exit: e == 0
|
||
---
|
||
name: oksh-seterror-6
|
||
description:
|
||
When trapping ERR and EXIT, both traps should run in -e mode
|
||
when an error occurs.
|
||
stdin:
|
||
trap 'echo EXIT' EXIT
|
||
trap 'echo ERR' ERR
|
||
set -e
|
||
false
|
||
echo DONE
|
||
exit 0
|
||
arguments: !-e!
|
||
expected-exit: e != 0
|
||
expected-stdout:
|
||
ERR
|
||
EXIT
|
||
---
|
||
name: oksh-seterror-7
|
||
description:
|
||
The -e flag within a command substitution should be honored
|
||
stdin:
|
||
echo $( set -e; false; echo foo )
|
||
arguments: !-e!
|
||
expected-stdout:
|
||
|
||
---
|
||
name: oksh-input-comsub
|
||
description:
|
||
A command substitution using input redirection should exit with
|
||
failure if the input file does not exist.
|
||
stdin:
|
||
var=$(< non-existent)
|
||
expected-exit: e != 0
|
||
expected-stderr-pattern: /non-existent/
|
||
---
|
||
name: oksh-empty-for-list
|
||
description:
|
||
A for list which expands to zero items should not execute the body.
|
||
stdin:
|
||
set foo bar baz ; for out in ; do echo $out ; done
|
||
---
|
||
name: oksh-varfunction-mod1
|
||
description:
|
||
(Inspired by PR 2450 on OpenBSD.) Calling
|
||
FOO=bar f
|
||
where f is a ksh style function, should not set FOO in the current
|
||
env. If f is a Bourne style function, FOO should be set. Furthermore,
|
||
the function should receive a correct value of FOO. However, differing
|
||
from oksh, setting FOO in the function itself must change the value in
|
||
setting FOO in the function itself should not change the value in
|
||
global environment.
|
||
stdin:
|
||
print '#!'"$__progname"'\nunset RANDOM\nexport | while IFS= read -r' \
|
||
'RANDOM; do eval '\''print -r -- "$RANDOM=$'\''"$RANDOM"'\'\"\'\; \
|
||
done >env; chmod +x env; PATH=.$PATHSEP$PATH
|
||
function k {
|
||
if [ x$FOO != xbar ]; then
|
||
echo 1
|
||
return 1
|
||
fi
|
||
x=$(env | grep FOO)
|
||
if [ "x$x" != "xFOO=bar" ]; then
|
||
echo 2
|
||
return 1;
|
||
fi
|
||
FOO=foo
|
||
return 0
|
||
}
|
||
b () {
|
||
if [ x$FOO != xbar ]; then
|
||
echo 3
|
||
return 1
|
||
fi
|
||
x=$(env | grep FOO)
|
||
if [ "x$x" != "xFOO=bar" ]; then
|
||
echo 4
|
||
return 1;
|
||
fi
|
||
FOO=foo
|
||
return 0
|
||
}
|
||
FOO=bar k
|
||
if [ $? != 0 ]; then
|
||
exit 1
|
||
fi
|
||
if [ x$FOO != x ]; then
|
||
exit 1
|
||
fi
|
||
FOO=bar b
|
||
if [ $? != 0 ]; then
|
||
exit 1
|
||
fi
|
||
if [ x$FOO != xfoo ]; then
|
||
exit 1
|
||
fi
|
||
FOO=barbar
|
||
FOO=bar k
|
||
if [ $? != 0 ]; then
|
||
exit 1
|
||
fi
|
||
if [ x$FOO != xbarbar ]; then
|
||
exit 1
|
||
fi
|
||
FOO=bar b
|
||
if [ $? != 0 ]; then
|
||
exit 1
|
||
fi
|
||
if [ x$FOO != xfoo ]; then
|
||
exit 1
|
||
fi
|
||
---
|
||
name: fd-cloexec-1
|
||
description:
|
||
Verify that file descriptors > 2 are private for Korn shells
|
||
AT&T ksh93 does this still, which means we must keep it as well
|
||
XXX fails on some old Perl installations
|
||
need-pass: no
|
||
stdin:
|
||
cat >cld <<-EOF
|
||
#!$__perlname
|
||
open(my \$fh, ">&", 9) or die "E: open \$!";
|
||
syswrite(\$fh, "Fowl\\n", 5) or die "E: write \$!";
|
||
EOF
|
||
chmod +x cld
|
||
exec 9>&1
|
||
./cld
|
||
expected-exit: e != 0
|
||
expected-stderr-pattern:
|
||
/E: open /
|
||
---
|
||
name: fd-cloexec-2
|
||
description:
|
||
Verify that file descriptors > 2 are not private for POSIX shells
|
||
See Debian Bug #154540, Closes: #499139
|
||
XXX fails on some old Perl installations
|
||
need-pass: no
|
||
stdin:
|
||
cat >cld <<-EOF
|
||
#!$__perlname
|
||
open(my \$fh, ">&", 9) or die "E: open \$!";
|
||
syswrite(\$fh, "Fowl\\n", 5) or die "E: write \$!";
|
||
EOF
|
||
chmod +x cld
|
||
test -n "$POSH_VERSION" || set -o posix
|
||
exec 9>&1
|
||
./cld
|
||
expected-stdout:
|
||
Fowl
|
||
---
|
||
name: comsub-1a
|
||
description:
|
||
COMSUB are now parsed recursively, so this works
|
||
see also regression-6: matching parenthesēs bug
|
||
Fails on: pdksh bash2 bash3 zsh
|
||
Passes on: bash4 ksh93 mksh(20110313+)
|
||
stdin:
|
||
echo 1 $(case 1 in (1) echo yes;; (2) echo no;; esac) .
|
||
echo 2 $(case 1 in 1) echo yes;; 2) echo no;; esac) .
|
||
TEST=1234; echo 3 ${TEST: $(case 1 in (1) echo 1;; (*) echo 2;; esac)} .
|
||
TEST=5678; echo 4 ${TEST: $(case 1 in 1) echo 1;; *) echo 2;; esac)} .
|
||
a=($(case 1 in (1) echo 1;; (*) echo 2;; esac)); echo 5 ${a[0]} .
|
||
a=($(case 1 in 1) echo 1;; *) echo 2;; esac)); echo 6 ${a[0]} .
|
||
expected-stdout:
|
||
1 yes .
|
||
2 yes .
|
||
3 234 .
|
||
4 678 .
|
||
5 1 .
|
||
6 1 .
|
||
---
|
||
name: comsub-1b
|
||
description:
|
||
COMSUB are now parsed recursively, so this works
|
||
Fails on: pdksh bash2 bash3 bash4 zsh
|
||
Passes on: ksh93 mksh(20110313+)
|
||
stdin:
|
||
echo 1 $(($(case 1 in (1) echo 1;; (*) echo 2;; esac)+10)) .
|
||
echo 2 $(($(case 1 in 1) echo 1;; *) echo 2;; esac)+20)) .
|
||
(( a = $(case 1 in (1) echo 1;; (*) echo 2;; esac) )); echo 3 $a .
|
||
(( a = $(case 1 in 1) echo 1;; *) echo 2;; esac) )); echo 4 $a .
|
||
a=($(($(case 1 in (1) echo 1;; (*) echo 2;; esac)+10))); echo 5 ${a[0]} .
|
||
a=($(($(case 1 in 1) echo 1;; *) echo 2;; esac)+20))); echo 6 ${a[0]} .
|
||
expected-stdout:
|
||
1 11 .
|
||
2 21 .
|
||
3 1 .
|
||
4 1 .
|
||
5 11 .
|
||
6 21 .
|
||
---
|
||
name: comsub-2
|
||
description:
|
||
RedHat BZ#496791 – another case of missing recursion
|
||
in parsing COMSUB expressions
|
||
Fails on: pdksh bash2 bash3¹ bash4¹ zsh
|
||
Passes on: ksh93 mksh(20110305+)
|
||
① bash[34] seem to choke on comment ending with backslash-newline
|
||
stdin:
|
||
# a comment with " ' \
|
||
x=$(
|
||
echo yes
|
||
# a comment with " ' \
|
||
)
|
||
echo $x
|
||
expected-stdout:
|
||
yes
|
||
---
|
||
name: comsub-3
|
||
description:
|
||
Extended test for COMSUB explaining why a recursive parser
|
||
is a must (a non-recursive parser cannot pass all three of
|
||
these test cases, especially the ‘#’ is difficult)
|
||
stdin:
|
||
print '#!'"$__progname"'\necho 1234' >id; chmod +x id; PATH=.$PATHSEP$PATH
|
||
echo $(typeset -i10 x=16#20; echo $x)
|
||
echo $(typeset -Uui16 x=16#$(id -u)
|
||
) .
|
||
echo $(c=1; d=1
|
||
typeset -Uui16 a=36#foo; c=2
|
||
typeset -Uui16 b=36 #foo; d=2
|
||
echo $a $b $c $d)
|
||
expected-stdout:
|
||
32
|
||
.
|
||
16#4F68 16#24 2 1
|
||
---
|
||
name: comsub-4
|
||
description:
|
||
Check the tree dump functions for !MKSH_SMALL functionality
|
||
category: !smksh
|
||
stdin:
|
||
x() { case $1 in u) echo x ;;& *) echo $1 ;; esac; }
|
||
typeset -f x
|
||
expected-stdout:
|
||
x() {
|
||
case $1 in
|
||
(u)
|
||
\echo x
|
||
;|
|
||
(*)
|
||
\echo $1
|
||
;;
|
||
esac
|
||
}
|
||
---
|
||
name: comsub-5
|
||
description:
|
||
Check COMSUB works with aliases (does not expand them twice)
|
||
and reentrancy safety
|
||
stdin:
|
||
print '#!'"$__progname"'\nfor x in "$@"; do print -r -- "$x"; done' >pfn
|
||
chmod +x pfn
|
||
alias echo='echo a'
|
||
foo() {
|
||
echo moo
|
||
./pfn "$(echo foo)"
|
||
}
|
||
./pfn "$(echo b)"
|
||
typeset -f foo >x
|
||
cat x
|
||
foo
|
||
. ./x
|
||
typeset -f foo
|
||
foo
|
||
expected-stdout:
|
||
a b
|
||
foo() {
|
||
\echo a moo
|
||
./pfn "$(\echo a foo )"
|
||
}
|
||
a moo
|
||
a foo
|
||
foo() {
|
||
\echo a moo
|
||
./pfn "$(\echo a foo )"
|
||
}
|
||
a moo
|
||
a foo
|
||
---
|
||
name: comsub-torture
|
||
description:
|
||
Check the tree dump functions work correctly
|
||
stdin:
|
||
if [[ -z $__progname ]]; then echo >&2 call me with __progname; exit 1; fi
|
||
while IFS= read -r line; do
|
||
if [[ $line = '#1' ]]; then
|
||
lastf=0
|
||
continue
|
||
elif [[ $line = EOFN* ]]; then
|
||
fbody=$fbody$'\n'$line
|
||
continue
|
||
elif [[ $line != '#'* ]]; then
|
||
fbody=$fbody$'\n\t'$line
|
||
continue
|
||
fi
|
||
if (( lastf )); then
|
||
x="inline_${nextf}() {"$fbody$'\n}\n'
|
||
print -nr -- "$x"
|
||
print -r -- "${x}typeset -f inline_$nextf" | "$__progname"
|
||
x="function comsub_$nextf { x=\$("$fbody$'\n); }\n'
|
||
print -nr -- "$x"
|
||
print -r -- "${x}typeset -f comsub_$nextf" | "$__progname"
|
||
x="function reread_$nextf { x=\$(("$fbody$'\n)|tr u x); }\n'
|
||
print -nr -- "$x"
|
||
print -r -- "${x}typeset -f reread_$nextf" | "$__progname"
|
||
fi
|
||
lastf=1
|
||
fbody=
|
||
nextf=${line#?}
|
||
done <<'EOD'
|
||
#1
|
||
#TCOM
|
||
vara=1 varb='2 3' cmd arg1 $arg2 "$arg3 4"
|
||
#TPAREN_TPIPE_TLIST
|
||
(echo $foo | tr -dc 0-9; echo)
|
||
#TAND_TOR
|
||
cmd && echo ja || echo nein
|
||
#TSELECT
|
||
select file in *; do echo "<$file>" ; break ; done
|
||
#TFOR_TTIME
|
||
time for i in {1,2,3} ; do echo $i ; done
|
||
#TCASE
|
||
case $foo in 1) echo eins;& 2) echo zwei ;| *) echo kann net bis drei zählen;; esac
|
||
#TIF_TBANG_TDBRACKET_TELIF
|
||
if ! [[ 1 = 1 ]] ; then echo eins; elif [[ 1 = 2 ]]; then echo zwei ;else echo drei; fi
|
||
#TWHILE
|
||
i=1; while (( i < 10 )); do echo $i; let ++i; done
|
||
#TUNTIL
|
||
i=10; until (( !--i )) ; do echo $i; done
|
||
#TCOPROC
|
||
cat * |& ls
|
||
#TFUNCT_TBRACE_TASYNC
|
||
function korn { echo eins; echo zwei ; }
|
||
bourne () { logger * & }
|
||
#IOREAD_IOCAT
|
||
tr x u 0<foo >>bar
|
||
#IOWRITE_IOCLOB_IOHERE_noIOSKIP
|
||
cat >|bar <<'EOFN'
|
||
foo
|
||
EOFN
|
||
#IOWRITE_noIOCLOB_IOHERE_IOSKIP
|
||
cat 1>bar <<-EOFI
|
||
foo
|
||
EOFI
|
||
#IORDWR_IODUP
|
||
sh 1<>/dev/console 0<&1 2>&1
|
||
#COMSUB_EXPRSUB_FUNSUB_VALSUB
|
||
echo $(true) $((1+ 2)) ${ :;} ${| REPLY=x;}
|
||
#QCHAR_OQUOTE_CQUOTE
|
||
echo fo\ob\"a\`r\'b\$az
|
||
echo "fo\ob\"a\`r\'b\$az"
|
||
echo 'fo\ob\"a\`r'\''b\$az'
|
||
#OSUBST_CSUBST_OPAT_SPAT_CPAT
|
||
[[ ${foo#bl\(u\)b} = @(bar|baz) ]]
|
||
#heredoc_closed
|
||
x=$(cat <<EOFN
|
||
note there must be no space between EOFN and )
|
||
EOFN); echo $x
|
||
#heredoc_space
|
||
x=$(cat <<EOFN\
|
||
note the space between EOFN and ) is actually part of the here document marker
|
||
EOFN ); echo $x
|
||
#patch_motd
|
||
x=$(sysctl -n kern.version | sed 1q)
|
||
[[ -s /etc/motd && "$([[ "$(head -1 /etc/motd)" != $x ]] && \
|
||
ed -s /etc/motd 2>&1 <<-EOF
|
||
1,/^\$/d
|
||
0a
|
||
$x
|
||
|
||
.
|
||
wq
|
||
EOF)" = @(?) ]] && rm -f /etc/motd
|
||
if [[ ! -s /etc/motd ]]; then
|
||
install -c -o root -g wheel -m 664 /dev/null /etc/motd
|
||
print -- "$x\n" >/etc/motd
|
||
fi
|
||
#wdarrassign
|
||
case x in
|
||
x) a+=b; c+=(d e)
|
||
esac
|
||
#0
|
||
EOD
|
||
expected-stdout:
|
||
inline_TCOM() {
|
||
vara=1 varb='2 3' cmd arg1 $arg2 "$arg3 4"
|
||
}
|
||
inline_TCOM() {
|
||
vara=1 varb="2 3" \cmd arg1 $arg2 "$arg3 4"
|
||
}
|
||
function comsub_TCOM { x=$(
|
||
vara=1 varb='2 3' cmd arg1 $arg2 "$arg3 4"
|
||
); }
|
||
function comsub_TCOM {
|
||
x=$(vara=1 varb="2 3" \cmd arg1 $arg2 "$arg3 4" )
|
||
}
|
||
function reread_TCOM { x=$((
|
||
vara=1 varb='2 3' cmd arg1 $arg2 "$arg3 4"
|
||
)|tr u x); }
|
||
function reread_TCOM {
|
||
x=$( ( vara=1 varb="2 3" \cmd arg1 $arg2 "$arg3 4" ) | \tr u x )
|
||
}
|
||
inline_TPAREN_TPIPE_TLIST() {
|
||
(echo $foo | tr -dc 0-9; echo)
|
||
}
|
||
inline_TPAREN_TPIPE_TLIST() {
|
||
( \echo $foo | \tr -dc 0-9
|
||
\echo )
|
||
}
|
||
function comsub_TPAREN_TPIPE_TLIST { x=$(
|
||
(echo $foo | tr -dc 0-9; echo)
|
||
); }
|
||
function comsub_TPAREN_TPIPE_TLIST {
|
||
x=$( ( \echo $foo | \tr -dc 0-9 ; \echo ) )
|
||
}
|
||
function reread_TPAREN_TPIPE_TLIST { x=$((
|
||
(echo $foo | tr -dc 0-9; echo)
|
||
)|tr u x); }
|
||
function reread_TPAREN_TPIPE_TLIST {
|
||
x=$( ( ( \echo $foo | \tr -dc 0-9 ; \echo ) ) | \tr u x )
|
||
}
|
||
inline_TAND_TOR() {
|
||
cmd && echo ja || echo nein
|
||
}
|
||
inline_TAND_TOR() {
|
||
\cmd && \echo ja || \echo nein
|
||
}
|
||
function comsub_TAND_TOR { x=$(
|
||
cmd && echo ja || echo nein
|
||
); }
|
||
function comsub_TAND_TOR {
|
||
x=$(\cmd && \echo ja || \echo nein )
|
||
}
|
||
function reread_TAND_TOR { x=$((
|
||
cmd && echo ja || echo nein
|
||
)|tr u x); }
|
||
function reread_TAND_TOR {
|
||
x=$( ( \cmd && \echo ja || \echo nein ) | \tr u x )
|
||
}
|
||
inline_TSELECT() {
|
||
select file in *; do echo "<$file>" ; break ; done
|
||
}
|
||
inline_TSELECT() {
|
||
select file in *
|
||
do
|
||
\echo "<$file>"
|
||
\break
|
||
done
|
||
}
|
||
function comsub_TSELECT { x=$(
|
||
select file in *; do echo "<$file>" ; break ; done
|
||
); }
|
||
function comsub_TSELECT {
|
||
x=$(select file in * ; do \echo "<$file>" ; \break ; done )
|
||
}
|
||
function reread_TSELECT { x=$((
|
||
select file in *; do echo "<$file>" ; break ; done
|
||
)|tr u x); }
|
||
function reread_TSELECT {
|
||
x=$( ( select file in * ; do \echo "<$file>" ; \break ; done ) | \tr u x )
|
||
}
|
||
inline_TFOR_TTIME() {
|
||
time for i in {1,2,3} ; do echo $i ; done
|
||
}
|
||
inline_TFOR_TTIME() {
|
||
time for i in {1,2,3}
|
||
do
|
||
\echo $i
|
||
done
|
||
}
|
||
function comsub_TFOR_TTIME { x=$(
|
||
time for i in {1,2,3} ; do echo $i ; done
|
||
); }
|
||
function comsub_TFOR_TTIME {
|
||
x=$(time for i in {1,2,3} ; do \echo $i ; done )
|
||
}
|
||
function reread_TFOR_TTIME { x=$((
|
||
time for i in {1,2,3} ; do echo $i ; done
|
||
)|tr u x); }
|
||
function reread_TFOR_TTIME {
|
||
x=$( ( time for i in {1,2,3} ; do \echo $i ; done ) | \tr u x )
|
||
}
|
||
inline_TCASE() {
|
||
case $foo in 1) echo eins;& 2) echo zwei ;| *) echo kann net bis drei zählen;; esac
|
||
}
|
||
inline_TCASE() {
|
||
case $foo in
|
||
(1)
|
||
\echo eins
|
||
;&
|
||
(2)
|
||
\echo zwei
|
||
;|
|
||
(*)
|
||
\echo kann net bis drei zählen
|
||
;;
|
||
esac
|
||
}
|
||
function comsub_TCASE { x=$(
|
||
case $foo in 1) echo eins;& 2) echo zwei ;| *) echo kann net bis drei zählen;; esac
|
||
); }
|
||
function comsub_TCASE {
|
||
x=$(case $foo in (1) \echo eins ;& (2) \echo zwei ;| (*) \echo kann net bis drei zählen ;; esac )
|
||
}
|
||
function reread_TCASE { x=$((
|
||
case $foo in 1) echo eins;& 2) echo zwei ;| *) echo kann net bis drei zählen;; esac
|
||
)|tr u x); }
|
||
function reread_TCASE {
|
||
x=$( ( case $foo in (1) \echo eins ;& (2) \echo zwei ;| (*) \echo kann net bis drei zählen ;; esac ) | \tr u x )
|
||
}
|
||
inline_TIF_TBANG_TDBRACKET_TELIF() {
|
||
if ! [[ 1 = 1 ]] ; then echo eins; elif [[ 1 = 2 ]]; then echo zwei ;else echo drei; fi
|
||
}
|
||
inline_TIF_TBANG_TDBRACKET_TELIF() {
|
||
if ! [[ 1 = 1 ]]
|
||
then
|
||
\echo eins
|
||
elif [[ 1 = 2 ]]
|
||
then
|
||
\echo zwei
|
||
else
|
||
\echo drei
|
||
fi
|
||
}
|
||
function comsub_TIF_TBANG_TDBRACKET_TELIF { x=$(
|
||
if ! [[ 1 = 1 ]] ; then echo eins; elif [[ 1 = 2 ]]; then echo zwei ;else echo drei; fi
|
||
); }
|
||
function comsub_TIF_TBANG_TDBRACKET_TELIF {
|
||
x=$(if ! [[ 1 = 1 ]] ; then \echo eins ; elif [[ 1 = 2 ]] ; then \echo zwei ; else \echo drei ; fi )
|
||
}
|
||
function reread_TIF_TBANG_TDBRACKET_TELIF { x=$((
|
||
if ! [[ 1 = 1 ]] ; then echo eins; elif [[ 1 = 2 ]]; then echo zwei ;else echo drei; fi
|
||
)|tr u x); }
|
||
function reread_TIF_TBANG_TDBRACKET_TELIF {
|
||
x=$( ( if ! [[ 1 = 1 ]] ; then \echo eins ; elif [[ 1 = 2 ]] ; then \echo zwei ; else \echo drei ; fi ) | \tr u x )
|
||
}
|
||
inline_TWHILE() {
|
||
i=1; while (( i < 10 )); do echo $i; let ++i; done
|
||
}
|
||
inline_TWHILE() {
|
||
i=1
|
||
while {
|
||
\\builtin let " i < 10 "
|
||
}
|
||
do
|
||
\echo $i
|
||
\let ++i
|
||
done
|
||
}
|
||
function comsub_TWHILE { x=$(
|
||
i=1; while (( i < 10 )); do echo $i; let ++i; done
|
||
); }
|
||
function comsub_TWHILE {
|
||
x=$(i=1 ; while { \\builtin let " i < 10 " ; } ; do \echo $i ; \let ++i ; done )
|
||
}
|
||
function reread_TWHILE { x=$((
|
||
i=1; while (( i < 10 )); do echo $i; let ++i; done
|
||
)|tr u x); }
|
||
function reread_TWHILE {
|
||
x=$( ( i=1 ; while { \\builtin let " i < 10 " ; } ; do \echo $i ; \let ++i ; done ) | \tr u x )
|
||
}
|
||
inline_TUNTIL() {
|
||
i=10; until (( !--i )) ; do echo $i; done
|
||
}
|
||
inline_TUNTIL() {
|
||
i=10
|
||
until {
|
||
\\builtin let " !--i "
|
||
}
|
||
do
|
||
\echo $i
|
||
done
|
||
}
|
||
function comsub_TUNTIL { x=$(
|
||
i=10; until (( !--i )) ; do echo $i; done
|
||
); }
|
||
function comsub_TUNTIL {
|
||
x=$(i=10 ; until { \\builtin let " !--i " ; } ; do \echo $i ; done )
|
||
}
|
||
function reread_TUNTIL { x=$((
|
||
i=10; until (( !--i )) ; do echo $i; done
|
||
)|tr u x); }
|
||
function reread_TUNTIL {
|
||
x=$( ( i=10 ; until { \\builtin let " !--i " ; } ; do \echo $i ; done ) | \tr u x )
|
||
}
|
||
inline_TCOPROC() {
|
||
cat * |& ls
|
||
}
|
||
inline_TCOPROC() {
|
||
\cat * |&
|
||
\ls
|
||
}
|
||
function comsub_TCOPROC { x=$(
|
||
cat * |& ls
|
||
); }
|
||
function comsub_TCOPROC {
|
||
x=$(\cat * |& \ls )
|
||
}
|
||
function reread_TCOPROC { x=$((
|
||
cat * |& ls
|
||
)|tr u x); }
|
||
function reread_TCOPROC {
|
||
x=$( ( \cat * |& \ls ) | \tr u x )
|
||
}
|
||
inline_TFUNCT_TBRACE_TASYNC() {
|
||
function korn { echo eins; echo zwei ; }
|
||
bourne () { logger * & }
|
||
}
|
||
inline_TFUNCT_TBRACE_TASYNC() {
|
||
function korn {
|
||
\echo eins
|
||
\echo zwei
|
||
}
|
||
bourne() {
|
||
\logger * &
|
||
}
|
||
}
|
||
function comsub_TFUNCT_TBRACE_TASYNC { x=$(
|
||
function korn { echo eins; echo zwei ; }
|
||
bourne () { logger * & }
|
||
); }
|
||
function comsub_TFUNCT_TBRACE_TASYNC {
|
||
x=$(function korn { \echo eins ; \echo zwei ; } ; bourne() { \logger * & } )
|
||
}
|
||
function reread_TFUNCT_TBRACE_TASYNC { x=$((
|
||
function korn { echo eins; echo zwei ; }
|
||
bourne () { logger * & }
|
||
)|tr u x); }
|
||
function reread_TFUNCT_TBRACE_TASYNC {
|
||
x=$( ( function korn { \echo eins ; \echo zwei ; } ; bourne() { \logger * & } ) | \tr u x )
|
||
}
|
||
inline_IOREAD_IOCAT() {
|
||
tr x u 0<foo >>bar
|
||
}
|
||
inline_IOREAD_IOCAT() {
|
||
\tr x u <foo >>bar
|
||
}
|
||
function comsub_IOREAD_IOCAT { x=$(
|
||
tr x u 0<foo >>bar
|
||
); }
|
||
function comsub_IOREAD_IOCAT {
|
||
x=$(\tr x u <foo >>bar )
|
||
}
|
||
function reread_IOREAD_IOCAT { x=$((
|
||
tr x u 0<foo >>bar
|
||
)|tr u x); }
|
||
function reread_IOREAD_IOCAT {
|
||
x=$( ( \tr x u <foo >>bar ) | \tr u x )
|
||
}
|
||
inline_IOWRITE_IOCLOB_IOHERE_noIOSKIP() {
|
||
cat >|bar <<'EOFN'
|
||
foo
|
||
EOFN
|
||
}
|
||
inline_IOWRITE_IOCLOB_IOHERE_noIOSKIP() {
|
||
\cat >|bar <<"EOFN"
|
||
foo
|
||
EOFN
|
||
|
||
}
|
||
function comsub_IOWRITE_IOCLOB_IOHERE_noIOSKIP { x=$(
|
||
cat >|bar <<'EOFN'
|
||
foo
|
||
EOFN
|
||
); }
|
||
function comsub_IOWRITE_IOCLOB_IOHERE_noIOSKIP {
|
||
x=$(\cat >|bar <<"EOFN"
|
||
foo
|
||
EOFN
|
||
)
|
||
}
|
||
function reread_IOWRITE_IOCLOB_IOHERE_noIOSKIP { x=$((
|
||
cat >|bar <<'EOFN'
|
||
foo
|
||
EOFN
|
||
)|tr u x); }
|
||
function reread_IOWRITE_IOCLOB_IOHERE_noIOSKIP {
|
||
x=$( ( \cat >|bar <<"EOFN"
|
||
foo
|
||
EOFN
|
||
) | \tr u x )
|
||
}
|
||
inline_IOWRITE_noIOCLOB_IOHERE_IOSKIP() {
|
||
cat 1>bar <<-EOFI
|
||
foo
|
||
EOFI
|
||
}
|
||
inline_IOWRITE_noIOCLOB_IOHERE_IOSKIP() {
|
||
\cat >bar <<-EOFI
|
||
foo
|
||
EOFI
|
||
|
||
}
|
||
function comsub_IOWRITE_noIOCLOB_IOHERE_IOSKIP { x=$(
|
||
cat 1>bar <<-EOFI
|
||
foo
|
||
EOFI
|
||
); }
|
||
function comsub_IOWRITE_noIOCLOB_IOHERE_IOSKIP {
|
||
x=$(\cat >bar <<-EOFI
|
||
foo
|
||
EOFI
|
||
)
|
||
}
|
||
function reread_IOWRITE_noIOCLOB_IOHERE_IOSKIP { x=$((
|
||
cat 1>bar <<-EOFI
|
||
foo
|
||
EOFI
|
||
)|tr u x); }
|
||
function reread_IOWRITE_noIOCLOB_IOHERE_IOSKIP {
|
||
x=$( ( \cat >bar <<-EOFI
|
||
foo
|
||
EOFI
|
||
) | \tr u x )
|
||
}
|
||
inline_IORDWR_IODUP() {
|
||
sh 1<>/dev/console 0<&1 2>&1
|
||
}
|
||
inline_IORDWR_IODUP() {
|
||
\sh 1<>/dev/console <&1 2>&1
|
||
}
|
||
function comsub_IORDWR_IODUP { x=$(
|
||
sh 1<>/dev/console 0<&1 2>&1
|
||
); }
|
||
function comsub_IORDWR_IODUP {
|
||
x=$(\sh 1<>/dev/console <&1 2>&1 )
|
||
}
|
||
function reread_IORDWR_IODUP { x=$((
|
||
sh 1<>/dev/console 0<&1 2>&1
|
||
)|tr u x); }
|
||
function reread_IORDWR_IODUP {
|
||
x=$( ( \sh 1<>/dev/console <&1 2>&1 ) | \tr u x )
|
||
}
|
||
inline_COMSUB_EXPRSUB_FUNSUB_VALSUB() {
|
||
echo $(true) $((1+ 2)) ${ :;} ${| REPLY=x;}
|
||
}
|
||
inline_COMSUB_EXPRSUB_FUNSUB_VALSUB() {
|
||
\echo $(\true ) $((1+ 2)) ${ \: ;} ${|REPLY=x ;}
|
||
}
|
||
function comsub_COMSUB_EXPRSUB_FUNSUB_VALSUB { x=$(
|
||
echo $(true) $((1+ 2)) ${ :;} ${| REPLY=x;}
|
||
); }
|
||
function comsub_COMSUB_EXPRSUB_FUNSUB_VALSUB {
|
||
x=$(\echo $(\true ) $((1+ 2)) ${ \: ;} ${|REPLY=x ;} )
|
||
}
|
||
function reread_COMSUB_EXPRSUB_FUNSUB_VALSUB { x=$((
|
||
echo $(true) $((1+ 2)) ${ :;} ${| REPLY=x;}
|
||
)|tr u x); }
|
||
function reread_COMSUB_EXPRSUB_FUNSUB_VALSUB {
|
||
x=$( ( \echo $(\true ) $((1+ 2)) ${ \: ;} ${|REPLY=x ;} ) | \tr u x )
|
||
}
|
||
inline_QCHAR_OQUOTE_CQUOTE() {
|
||
echo fo\ob\"a\`r\'b\$az
|
||
echo "fo\ob\"a\`r\'b\$az"
|
||
echo 'fo\ob\"a\`r'\''b\$az'
|
||
}
|
||
inline_QCHAR_OQUOTE_CQUOTE() {
|
||
\echo fo\ob\"a\`r\'b\$az
|
||
\echo "fo\ob\"a\`r\'b\$az"
|
||
\echo "fo\\ob\\\"a\\\`r"\'"b\\\$az"
|
||
}
|
||
function comsub_QCHAR_OQUOTE_CQUOTE { x=$(
|
||
echo fo\ob\"a\`r\'b\$az
|
||
echo "fo\ob\"a\`r\'b\$az"
|
||
echo 'fo\ob\"a\`r'\''b\$az'
|
||
); }
|
||
function comsub_QCHAR_OQUOTE_CQUOTE {
|
||
x=$(\echo fo\ob\"a\`r\'b\$az ; \echo "fo\ob\"a\`r\'b\$az" ; \echo "fo\\ob\\\"a\\\`r"\'"b\\\$az" )
|
||
}
|
||
function reread_QCHAR_OQUOTE_CQUOTE { x=$((
|
||
echo fo\ob\"a\`r\'b\$az
|
||
echo "fo\ob\"a\`r\'b\$az"
|
||
echo 'fo\ob\"a\`r'\''b\$az'
|
||
)|tr u x); }
|
||
function reread_QCHAR_OQUOTE_CQUOTE {
|
||
x=$( ( \echo fo\ob\"a\`r\'b\$az ; \echo "fo\ob\"a\`r\'b\$az" ; \echo "fo\\ob\\\"a\\\`r"\'"b\\\$az" ) | \tr u x )
|
||
}
|
||
inline_OSUBST_CSUBST_OPAT_SPAT_CPAT() {
|
||
[[ ${foo#bl\(u\)b} = @(bar|baz) ]]
|
||
}
|
||
inline_OSUBST_CSUBST_OPAT_SPAT_CPAT() {
|
||
[[ ${foo#bl\(u\)b} = @(bar|baz) ]]
|
||
}
|
||
function comsub_OSUBST_CSUBST_OPAT_SPAT_CPAT { x=$(
|
||
[[ ${foo#bl\(u\)b} = @(bar|baz) ]]
|
||
); }
|
||
function comsub_OSUBST_CSUBST_OPAT_SPAT_CPAT {
|
||
x=$([[ ${foo#bl\(u\)b} = @(bar|baz) ]] )
|
||
}
|
||
function reread_OSUBST_CSUBST_OPAT_SPAT_CPAT { x=$((
|
||
[[ ${foo#bl\(u\)b} = @(bar|baz) ]]
|
||
)|tr u x); }
|
||
function reread_OSUBST_CSUBST_OPAT_SPAT_CPAT {
|
||
x=$( ( [[ ${foo#bl\(u\)b} = @(bar|baz) ]] ) | \tr u x )
|
||
}
|
||
inline_heredoc_closed() {
|
||
x=$(cat <<EOFN
|
||
note there must be no space between EOFN and )
|
||
EOFN); echo $x
|
||
}
|
||
inline_heredoc_closed() {
|
||
x=$(\cat <<EOFN
|
||
note there must be no space between EOFN and )
|
||
EOFN
|
||
)
|
||
\echo $x
|
||
}
|
||
function comsub_heredoc_closed { x=$(
|
||
x=$(cat <<EOFN
|
||
note there must be no space between EOFN and )
|
||
EOFN); echo $x
|
||
); }
|
||
function comsub_heredoc_closed {
|
||
x=$(x=$(\cat <<EOFN
|
||
note there must be no space between EOFN and )
|
||
EOFN
|
||
) ; \echo $x )
|
||
}
|
||
function reread_heredoc_closed { x=$((
|
||
x=$(cat <<EOFN
|
||
note there must be no space between EOFN and )
|
||
EOFN); echo $x
|
||
)|tr u x); }
|
||
function reread_heredoc_closed {
|
||
x=$( ( x=$(\cat <<EOFN
|
||
note there must be no space between EOFN and )
|
||
EOFN
|
||
) ; \echo $x ) | \tr u x )
|
||
}
|
||
inline_heredoc_space() {
|
||
x=$(cat <<EOFN\
|
||
note the space between EOFN and ) is actually part of the here document marker
|
||
EOFN ); echo $x
|
||
}
|
||
inline_heredoc_space() {
|
||
x=$(\cat <<EOFN\
|
||
note the space between EOFN and ) is actually part of the here document marker
|
||
EOFN
|
||
)
|
||
\echo $x
|
||
}
|
||
function comsub_heredoc_space { x=$(
|
||
x=$(cat <<EOFN\
|
||
note the space between EOFN and ) is actually part of the here document marker
|
||
EOFN ); echo $x
|
||
); }
|
||
function comsub_heredoc_space {
|
||
x=$(x=$(\cat <<EOFN\
|
||
note the space between EOFN and ) is actually part of the here document marker
|
||
EOFN
|
||
) ; \echo $x )
|
||
}
|
||
function reread_heredoc_space { x=$((
|
||
x=$(cat <<EOFN\
|
||
note the space between EOFN and ) is actually part of the here document marker
|
||
EOFN ); echo $x
|
||
)|tr u x); }
|
||
function reread_heredoc_space {
|
||
x=$( ( x=$(\cat <<EOFN\
|
||
note the space between EOFN and ) is actually part of the here document marker
|
||
EOFN
|
||
) ; \echo $x ) | \tr u x )
|
||
}
|
||
inline_patch_motd() {
|
||
x=$(sysctl -n kern.version | sed 1q)
|
||
[[ -s /etc/motd && "$([[ "$(head -1 /etc/motd)" != $x ]] && \
|
||
ed -s /etc/motd 2>&1 <<-EOF
|
||
1,/^\$/d
|
||
0a
|
||
$x
|
||
|
||
.
|
||
wq
|
||
EOF)" = @(?) ]] && rm -f /etc/motd
|
||
if [[ ! -s /etc/motd ]]; then
|
||
install -c -o root -g wheel -m 664 /dev/null /etc/motd
|
||
print -- "$x\n" >/etc/motd
|
||
fi
|
||
}
|
||
inline_patch_motd() {
|
||
x=$(\sysctl -n kern.version | \sed 1q )
|
||
[[ -s /etc/motd && "$([[ "$(\head -1 /etc/motd )" != $x ]] && \ed -s /etc/motd 2>&1 <<-EOF
|
||
1,/^\$/d
|
||
0a
|
||
$x
|
||
|
||
.
|
||
wq
|
||
EOF
|
||
)" = @(?) ]] && \rm -f /etc/motd
|
||
if [[ ! -s /etc/motd ]]
|
||
then
|
||
\install -c -o root -g wheel -m 664 /dev/null /etc/motd
|
||
\print -- "$x\n" >/etc/motd
|
||
fi
|
||
}
|
||
function comsub_patch_motd { x=$(
|
||
x=$(sysctl -n kern.version | sed 1q)
|
||
[[ -s /etc/motd && "$([[ "$(head -1 /etc/motd)" != $x ]] && \
|
||
ed -s /etc/motd 2>&1 <<-EOF
|
||
1,/^\$/d
|
||
0a
|
||
$x
|
||
|
||
.
|
||
wq
|
||
EOF)" = @(?) ]] && rm -f /etc/motd
|
||
if [[ ! -s /etc/motd ]]; then
|
||
install -c -o root -g wheel -m 664 /dev/null /etc/motd
|
||
print -- "$x\n" >/etc/motd
|
||
fi
|
||
); }
|
||
function comsub_patch_motd {
|
||
x=$(x=$(\sysctl -n kern.version | \sed 1q ) ; [[ -s /etc/motd && "$([[ "$(\head -1 /etc/motd )" != $x ]] && \ed -s /etc/motd 2>&1 <<-EOF
|
||
1,/^\$/d
|
||
0a
|
||
$x
|
||
|
||
.
|
||
wq
|
||
EOF
|
||
)" = @(?) ]] && \rm -f /etc/motd ; if [[ ! -s /etc/motd ]] ; then \install -c -o root -g wheel -m 664 /dev/null /etc/motd ; \print -- "$x\n" >/etc/motd ; fi )
|
||
}
|
||
function reread_patch_motd { x=$((
|
||
x=$(sysctl -n kern.version | sed 1q)
|
||
[[ -s /etc/motd && "$([[ "$(head -1 /etc/motd)" != $x ]] && \
|
||
ed -s /etc/motd 2>&1 <<-EOF
|
||
1,/^\$/d
|
||
0a
|
||
$x
|
||
|
||
.
|
||
wq
|
||
EOF)" = @(?) ]] && rm -f /etc/motd
|
||
if [[ ! -s /etc/motd ]]; then
|
||
install -c -o root -g wheel -m 664 /dev/null /etc/motd
|
||
print -- "$x\n" >/etc/motd
|
||
fi
|
||
)|tr u x); }
|
||
function reread_patch_motd {
|
||
x=$( ( x=$(\sysctl -n kern.version | \sed 1q ) ; [[ -s /etc/motd && "$([[ "$(\head -1 /etc/motd )" != $x ]] && \ed -s /etc/motd 2>&1 <<-EOF
|
||
1,/^\$/d
|
||
0a
|
||
$x
|
||
|
||
.
|
||
wq
|
||
EOF
|
||
)" = @(?) ]] && \rm -f /etc/motd ; if [[ ! -s /etc/motd ]] ; then \install -c -o root -g wheel -m 664 /dev/null /etc/motd ; \print -- "$x\n" >/etc/motd ; fi ) | \tr u x )
|
||
}
|
||
inline_wdarrassign() {
|
||
case x in
|
||
x) a+=b; c+=(d e)
|
||
esac
|
||
}
|
||
inline_wdarrassign() {
|
||
case x in
|
||
(x)
|
||
a+=b
|
||
\\builtin set -A c+ -- d e
|
||
;;
|
||
esac
|
||
}
|
||
function comsub_wdarrassign { x=$(
|
||
case x in
|
||
x) a+=b; c+=(d e)
|
||
esac
|
||
); }
|
||
function comsub_wdarrassign {
|
||
x=$(case x in (x) a+=b ; \\builtin set -A c+ -- d e ;; esac )
|
||
}
|
||
function reread_wdarrassign { x=$((
|
||
case x in
|
||
x) a+=b; c+=(d e)
|
||
esac
|
||
)|tr u x); }
|
||
function reread_wdarrassign {
|
||
x=$( ( case x in (x) a+=b ; \\builtin set -A c+ -- d e ;; esac ) | \tr u x )
|
||
}
|
||
---
|
||
name: comsub-torture-io
|
||
description:
|
||
Check the tree dump functions work correctly with I/O redirection
|
||
stdin:
|
||
if [[ -z $__progname ]]; then echo >&2 call me with __progname; exit 1; fi
|
||
while IFS= read -r line; do
|
||
if [[ $line = '#1' ]]; then
|
||
lastf=0
|
||
continue
|
||
elif [[ $line = EOFN* ]]; then
|
||
fbody=$fbody$'\n'$line
|
||
continue
|
||
elif [[ $line != '#'* ]]; then
|
||
fbody=$fbody$'\n\t'$line
|
||
continue
|
||
fi
|
||
if (( lastf )); then
|
||
x="inline_${nextf}() {"$fbody$'\n}\n'
|
||
print -nr -- "$x"
|
||
print -r -- "${x}typeset -f inline_$nextf" | "$__progname"
|
||
x="function comsub_$nextf { x=\$("$fbody$'\n); }\n'
|
||
print -nr -- "$x"
|
||
print -r -- "${x}typeset -f comsub_$nextf" | "$__progname"
|
||
x="function reread_$nextf { x=\$(("$fbody$'\n)|tr u x); }\n'
|
||
print -nr -- "$x"
|
||
print -r -- "${x}typeset -f reread_$nextf" | "$__progname"
|
||
fi
|
||
lastf=1
|
||
fbody=
|
||
nextf=${line#?}
|
||
done <<'EOD'
|
||
#1
|
||
#TCOM
|
||
vara=1 varb='2 3' cmd arg1 $arg2 "$arg3 4" >&3
|
||
#TPAREN_TPIPE_TLIST
|
||
(echo $foo | tr -dc 0-9 >&3; echo >&3) >&3
|
||
#TAND_TOR
|
||
cmd >&3 && >&3 echo ja || echo >&3 nein
|
||
#TSELECT
|
||
select file in *; do echo "<$file>" ; break >&3 ; done >&3
|
||
#TFOR_TTIME
|
||
for i in {1,2,3} ; do time >&3 echo $i ; done >&3
|
||
#TCASE
|
||
case $foo in 1) echo eins >&3;& 2) echo zwei >&3 ;| *) echo kann net bis drei zählen >&3;; esac >&3
|
||
#TIF_TBANG_TDBRACKET_TELIF
|
||
if ! [[ 1 = 1 ]] >&3 ; then echo eins; elif [[ 1 = 2 ]] >&3; then echo zwei ;else echo drei; fi >&3
|
||
#TWHILE
|
||
i=1; while (( i < 10 )) >&3; do echo $i; let ++i; done >&3
|
||
#TUNTIL
|
||
i=10; until (( !--i )) >&3 ; do echo $i; done >&3
|
||
#TCOPROC
|
||
cat * >&3 |& >&3 ls
|
||
#TFUNCT_TBRACE_TASYNC
|
||
function korn { echo eins; echo >&3 zwei ; }
|
||
bourne () { logger * >&3 & }
|
||
#COMSUB_EXPRSUB
|
||
echo $(true >&3) $((1+ 2))
|
||
#0
|
||
EOD
|
||
expected-stdout:
|
||
inline_TCOM() {
|
||
vara=1 varb='2 3' cmd arg1 $arg2 "$arg3 4" >&3
|
||
}
|
||
inline_TCOM() {
|
||
vara=1 varb="2 3" \cmd arg1 $arg2 "$arg3 4" >&3
|
||
}
|
||
function comsub_TCOM { x=$(
|
||
vara=1 varb='2 3' cmd arg1 $arg2 "$arg3 4" >&3
|
||
); }
|
||
function comsub_TCOM {
|
||
x=$(vara=1 varb="2 3" \cmd arg1 $arg2 "$arg3 4" >&3 )
|
||
}
|
||
function reread_TCOM { x=$((
|
||
vara=1 varb='2 3' cmd arg1 $arg2 "$arg3 4" >&3
|
||
)|tr u x); }
|
||
function reread_TCOM {
|
||
x=$( ( vara=1 varb="2 3" \cmd arg1 $arg2 "$arg3 4" >&3 ) | \tr u x )
|
||
}
|
||
inline_TPAREN_TPIPE_TLIST() {
|
||
(echo $foo | tr -dc 0-9 >&3; echo >&3) >&3
|
||
}
|
||
inline_TPAREN_TPIPE_TLIST() {
|
||
( \echo $foo | \tr -dc 0-9 >&3
|
||
\echo >&3 ) >&3
|
||
}
|
||
function comsub_TPAREN_TPIPE_TLIST { x=$(
|
||
(echo $foo | tr -dc 0-9 >&3; echo >&3) >&3
|
||
); }
|
||
function comsub_TPAREN_TPIPE_TLIST {
|
||
x=$( ( \echo $foo | \tr -dc 0-9 >&3 ; \echo >&3 ) >&3 )
|
||
}
|
||
function reread_TPAREN_TPIPE_TLIST { x=$((
|
||
(echo $foo | tr -dc 0-9 >&3; echo >&3) >&3
|
||
)|tr u x); }
|
||
function reread_TPAREN_TPIPE_TLIST {
|
||
x=$( ( ( \echo $foo | \tr -dc 0-9 >&3 ; \echo >&3 ) >&3 ) | \tr u x )
|
||
}
|
||
inline_TAND_TOR() {
|
||
cmd >&3 && >&3 echo ja || echo >&3 nein
|
||
}
|
||
inline_TAND_TOR() {
|
||
\cmd >&3 && \echo ja >&3 || \echo nein >&3
|
||
}
|
||
function comsub_TAND_TOR { x=$(
|
||
cmd >&3 && >&3 echo ja || echo >&3 nein
|
||
); }
|
||
function comsub_TAND_TOR {
|
||
x=$(\cmd >&3 && \echo ja >&3 || \echo nein >&3 )
|
||
}
|
||
function reread_TAND_TOR { x=$((
|
||
cmd >&3 && >&3 echo ja || echo >&3 nein
|
||
)|tr u x); }
|
||
function reread_TAND_TOR {
|
||
x=$( ( \cmd >&3 && \echo ja >&3 || \echo nein >&3 ) | \tr u x )
|
||
}
|
||
inline_TSELECT() {
|
||
select file in *; do echo "<$file>" ; break >&3 ; done >&3
|
||
}
|
||
inline_TSELECT() {
|
||
select file in *
|
||
do
|
||
\echo "<$file>"
|
||
\break >&3
|
||
done >&3
|
||
}
|
||
function comsub_TSELECT { x=$(
|
||
select file in *; do echo "<$file>" ; break >&3 ; done >&3
|
||
); }
|
||
function comsub_TSELECT {
|
||
x=$(select file in * ; do \echo "<$file>" ; \break >&3 ; done >&3 )
|
||
}
|
||
function reread_TSELECT { x=$((
|
||
select file in *; do echo "<$file>" ; break >&3 ; done >&3
|
||
)|tr u x); }
|
||
function reread_TSELECT {
|
||
x=$( ( select file in * ; do \echo "<$file>" ; \break >&3 ; done >&3 ) | \tr u x )
|
||
}
|
||
inline_TFOR_TTIME() {
|
||
for i in {1,2,3} ; do time >&3 echo $i ; done >&3
|
||
}
|
||
inline_TFOR_TTIME() {
|
||
for i in {1,2,3}
|
||
do
|
||
time \echo $i >&3
|
||
done >&3
|
||
}
|
||
function comsub_TFOR_TTIME { x=$(
|
||
for i in {1,2,3} ; do time >&3 echo $i ; done >&3
|
||
); }
|
||
function comsub_TFOR_TTIME {
|
||
x=$(for i in {1,2,3} ; do time \echo $i >&3 ; done >&3 )
|
||
}
|
||
function reread_TFOR_TTIME { x=$((
|
||
for i in {1,2,3} ; do time >&3 echo $i ; done >&3
|
||
)|tr u x); }
|
||
function reread_TFOR_TTIME {
|
||
x=$( ( for i in {1,2,3} ; do time \echo $i >&3 ; done >&3 ) | \tr u x )
|
||
}
|
||
inline_TCASE() {
|
||
case $foo in 1) echo eins >&3;& 2) echo zwei >&3 ;| *) echo kann net bis drei zählen >&3;; esac >&3
|
||
}
|
||
inline_TCASE() {
|
||
case $foo in
|
||
(1)
|
||
\echo eins >&3
|
||
;&
|
||
(2)
|
||
\echo zwei >&3
|
||
;|
|
||
(*)
|
||
\echo kann net bis drei zählen >&3
|
||
;;
|
||
esac >&3
|
||
}
|
||
function comsub_TCASE { x=$(
|
||
case $foo in 1) echo eins >&3;& 2) echo zwei >&3 ;| *) echo kann net bis drei zählen >&3;; esac >&3
|
||
); }
|
||
function comsub_TCASE {
|
||
x=$(case $foo in (1) \echo eins >&3 ;& (2) \echo zwei >&3 ;| (*) \echo kann net bis drei zählen >&3 ;; esac >&3 )
|
||
}
|
||
function reread_TCASE { x=$((
|
||
case $foo in 1) echo eins >&3;& 2) echo zwei >&3 ;| *) echo kann net bis drei zählen >&3;; esac >&3
|
||
)|tr u x); }
|
||
function reread_TCASE {
|
||
x=$( ( case $foo in (1) \echo eins >&3 ;& (2) \echo zwei >&3 ;| (*) \echo kann net bis drei zählen >&3 ;; esac >&3 ) | \tr u x )
|
||
}
|
||
inline_TIF_TBANG_TDBRACKET_TELIF() {
|
||
if ! [[ 1 = 1 ]] >&3 ; then echo eins; elif [[ 1 = 2 ]] >&3; then echo zwei ;else echo drei; fi >&3
|
||
}
|
||
inline_TIF_TBANG_TDBRACKET_TELIF() {
|
||
if ! [[ 1 = 1 ]] >&3
|
||
then
|
||
\echo eins
|
||
elif [[ 1 = 2 ]] >&3
|
||
then
|
||
\echo zwei
|
||
else
|
||
\echo drei
|
||
fi >&3
|
||
}
|
||
function comsub_TIF_TBANG_TDBRACKET_TELIF { x=$(
|
||
if ! [[ 1 = 1 ]] >&3 ; then echo eins; elif [[ 1 = 2 ]] >&3; then echo zwei ;else echo drei; fi >&3
|
||
); }
|
||
function comsub_TIF_TBANG_TDBRACKET_TELIF {
|
||
x=$(if ! [[ 1 = 1 ]] >&3 ; then \echo eins ; elif [[ 1 = 2 ]] >&3 ; then \echo zwei ; else \echo drei ; fi >&3 )
|
||
}
|
||
function reread_TIF_TBANG_TDBRACKET_TELIF { x=$((
|
||
if ! [[ 1 = 1 ]] >&3 ; then echo eins; elif [[ 1 = 2 ]] >&3; then echo zwei ;else echo drei; fi >&3
|
||
)|tr u x); }
|
||
function reread_TIF_TBANG_TDBRACKET_TELIF {
|
||
x=$( ( if ! [[ 1 = 1 ]] >&3 ; then \echo eins ; elif [[ 1 = 2 ]] >&3 ; then \echo zwei ; else \echo drei ; fi >&3 ) | \tr u x )
|
||
}
|
||
inline_TWHILE() {
|
||
i=1; while (( i < 10 )) >&3; do echo $i; let ++i; done >&3
|
||
}
|
||
inline_TWHILE() {
|
||
i=1
|
||
while {
|
||
\\builtin let " i < 10 "
|
||
} >&3
|
||
do
|
||
\echo $i
|
||
\let ++i
|
||
done >&3
|
||
}
|
||
function comsub_TWHILE { x=$(
|
||
i=1; while (( i < 10 )) >&3; do echo $i; let ++i; done >&3
|
||
); }
|
||
function comsub_TWHILE {
|
||
x=$(i=1 ; while { \\builtin let " i < 10 " ; } >&3 ; do \echo $i ; \let ++i ; done >&3 )
|
||
}
|
||
function reread_TWHILE { x=$((
|
||
i=1; while (( i < 10 )) >&3; do echo $i; let ++i; done >&3
|
||
)|tr u x); }
|
||
function reread_TWHILE {
|
||
x=$( ( i=1 ; while { \\builtin let " i < 10 " ; } >&3 ; do \echo $i ; \let ++i ; done >&3 ) | \tr u x )
|
||
}
|
||
inline_TUNTIL() {
|
||
i=10; until (( !--i )) >&3 ; do echo $i; done >&3
|
||
}
|
||
inline_TUNTIL() {
|
||
i=10
|
||
until {
|
||
\\builtin let " !--i "
|
||
} >&3
|
||
do
|
||
\echo $i
|
||
done >&3
|
||
}
|
||
function comsub_TUNTIL { x=$(
|
||
i=10; until (( !--i )) >&3 ; do echo $i; done >&3
|
||
); }
|
||
function comsub_TUNTIL {
|
||
x=$(i=10 ; until { \\builtin let " !--i " ; } >&3 ; do \echo $i ; done >&3 )
|
||
}
|
||
function reread_TUNTIL { x=$((
|
||
i=10; until (( !--i )) >&3 ; do echo $i; done >&3
|
||
)|tr u x); }
|
||
function reread_TUNTIL {
|
||
x=$( ( i=10 ; until { \\builtin let " !--i " ; } >&3 ; do \echo $i ; done >&3 ) | \tr u x )
|
||
}
|
||
inline_TCOPROC() {
|
||
cat * >&3 |& >&3 ls
|
||
}
|
||
inline_TCOPROC() {
|
||
\cat * >&3 |&
|
||
\ls >&3
|
||
}
|
||
function comsub_TCOPROC { x=$(
|
||
cat * >&3 |& >&3 ls
|
||
); }
|
||
function comsub_TCOPROC {
|
||
x=$(\cat * >&3 |& \ls >&3 )
|
||
}
|
||
function reread_TCOPROC { x=$((
|
||
cat * >&3 |& >&3 ls
|
||
)|tr u x); }
|
||
function reread_TCOPROC {
|
||
x=$( ( \cat * >&3 |& \ls >&3 ) | \tr u x )
|
||
}
|
||
inline_TFUNCT_TBRACE_TASYNC() {
|
||
function korn { echo eins; echo >&3 zwei ; }
|
||
bourne () { logger * >&3 & }
|
||
}
|
||
inline_TFUNCT_TBRACE_TASYNC() {
|
||
function korn {
|
||
\echo eins
|
||
\echo zwei >&3
|
||
}
|
||
bourne() {
|
||
\logger * >&3 &
|
||
}
|
||
}
|
||
function comsub_TFUNCT_TBRACE_TASYNC { x=$(
|
||
function korn { echo eins; echo >&3 zwei ; }
|
||
bourne () { logger * >&3 & }
|
||
); }
|
||
function comsub_TFUNCT_TBRACE_TASYNC {
|
||
x=$(function korn { \echo eins ; \echo zwei >&3 ; } ; bourne() { \logger * >&3 & } )
|
||
}
|
||
function reread_TFUNCT_TBRACE_TASYNC { x=$((
|
||
function korn { echo eins; echo >&3 zwei ; }
|
||
bourne () { logger * >&3 & }
|
||
)|tr u x); }
|
||
function reread_TFUNCT_TBRACE_TASYNC {
|
||
x=$( ( function korn { \echo eins ; \echo zwei >&3 ; } ; bourne() { \logger * >&3 & } ) | \tr u x )
|
||
}
|
||
inline_COMSUB_EXPRSUB() {
|
||
echo $(true >&3) $((1+ 2))
|
||
}
|
||
inline_COMSUB_EXPRSUB() {
|
||
\echo $(\true >&3 ) $((1+ 2))
|
||
}
|
||
function comsub_COMSUB_EXPRSUB { x=$(
|
||
echo $(true >&3) $((1+ 2))
|
||
); }
|
||
function comsub_COMSUB_EXPRSUB {
|
||
x=$(\echo $(\true >&3 ) $((1+ 2)) )
|
||
}
|
||
function reread_COMSUB_EXPRSUB { x=$((
|
||
echo $(true >&3) $((1+ 2))
|
||
)|tr u x); }
|
||
function reread_COMSUB_EXPRSUB {
|
||
x=$( ( \echo $(\true >&3 ) $((1+ 2)) ) | \tr u x )
|
||
}
|
||
---
|
||
name: funsub-1
|
||
description:
|
||
Check that non-subenvironment command substitution works
|
||
stdin:
|
||
set -e
|
||
foo=bar
|
||
echo "ob $foo ."
|
||
echo "${
|
||
echo "ib $foo :"
|
||
foo=baz
|
||
echo "ia $foo :"
|
||
false
|
||
}" .
|
||
echo "oa $foo ."
|
||
expected-stdout:
|
||
ob bar .
|
||
ib bar :
|
||
ia baz : .
|
||
oa baz .
|
||
---
|
||
name: funsub-2
|
||
description:
|
||
You can now reliably use local and return in funsubs
|
||
(not exit though)
|
||
stdin:
|
||
x=q; e=1; x=${ echo a; e=2; echo x$e;}; echo 1:y$x,$e,$?.
|
||
x=q; e=1; x=${ echo a; typeset e=2; echo x$e;}; echo 2:y$x,$e,$?.
|
||
x=q; e=1; x=${ echo a; typeset e=2; return 3; echo x$e;}; echo 3:y$x,$e,$?.
|
||
expected-stdout:
|
||
1:ya x2,2,0.
|
||
2:ya x2,1,0.
|
||
3:ya,1,3.
|
||
---
|
||
name: valsub-1
|
||
description:
|
||
Check that "value substitutions" work as advertised
|
||
stdin:
|
||
x=1
|
||
y=2
|
||
z=3
|
||
REPLY=4
|
||
echo "before: x<$x> y<$y> z<$z> R<$REPLY>"
|
||
x=${|
|
||
local y
|
||
echo "start: x<$x> y<$y> z<$z> R<$REPLY>"
|
||
x=5
|
||
y=6
|
||
z=7
|
||
REPLY=8
|
||
echo "end: x<$x> y<$y> z<$z> R<$REPLY>"
|
||
}
|
||
echo "after: x<$x> y<$y> z<$z> R<$REPLY>"
|
||
# ensure trailing newlines are kept
|
||
t=${|REPLY=$'foo\n\n';}
|
||
typeset -p t
|
||
echo -n this used to segfault
|
||
echo ${|true;}$(true).
|
||
expected-stdout:
|
||
before: x<1> y<2> z<3> R<4>
|
||
start: x<1> y<> z<3> R<>
|
||
end: x<5> y<6> z<7> R<8>
|
||
after: x<8> y<2> z<7> R<4>
|
||
typeset t=$'foo\n\n'
|
||
this used to segfault.
|
||
---
|
||
name: event-subst-3
|
||
description:
|
||
Check that '!' substitution in noninteractive mode is ignored
|
||
file-setup: file 755 "falsetto"
|
||
#! /bin/sh
|
||
echo molto bene
|
||
exit 42
|
||
file-setup: file 755 "!false"
|
||
#! /bin/sh
|
||
echo si
|
||
stdin:
|
||
export PATH=.$PATHSEP$PATH
|
||
falsetto
|
||
echo yeap
|
||
!false
|
||
echo meow
|
||
! false
|
||
echo = $?
|
||
if
|
||
! false; then echo foo; else echo bar; fi
|
||
expected-stdout:
|
||
molto bene
|
||
yeap
|
||
si
|
||
meow
|
||
= 0
|
||
foo
|
||
---
|
||
name: event-subst-0
|
||
description:
|
||
Check that '!' substitution in interactive mode is ignored
|
||
need-ctty: yes
|
||
arguments: !-i!
|
||
file-setup: file 755 "falsetto"
|
||
#! /bin/sh
|
||
echo molto bene
|
||
exit 42
|
||
file-setup: file 755 "!false"
|
||
#! /bin/sh
|
||
echo si
|
||
stdin:
|
||
export PATH=.$PATHSEP$PATH
|
||
falsetto
|
||
echo yeap
|
||
!false
|
||
echo meow
|
||
! false
|
||
echo = $?
|
||
if
|
||
! false; then echo foo; else echo bar; fi
|
||
expected-stdout:
|
||
molto bene
|
||
yeap
|
||
si
|
||
meow
|
||
= 0
|
||
foo
|
||
expected-stderr-pattern:
|
||
/.*/
|
||
---
|
||
name: nounset-1
|
||
description:
|
||
Check that "set -u" matches (future) SUSv4 requirement
|
||
stdin:
|
||
(set -u
|
||
try() {
|
||
local v
|
||
eval v=\$$1
|
||
if [[ -n $v ]]; then
|
||
echo $1=nz
|
||
else
|
||
echo $1=zf
|
||
fi
|
||
}
|
||
x=y
|
||
(echo $x)
|
||
echo =1
|
||
(echo $y)
|
||
echo =2
|
||
(try x)
|
||
echo =3
|
||
(try y)
|
||
echo =4
|
||
(try 0)
|
||
echo =5
|
||
(try 2)
|
||
echo =6
|
||
(try)
|
||
echo =7
|
||
(echo at=$@)
|
||
echo =8
|
||
(echo asterisk=$*)
|
||
echo =9
|
||
(echo $?)
|
||
echo =10
|
||
(echo $!)
|
||
echo =11
|
||
(echo $-)
|
||
echo =12
|
||
#(echo $_)
|
||
#echo =13
|
||
(echo $#)
|
||
echo =14
|
||
(mypid=$$; try mypid)
|
||
echo =15
|
||
) 2>&1 | sed -e 's/^[^]]*]//' -e 's/^[^:]*: *//'
|
||
exit ${PIPESTATUS[0]}
|
||
expected-stdout:
|
||
y
|
||
=1
|
||
y: parameter not set
|
||
=2
|
||
x=nz
|
||
=3
|
||
y: parameter not set
|
||
=4
|
||
0=nz
|
||
=5
|
||
2: parameter not set
|
||
=6
|
||
1: parameter not set
|
||
=7
|
||
at=
|
||
=8
|
||
asterisk=
|
||
=9
|
||
0
|
||
=10
|
||
!: parameter not set
|
||
=11
|
||
ush
|
||
=12
|
||
0
|
||
=14
|
||
mypid=nz
|
||
=15
|
||
---
|
||
name: nameref-1
|
||
description:
|
||
Testsuite for nameref (bound variables)
|
||
stdin:
|
||
bar=global
|
||
typeset -n ir2=bar
|
||
typeset -n ind=ir2
|
||
echo !ind: ${!ind}
|
||
echo ind: $ind
|
||
echo !ir2: ${!ir2}
|
||
echo ir2: $ir2
|
||
typeset +n ind
|
||
echo !ind: ${!ind}
|
||
echo ind: $ind
|
||
typeset -n ir2=ind
|
||
echo !ir2: ${!ir2}
|
||
echo ir2: $ir2
|
||
set|grep ^ir2|sed 's/^/s1: /'
|
||
typeset|grep ' ir2'|sed -e 's/^/s2: /' -e 's/nameref/typeset -n/'
|
||
set -A blub -- e1 e2 e3
|
||
typeset -n ind=blub
|
||
typeset -n ir2=blub[2]
|
||
echo !ind[1]: ${!ind[1]}
|
||
echo !ir2: $!ir2
|
||
echo ind[1]: ${ind[1]}
|
||
echo ir2: $ir2
|
||
expected-stdout:
|
||
!ind: bar
|
||
ind: global
|
||
!ir2: bar
|
||
ir2: global
|
||
!ind: ind
|
||
ind: ir2
|
||
!ir2: ind
|
||
ir2: ir2
|
||
s1: ir2=ind
|
||
s2: typeset -n ir2
|
||
!ind[1]: blub[1]
|
||
!ir2: ir2
|
||
ind[1]: e2
|
||
ir2: e3
|
||
---
|
||
name: nameref-2da
|
||
description:
|
||
Testsuite for nameref (bound variables)
|
||
Functions, argument given directly, after local
|
||
stdin:
|
||
function foo {
|
||
typeset bar=lokal baz=auch
|
||
typeset -n v=bar
|
||
echo entering
|
||
echo !v: ${!v}
|
||
echo !bar: ${!bar}
|
||
echo !baz: ${!baz}
|
||
echo bar: $bar
|
||
echo v: $v
|
||
v=123
|
||
echo bar: $bar
|
||
echo v: $v
|
||
echo exiting
|
||
}
|
||
bar=global
|
||
echo bar: $bar
|
||
foo bar
|
||
echo bar: $bar
|
||
expected-stdout:
|
||
bar: global
|
||
entering
|
||
!v: bar
|
||
!bar: bar
|
||
!baz: baz
|
||
bar: lokal
|
||
v: lokal
|
||
bar: 123
|
||
v: 123
|
||
exiting
|
||
bar: global
|
||
---
|
||
name: nameref-3
|
||
description:
|
||
Advanced testsuite for bound variables (ksh93 fails this)
|
||
stdin:
|
||
typeset -n foo=bar[i]
|
||
set -A bar -- b c a
|
||
for i in 0 1 2 3; do
|
||
print $i $foo .
|
||
done
|
||
expected-stdout:
|
||
0 b .
|
||
1 c .
|
||
2 a .
|
||
3 .
|
||
---
|
||
name: nameref-4
|
||
description:
|
||
Ensure we don't run in an infinite loop
|
||
time-limit: 3
|
||
stdin:
|
||
baz() {
|
||
typeset -n foo=fnord fnord=foo
|
||
foo[0]=bar
|
||
}
|
||
set -A foo bad
|
||
echo sind $foo .
|
||
baz
|
||
echo blah $foo .
|
||
expected-stdout:
|
||
sind bad .
|
||
blah bad .
|
||
expected-stderr-pattern:
|
||
/fnord: expression recurses on parameter/
|
||
---
|
||
name: better-parens-1a
|
||
description:
|
||
Check support for ((…)) and $((…)) vs (…) and $(…)
|
||
stdin:
|
||
if ( (echo fubar)|tr u x); then
|
||
echo ja
|
||
else
|
||
echo nein
|
||
fi
|
||
expected-stdout:
|
||
fxbar
|
||
ja
|
||
---
|
||
name: better-parens-1b
|
||
description:
|
||
Check support for ((…)) and $((…)) vs (…) and $(…)
|
||
stdin:
|
||
echo $( (echo fubar)|tr u x) $?
|
||
expected-stdout:
|
||
fxbar 0
|
||
---
|
||
name: better-parens-1c
|
||
description:
|
||
Check support for ((…)) and $((…)) vs (…) and $(…)
|
||
stdin:
|
||
x=$( (echo fubar)|tr u x); echo $x $?
|
||
expected-stdout:
|
||
fxbar 0
|
||
---
|
||
name: better-parens-2a
|
||
description:
|
||
Check support for ((…)) and $((…)) vs (…) and $(…)
|
||
stdin:
|
||
if ((echo fubar)|tr u x); then
|
||
echo ja
|
||
else
|
||
echo nein
|
||
fi
|
||
expected-stdout:
|
||
fxbar
|
||
ja
|
||
---
|
||
name: better-parens-2b
|
||
description:
|
||
Check support for ((…)) and $((…)) vs (…) and $(…)
|
||
stdin:
|
||
echo $((echo fubar)|tr u x) $?
|
||
expected-stdout:
|
||
fxbar 0
|
||
---
|
||
name: better-parens-2c
|
||
description:
|
||
Check support for ((…)) and $((…)) vs (…) and $(…)
|
||
stdin:
|
||
x=$((echo fubar)|tr u x); echo $x $?
|
||
expected-stdout:
|
||
fxbar 0
|
||
---
|
||
name: better-parens-3a
|
||
description:
|
||
Check support for ((…)) and $((…)) vs (…) and $(…)
|
||
stdin:
|
||
if ( (echo fubar)|(tr u x)); then
|
||
echo ja
|
||
else
|
||
echo nein
|
||
fi
|
||
expected-stdout:
|
||
fxbar
|
||
ja
|
||
---
|
||
name: better-parens-3b
|
||
description:
|
||
Check support for ((…)) and $((…)) vs (…) and $(…)
|
||
stdin:
|
||
echo $( (echo fubar)|(tr u x)) $?
|
||
expected-stdout:
|
||
fxbar 0
|
||
---
|
||
name: better-parens-3c
|
||
description:
|
||
Check support for ((…)) and $((…)) vs (…) and $(…)
|
||
stdin:
|
||
x=$( (echo fubar)|(tr u x)); echo $x $?
|
||
expected-stdout:
|
||
fxbar 0
|
||
---
|
||
name: better-parens-4a
|
||
description:
|
||
Check support for ((…)) and $((…)) vs (…) and $(…)
|
||
stdin:
|
||
if ((echo fubar)|(tr u x)); then
|
||
echo ja
|
||
else
|
||
echo nein
|
||
fi
|
||
expected-stdout:
|
||
fxbar
|
||
ja
|
||
---
|
||
name: better-parens-4b
|
||
description:
|
||
Check support for ((…)) and $((…)) vs (…) and $(…)
|
||
stdin:
|
||
echo $((echo fubar)|(tr u x)) $?
|
||
expected-stdout:
|
||
fxbar 0
|
||
---
|
||
name: better-parens-4c
|
||
description:
|
||
Check support for ((…)) and $((…)) vs (…) and $(…)
|
||
stdin:
|
||
x=$((echo fubar)|(tr u x)); echo $x $?
|
||
expected-stdout:
|
||
fxbar 0
|
||
---
|
||
name: better-parens-5
|
||
description:
|
||
Another corner case
|
||
stdin:
|
||
( (echo 'fo o$bar' "baz\$bla\"" m\$eh) | tr a A)
|
||
((echo 'fo o$bar' "baz\$bla\"" m\$eh) | tr a A)
|
||
expected-stdout:
|
||
fo o$bAr bAz$blA" m$eh
|
||
fo o$bAr bAz$blA" m$eh
|
||
---
|
||
name: echo-test-1
|
||
description:
|
||
Test what the echo builtin does (mksh)
|
||
category: !shell:ebcdic-yes
|
||
stdin:
|
||
echo -n 'foo\x40bar'
|
||
echo -e '\tbaz'
|
||
expected-stdout:
|
||
foo@bar baz
|
||
---
|
||
name: echo-test-1-ebcdic
|
||
description:
|
||
Test what the echo builtin does (mksh)
|
||
category: !shell:ebcdic-no
|
||
stdin:
|
||
echo -n 'foo\x7Cbar'
|
||
echo -e '\tbaz'
|
||
expected-stdout:
|
||
foo@bar baz
|
||
---
|
||
name: echo-test-2
|
||
description:
|
||
Test what the echo builtin does (POSIX)
|
||
Note: this follows Debian Policy 10.4 which mandates
|
||
that -n shall be treated as an option, not XSI which
|
||
mandates it shall be treated as string but escapes
|
||
shall be expanded.
|
||
stdin:
|
||
test -n "$POSH_VERSION" || set -o posix
|
||
echo -n 'foo\x40bar'
|
||
echo -e '\tbaz'
|
||
expected-stdout:
|
||
foo\x40bar-e \tbaz
|
||
---
|
||
name: echo-test-3-mnbsd
|
||
description:
|
||
Test what the echo builtin does, and test a compatibility flag.
|
||
category: mnbsdash
|
||
stdin:
|
||
"$__progname" -c 'echo -n 1=\\x40$1; echo -e \\x2E' -- foo bar
|
||
"$__progname" -o posix -c 'echo -n 2=\\x40$1; echo -e \\x2E' -- foo bar
|
||
"$__progname" -o sh -c 'echo -n 3=\\x40$1; echo -e \\x2E' -- foo bar
|
||
expected-stdout:
|
||
1=@foo.
|
||
2=\x40foo-e \x2E
|
||
3=\x40bar.
|
||
---
|
||
name: echo-test-3-normal
|
||
description:
|
||
Test what the echo builtin does, and test a compatibility flag.
|
||
category: !mnbsdash,!shell:ebcdic-yes
|
||
stdin:
|
||
"$__progname" -c 'echo -n 1=\\x40$1; echo -e \\x2E' -- foo bar
|
||
"$__progname" -o posix -c 'echo -n 2=\\x40$1; echo -e \\x2E' -- foo bar
|
||
"$__progname" -o sh -c 'echo -n 3=\\x40$1; echo -e \\x2E' -- foo bar
|
||
expected-stdout:
|
||
1=@foo.
|
||
2=\x40foo-e \x2E
|
||
3=\x40foo-e \x2E
|
||
---
|
||
name: echo-test-3-ebcdic
|
||
description:
|
||
Test what the echo builtin does, and test a compatibility flag.
|
||
category: !mnbsdash,!shell:ebcdic-no
|
||
stdin:
|
||
"$__progname" -c 'echo -n 1=\\x7C$1; echo -e \\x4B' -- foo bar
|
||
"$__progname" -o posix -c 'echo -n 2=\\x7C$1; echo -e \\x4B' -- foo bar
|
||
"$__progname" -o sh -c 'echo -n 3=\\x7C$1; echo -e \\x4B' -- foo bar
|
||
expected-stdout:
|
||
1=@foo.
|
||
2=\x7Cfoo-e \x4B
|
||
3=\x7Cfoo-e \x4B
|
||
---
|
||
name: utilities-getopts-1
|
||
description:
|
||
getopts sets OPTIND correctly for unparsed option
|
||
stdin:
|
||
set -- -a -a -x
|
||
while getopts :a optc; do
|
||
echo "OPTARG=$OPTARG, OPTIND=$OPTIND, optc=$optc."
|
||
done
|
||
echo done
|
||
expected-stdout:
|
||
OPTARG=, OPTIND=2, optc=a.
|
||
OPTARG=, OPTIND=3, optc=a.
|
||
OPTARG=x, OPTIND=4, optc=?.
|
||
done
|
||
---
|
||
name: utilities-getopts-2
|
||
description:
|
||
Check OPTARG
|
||
stdin:
|
||
set -- -a Mary -x
|
||
while getopts a: optc; do
|
||
echo "OPTARG=$OPTARG, OPTIND=$OPTIND, optc=$optc."
|
||
done
|
||
echo done
|
||
expected-stdout:
|
||
OPTARG=Mary, OPTIND=3, optc=a.
|
||
OPTARG=, OPTIND=4, optc=?.
|
||
done
|
||
expected-stderr-pattern: /.*-x.*option/
|
||
---
|
||
name: utilities-getopts-3
|
||
description:
|
||
Check unsetting OPTARG
|
||
stdin:
|
||
set -- -x arg -y
|
||
getopts x:y opt && echo "${OPTARG-unset}"
|
||
getopts x:y opt && echo "${OPTARG-unset}"
|
||
expected-stdout:
|
||
arg
|
||
unset
|
||
---
|
||
name: wcswidth-1
|
||
description:
|
||
Check the new wcswidth feature
|
||
stdin:
|
||
s=何
|
||
set +U
|
||
print octets: ${#s} .
|
||
print 8-bit width: ${%s} .
|
||
set -U
|
||
print characters: ${#s} .
|
||
print columns: ${%s} .
|
||
s=<3D>
|
||
set +U
|
||
print octets: ${#s} .
|
||
print 8-bit width: ${%s} .
|
||
set -U
|
||
print characters: ${#s} .
|
||
print columns: ${%s} .
|
||
expected-stdout:
|
||
octets: 3 .
|
||
8-bit width: -1 .
|
||
characters: 1 .
|
||
columns: 2 .
|
||
octets: 3 .
|
||
8-bit width: 3 .
|
||
characters: 1 .
|
||
columns: 1 .
|
||
---
|
||
name: wcswidth-2
|
||
description:
|
||
Check some corner cases
|
||
stdin:
|
||
print % $% .
|
||
set -U
|
||
x='a b'
|
||
print c ${%x} .
|
||
set +U
|
||
x='a b'
|
||
print d ${%x} .
|
||
expected-stdout:
|
||
% $% .
|
||
c -1 .
|
||
d -1 .
|
||
---
|
||
name: wcswidth-3
|
||
description:
|
||
Check some corner cases
|
||
stdin:
|
||
print ${%} .
|
||
expected-stderr-pattern:
|
||
/bad substitution/
|
||
expected-exit: 1
|
||
---
|
||
name: wcswidth-4a
|
||
description:
|
||
Check some corner cases
|
||
stdin:
|
||
print ${%*} .
|
||
expected-stderr-pattern:
|
||
/bad substitution/
|
||
expected-exit: 1
|
||
---
|
||
name: wcswidth-4b
|
||
description:
|
||
Check some corner cases
|
||
stdin:
|
||
print ${%@} .
|
||
expected-stderr-pattern:
|
||
/bad substitution/
|
||
expected-exit: 1
|
||
---
|
||
name: wcswidth-4c
|
||
description:
|
||
Check some corner cases
|
||
stdin:
|
||
:
|
||
print ${%?} .
|
||
expected-stdout:
|
||
1 .
|
||
---
|
||
name: realpath-1
|
||
description:
|
||
Check proper return values for realpath
|
||
category: os:mirbsd
|
||
stdin:
|
||
wd=$(realpath .)
|
||
mkdir dir
|
||
:>file
|
||
:>dir/file
|
||
ln -s dir lndir
|
||
ln -s file lnfile
|
||
ln -s nix lnnix
|
||
ln -s . lnself
|
||
i=0
|
||
chk() {
|
||
typeset x y
|
||
x=$(realpath "$wd/$1" 2>&1); y=$?
|
||
print $((++i)) "?$1" =${x##*$wd/} !$y
|
||
}
|
||
chk dir
|
||
chk dir/
|
||
chk dir/file
|
||
chk dir/nix
|
||
chk file
|
||
chk file/
|
||
chk file/file
|
||
chk file/nix
|
||
chk nix
|
||
chk nix/
|
||
chk nix/file
|
||
chk nix/nix
|
||
chk lndir
|
||
chk lndir/
|
||
chk lndir/file
|
||
chk lndir/nix
|
||
chk lnfile
|
||
chk lnfile/
|
||
chk lnfile/file
|
||
chk lnfile/nix
|
||
chk lnnix
|
||
chk lnnix/
|
||
chk lnnix/file
|
||
chk lnnix/nix
|
||
chk lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself
|
||
rm lnself
|
||
expected-stdout:
|
||
1 ?dir =dir !0
|
||
2 ?dir/ =dir !0
|
||
3 ?dir/file =dir/file !0
|
||
4 ?dir/nix =dir/nix !0
|
||
5 ?file =file !0
|
||
6 ?file/ =file/: Not a directory !20
|
||
7 ?file/file =file/file: Not a directory !20
|
||
8 ?file/nix =file/nix: Not a directory !20
|
||
9 ?nix =nix !0
|
||
10 ?nix/ =nix !0
|
||
11 ?nix/file =nix/file: No such file or directory !2
|
||
12 ?nix/nix =nix/nix: No such file or directory !2
|
||
13 ?lndir =dir !0
|
||
14 ?lndir/ =dir !0
|
||
15 ?lndir/file =dir/file !0
|
||
16 ?lndir/nix =dir/nix !0
|
||
17 ?lnfile =file !0
|
||
18 ?lnfile/ =lnfile/: Not a directory !20
|
||
19 ?lnfile/file =lnfile/file: Not a directory !20
|
||
20 ?lnfile/nix =lnfile/nix: Not a directory !20
|
||
21 ?lnnix =nix !0
|
||
22 ?lnnix/ =nix !0
|
||
23 ?lnnix/file =lnnix/file: No such file or directory !2
|
||
24 ?lnnix/nix =lnnix/nix: No such file or directory !2
|
||
25 ?lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself =lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself/lnself: Too many levels of symbolic links !62
|
||
---
|
||
name: realpath-2
|
||
description:
|
||
Ensure that exactly two leading slashes are not collapsed
|
||
POSIX guarantees this exception, e.g. for UNC paths on Cygwin
|
||
category: os:mirbsd
|
||
stdin:
|
||
ln -s /bin t1
|
||
ln -s //bin t2
|
||
ln -s ///bin t3
|
||
realpath /bin
|
||
realpath //bin
|
||
realpath ///bin
|
||
realpath /usr/bin
|
||
realpath /usr//bin
|
||
realpath /usr///bin
|
||
realpath t1
|
||
realpath t2
|
||
realpath t3
|
||
rm -f t1 t2 t3
|
||
cd //usr/bin
|
||
pwd
|
||
cd ../lib
|
||
pwd
|
||
realpath //usr/include/../bin
|
||
expected-stdout:
|
||
/bin
|
||
//bin
|
||
/bin
|
||
/usr/bin
|
||
/usr/bin
|
||
/usr/bin
|
||
/bin
|
||
//bin
|
||
/bin
|
||
//usr/bin
|
||
//usr/lib
|
||
//usr/bin
|
||
---
|
||
name: crash-1
|
||
description:
|
||
Crashed during March 2011, fixed on vernal equinōx ☺
|
||
category: os:mirbsd,os:openbsd
|
||
stdin:
|
||
export MALLOC_OPTIONS=FGJPRSX
|
||
"$__progname" -c 'x=$(tr z r <<<baz); echo $x'
|
||
expected-stdout:
|
||
bar
|
||
---
|
||
name: debian-117-1
|
||
description:
|
||
Check test - bug#465250
|
||
stdin:
|
||
test \( ! -e \) ; echo $?
|
||
expected-stdout:
|
||
1
|
||
---
|
||
name: debian-117-2
|
||
description:
|
||
Check test - bug#465250
|
||
stdin:
|
||
test \( -e \) ; echo $?
|
||
expected-stdout:
|
||
0
|
||
---
|
||
name: debian-117-3
|
||
description:
|
||
Check test - bug#465250
|
||
stdin:
|
||
test ! -e ; echo $?
|
||
expected-stdout:
|
||
1
|
||
---
|
||
name: debian-117-4
|
||
description:
|
||
Check test - bug#465250
|
||
stdin:
|
||
test -e ; echo $?
|
||
expected-stdout:
|
||
0
|
||
---
|
||
name: case-zsh
|
||
description:
|
||
Check that zsh case variants work
|
||
stdin:
|
||
case 'b' in
|
||
a) echo a ;;
|
||
b) echo b ;;
|
||
c) echo c ;;
|
||
*) echo x ;;
|
||
esac
|
||
echo =
|
||
case 'b' in
|
||
a) echo a ;&
|
||
b) echo b ;&
|
||
c) echo c ;&
|
||
*) echo x ;&
|
||
esac
|
||
echo =
|
||
case 'b' in
|
||
a) echo a ;|
|
||
b) echo b ;|
|
||
c) echo c ;|
|
||
*) echo x ;|
|
||
esac
|
||
expected-stdout:
|
||
b
|
||
=
|
||
b
|
||
c
|
||
x
|
||
=
|
||
b
|
||
x
|
||
---
|
||
name: case-braces
|
||
description:
|
||
Check that case end tokens are not mixed up (Debian #220272)
|
||
stdin:
|
||
i=0
|
||
for value in 'x' '}' 'esac'; do
|
||
print -n "$((++i))($value)bourne "
|
||
case $value in
|
||
}) echo brace ;;
|
||
*) echo no ;;
|
||
esac
|
||
print -n "$((++i))($value)korn "
|
||
case $value {
|
||
esac) echo esac ;;
|
||
*) echo no ;;
|
||
}
|
||
done
|
||
expected-stdout:
|
||
1(x)bourne no
|
||
2(x)korn no
|
||
3(})bourne brace
|
||
4(})korn no
|
||
5(esac)bourne no
|
||
6(esac)korn esac
|
||
---
|
||
name: command-shift
|
||
description:
|
||
Check that 'command shift' works
|
||
stdin:
|
||
function snc {
|
||
echo "before 0='$0' 1='$1' 2='$2'"
|
||
shift
|
||
echo "after 0='$0' 1='$1' 2='$2'"
|
||
}
|
||
function swc {
|
||
echo "before 0='$0' 1='$1' 2='$2'"
|
||
command shift
|
||
echo "after 0='$0' 1='$1' 2='$2'"
|
||
}
|
||
echo = without command
|
||
snc 一 二
|
||
echo = with command
|
||
swc 一 二
|
||
echo = done
|
||
expected-stdout:
|
||
= without command
|
||
before 0='snc' 1='一' 2='二'
|
||
after 0='snc' 1='二' 2=''
|
||
= with command
|
||
before 0='swc' 1='一' 2='二'
|
||
after 0='swc' 1='二' 2=''
|
||
= done
|
||
---
|
||
name: command-pvV-posix-priorities
|
||
description:
|
||
For POSIX compatibility, command -v should find aliases and reserved
|
||
words, and command -p[vV] should find aliases, reserved words, and
|
||
builtins over external commands.
|
||
stdin:
|
||
PATH=/bin:/usr/bin
|
||
alias foo="bar baz"
|
||
bar() { :; }
|
||
for word in 'if' 'foo' 'bar' 'set' 'true'; do
|
||
command -v "$word"
|
||
command -pv "$word"
|
||
command -V "$word"
|
||
command -pV "$word"
|
||
done
|
||
expected-stdout:
|
||
if
|
||
if
|
||
if is a reserved word
|
||
if is a reserved word
|
||
alias foo='bar baz'
|
||
alias foo='bar baz'
|
||
foo is an alias for 'bar baz'
|
||
foo is an alias for 'bar baz'
|
||
bar
|
||
bar
|
||
bar is a function
|
||
bar is a function
|
||
set
|
||
set
|
||
set is a special shell builtin
|
||
set is a special shell builtin
|
||
true
|
||
true
|
||
true is a shell builtin
|
||
true is a shell builtin
|
||
---
|
||
name: whence-preserve-tradition
|
||
description:
|
||
This regression test is to ensure that the POSIX compatibility
|
||
changes for 'command' (see previous test) do not affect traditional
|
||
'whence' behaviour.
|
||
category: os:mirbsd
|
||
stdin:
|
||
PATH=/bin:/usr/bin
|
||
alias foo="bar baz"
|
||
bar() { :; }
|
||
for word in 'if' 'foo' 'bar' 'set' 'true'; do
|
||
whence "$word"
|
||
whence -p "$word"
|
||
whence -v "$word"
|
||
whence -pv "$word"
|
||
done
|
||
expected-stdout:
|
||
if
|
||
if is a reserved word
|
||
if not found
|
||
'bar baz'
|
||
foo is an alias for 'bar baz'
|
||
foo not found
|
||
bar
|
||
bar is a function
|
||
bar not found
|
||
set
|
||
set is a special shell builtin
|
||
set not found
|
||
true
|
||
/bin/true
|
||
true is a shell builtin
|
||
true is a tracked alias for /bin/true
|
||
---
|
||
name: duffs-device
|
||
description:
|
||
Check that the compiler did not optimise-break them
|
||
(lex.c has got a similar one in SHEREDELIM)
|
||
category: !shell:faux-ebcdic,!shell:ebcdic-yes
|
||
stdin:
|
||
set +U
|
||
s=
|
||
typeset -i1 i=0
|
||
while (( ++i < 256 )); do
|
||
s+=${i#1#}
|
||
done
|
||
s+=$'\xC2\xA0\xE2\x82\xAC\xEF\xBF\xBD\xEF\xBF\xBE\xEF\xBF\xBF\xF0\x90\x80\x80.'
|
||
typeset -p s
|
||
expected-stdout:
|
||
typeset s=$'\001\002\003\004\005\006\a\b\t\n\v\f\r\016\017\020\021\022\023\024\025\026\027\030\031\032\E\034\035\036\037 !"#$%&\047()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377\u00A0\u20AC\uFFFD\357\277\276\357\277\277\360\220\200\200.'
|
||
---
|
||
name: duffs-device-ebcdic
|
||
description:
|
||
Check that the compiler did not optimise-break them
|
||
category: !shell:ebcdic-no
|
||
stdin:
|
||
set +U
|
||
s=
|
||
typeset -i1 i=0
|
||
while (( ++i < 256 )); do
|
||
s+=${i#1#}
|
||
done
|
||
#s+=$'\xC2\xA0\xE2\x82\xAC\xEF\xBF\xBD\xEF\xBF\xBE\xEF\xBF\xBF\xF0\x90\x80\x80.' #XXX
|
||
typeset -p s
|
||
expected-stdout:
|
||
typeset s=$'\001\002\003\004\t\006\007\010\011\012\v\f\r\016\017\020\021\022\023\024\n\b\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\E\050\051\052\053\054\055\056\a\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.<(+|&<26><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>!$*);^-/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ѧ,%_>?<3F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>`:#@\175="<EFBFBD>abcdefghi<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>jklmnopqr<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƥ<EFBFBD>~stuvwxyz<79><7A><EFBFBD>[ޮ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݨ<EFBFBD>]<EFBFBD><EFBFBD>{ABCDEFGHI<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>}JKLMNOPQR<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\\<EFBFBD>STUVWXYZ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0123456789<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\377'
|
||
---
|
||
name: duffs-device-faux-EBCDIC
|
||
description:
|
||
Check that the compiler did not optimise-break them
|
||
category: shell:faux-ebcdic
|
||
stdin:
|
||
set +U
|
||
s=
|
||
typeset -i1 i=0
|
||
while (( ++i < 256 )); do
|
||
s+=${i#1#}
|
||
done
|
||
s+=$'\xC2\xA0\xE2\x82\xAC\xEF\xBF\xBD\xEF\xBF\xBE\xEF\xBF\xBF\xF0\x90\x80\x80.'
|
||
typeset -p s
|
||
expected-stdout:
|
||
typeset s=$'\001\002\003\004\005\006\a\b\t\n\v\f\r\016\017\020\021\022\023\024\025\026\027\030\031\032\E\034\035\036\037 !"#$%&\047()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237<33><37><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\u00A0\u20AC\uFFFD<EFBFBE>\220\200\200.'
|
||
---
|
||
name: stateptr-underflow
|
||
description:
|
||
This check overflows an Xrestpos stored in a short in R40
|
||
category: fastbox
|
||
stdin:
|
||
function Lb64decode {
|
||
[[ -o utf8-mode ]]; local u=$?
|
||
set +U
|
||
local c s="$*" t=
|
||
[[ -n $s ]] || { s=$(cat;print x); s=${s%x}; }
|
||
local -i i=0 n=${#s} p=0 v x
|
||
local -i16 o
|
||
|
||
while (( i < n )); do
|
||
c=${s:(i++):1}
|
||
case $c {
|
||
(=) break ;;
|
||
([A-Z]) (( v = 1#$c - 65 )) ;;
|
||
([a-z]) (( v = 1#$c - 71 )) ;;
|
||
([0-9]) (( v = 1#$c + 4 )) ;;
|
||
(+) v=62 ;;
|
||
(/) v=63 ;;
|
||
(*) continue ;;
|
||
}
|
||
(( x = (x << 6) | v ))
|
||
case $((p++)) {
|
||
(0) continue ;;
|
||
(1) (( o = (x >> 4) & 255 )) ;;
|
||
(2) (( o = (x >> 2) & 255 )) ;;
|
||
(3) (( o = x & 255 ))
|
||
p=0
|
||
;;
|
||
}
|
||
t=$t\\x${o#16#}
|
||
done
|
||
print -n $t
|
||
(( u )) || set -U
|
||
}
|
||
|
||
i=-1
|
||
s=
|
||
while (( ++i < 12120 )); do
|
||
s+=a
|
||
done
|
||
Lb64decode $s >/dev/null
|
||
---
|
||
name: xtrace-1
|
||
description:
|
||
Check that "set -x" doesn't redirect too quickly
|
||
stdin:
|
||
print '#!'"$__progname" >bash
|
||
cat >>bash <<'EOF'
|
||
echo 'GNU bash, version 2.05b.0(1)-release (i386-ecce-mirbsd10)
|
||
Copyright (C) 2002 Free Software Foundation, Inc.'
|
||
EOF
|
||
chmod +x bash
|
||
"$__progname" -xc 'foo=$(./bash --version 2>&1 | sed q); echo "=$foo="'
|
||
expected-stdout:
|
||
=GNU bash, version 2.05b.0(1)-release (i386-ecce-mirbsd10)=
|
||
expected-stderr-pattern:
|
||
/.*/
|
||
---
|
||
name: xtrace-2
|
||
description:
|
||
Check that "set -x" is off during PS4 expansion
|
||
stdin:
|
||
f() {
|
||
print -n "(f1:$-)"
|
||
set -x
|
||
print -n "(f2:$-)"
|
||
}
|
||
PS4='[(p:$-)$(f)] '
|
||
print "(o0:$-)"
|
||
set -x -o inherit-xtrace
|
||
print "(o1:$-)"
|
||
set +x
|
||
print "(o2:$-)"
|
||
expected-stdout:
|
||
(o0:sh)
|
||
(o1:shx)
|
||
(o2:sh)
|
||
expected-stderr:
|
||
[(p:sh)(f1:sh)(f2:sh)] print '(o1:shx)'
|
||
[(p:sh)(f1:sh)(f2:sh)] set +x
|
||
---
|
||
name: fksh-flags
|
||
description:
|
||
Check that FKSH functions have their own shell flags
|
||
category: shell:legacy-no
|
||
stdin:
|
||
[[ $KSH_VERSION = Version* ]] && set +B
|
||
function foo {
|
||
set +f
|
||
set -e
|
||
echo 2 "${-/s}" .
|
||
}
|
||
set -fh
|
||
echo 1 "${-/s}" .
|
||
foo
|
||
echo 3 "${-/s}" .
|
||
expected-stdout:
|
||
1 fh .
|
||
2 eh .
|
||
3 fh .
|
||
---
|
||
name: fksh-flags-legacy
|
||
description:
|
||
Check that even FKSH functions share the shell flags
|
||
category: shell:legacy-yes
|
||
stdin:
|
||
[[ $KSH_VERSION = Version* ]] && set +B
|
||
foo() {
|
||
set +f
|
||
set -e
|
||
echo 2 "${-/s}" .
|
||
}
|
||
set -fh
|
||
echo 1 "${-/s}" .
|
||
foo
|
||
echo 3 "${-/s}" .
|
||
expected-stdout:
|
||
1 fh .
|
||
2 eh .
|
||
3 eh .
|
||
---
|
||
name: fsh-flags
|
||
description:
|
||
Check that !FKSH functions share the shell flags
|
||
stdin:
|
||
[[ $KSH_VERSION = Version* ]] && set +B
|
||
foo() {
|
||
set +f
|
||
set -e
|
||
echo 2 "${-/s}" .
|
||
}
|
||
set -fh
|
||
echo 1 "${-/s}" .
|
||
foo
|
||
echo 3 "${-/s}" .
|
||
expected-stdout:
|
||
1 fh .
|
||
2 eh .
|
||
3 eh .
|
||
---
|