1 |
#!/usr/bin/env bash |
2 |
|
3 |
### echo dashes |
4 |
echo - |
5 |
echo -- |
6 |
echo --- |
7 |
# stdout-json: "-\n--\n---\n" |
8 |
|
9 |
### echo -en |
10 |
echo -en 'abc\ndef\n' |
11 |
# stdout-json: "abc\ndef\n" |
12 |
# N-I dash stdout-json: "-en abc\ndef\n\n" |
13 |
|
14 |
### echo -ez (invalid flag) |
15 |
# bash differs from the other two shells, but its behavior is possibly more |
16 |
# sensible, if you're going to ignore the error. It doesn't make sense for the |
17 |
# 'e' to mean 2 different things simultaneously: flag and literal to be |
18 |
# printed. |
19 |
echo -ez 'abc\n' |
20 |
# stdout-json: "-ez abc\\n\n" |
21 |
# BUG dash/mksh stdout-json: "-ez abc\n\n" |
22 |
|
23 |
### exec builtin |
24 |
exec echo hi |
25 |
# stdout: hi |
26 |
|
27 |
### exec builtin with redirects |
28 |
exec 1>&2 |
29 |
echo 'to stderr' |
30 |
# stdout-json: "" |
31 |
# stderr: to stderr |
32 |
|
33 |
### exec builtin with here doc |
34 |
# This has in a separate file because both code and data can be read from |
35 |
# stdin. |
36 |
$SH spec/exec-here-doc.sh |
37 |
# stdout-json: "x=one\ny=two\nDONE\n" |
38 |
|
39 |
### cd and $PWD |
40 |
cd / |
41 |
echo $PWD |
42 |
# stdout: / |
43 |
|
44 |
### $OLDPWD |
45 |
cd / |
46 |
cd $TMP |
47 |
echo "old: $OLDPWD" |
48 |
cd - |
49 |
# stdout-json: "old: /\n/\n" |
50 |
|
51 |
### pushd/popd |
52 |
set -o errexit |
53 |
cd / |
54 |
pushd $TMP |
55 |
popd |
56 |
pwd |
57 |
# status: 0 |
58 |
# N-I dash/mksh status: 127 |
59 |
|
60 |
### Source |
61 |
lib=$TMP/spec-test-lib.sh |
62 |
echo 'LIBVAR=libvar' > $lib |
63 |
. $lib # dash doesn't have source |
64 |
echo $LIBVAR |
65 |
# stdout: libvar |
66 |
|
67 |
### Exit builtin |
68 |
exit 3 |
69 |
# status: 3 |
70 |
|
71 |
### Exit builtin with invalid arg |
72 |
exit invalid |
73 |
# Rationale: runtime errors are 1 |
74 |
# status: 1 |
75 |
# OK dash/bash status: 2 |
76 |
|
77 |
### Exit builtin with too many args |
78 |
exit 7 8 9 |
79 |
echo "no exit: $?" |
80 |
# status: 0 |
81 |
# stdout-json: "no exit: 1\n" |
82 |
# BUG dash status: 7 |
83 |
# BUG dash stdout-json: "" |
84 |
# OK mksh status: 1 |
85 |
# OK mksh stdout-json: "" |
86 |
|
87 |
### time block |
88 |
# bash and mksh work; dash does't. |
89 |
# TODO: osh needs to implement BraceGroup redirect properly. |
90 |
err=_tmp/time-$(basename $SH).txt |
91 |
{ |
92 |
time { |
93 |
sleep 0.01 |
94 |
sleep 0.02 |
95 |
} |
96 |
} 2> $err |
97 |
cat $err | grep --only-matching real |
98 |
# Just check that we found 'real'. |
99 |
# This is fiddly: |
100 |
# | sed -n -E -e 's/.*(0m0\.03).*/\1/' |
101 |
# |
102 |
# status: 0 |
103 |
# stdout: real |
104 |
# BUG dash status: 2 |
105 |
# BUG dash stdout-json: "" |
106 |
|
107 |
### time pipeline |
108 |
time echo hi | wc -c |
109 |
# stdout: 3 |
110 |
# status: 0 |
111 |
|
112 |
### shift |
113 |
set -- 1 2 3 4 |
114 |
shift |
115 |
echo "$@" |
116 |
shift 2 |
117 |
echo "$@" |
118 |
# stdout-json: "2 3 4\n4\n" |
119 |
# status: 0 |
120 |
|
121 |
### Shifting too far |
122 |
set -- 1 |
123 |
shift 2 |
124 |
# status: 1 |
125 |
# OK dash status: 2 |
126 |
|
127 |
### Invalid shift argument |
128 |
shift ZZZ |
129 |
# status: 1 |
130 |
# OK dash status: 2 |
131 |
# BUG mksh status: 0 |
132 |
|
133 |
### Read builtin |
134 |
# NOTE: there are TABS below |
135 |
read x <<EOF |
136 |
A B C D E |
137 |
FG |
138 |
EOF |
139 |
echo "[$x]" |
140 |
# stdout: [A B C D E] |
141 |
# status: 0 |
142 |
|
143 |
### Read builtin with no newline. |
144 |
# This is odd because the variable is populated successfully. OSH/Oil might |
145 |
# need a separate put reading feature that doesn't use IFS. |
146 |
echo -n ZZZ | { read x; echo $?; echo $x; } |
147 |
# stdout-json: "1\nZZZ\n" |
148 |
# status: 0 |
149 |
|
150 |
### Read builtin with multiple variables |
151 |
# NOTE: there are TABS below |
152 |
read x y z <<EOF |
153 |
A B C D E |
154 |
FG |
155 |
EOF |
156 |
echo "$x/$y/$z" |
157 |
# stdout: A/B/C D E |
158 |
# status: 0 |
159 |
|
160 |
### Read builtin with not enough variables |
161 |
set -o errexit |
162 |
set -o nounset # hm this doesn't change it |
163 |
read x y z <<EOF |
164 |
A B |
165 |
EOF |
166 |
echo /$x/$y/$z/ |
167 |
# stdout: /A/B// |
168 |
# status: 0 |
169 |
|
170 |
### get umask |
171 |
umask | grep '[0-9]\+' # check for digits |
172 |
# status: 0 |
173 |
|
174 |
### set umask in octal |
175 |
rm $TMP/umask-one $TMP/umask-two |
176 |
umask 0002 |
177 |
echo one > $TMP/umask-one |
178 |
umask 0022 |
179 |
echo two > $TMP/umask-two |
180 |
stat -c '%a' $TMP/umask-one $TMP/umask-two |
181 |
# status: 0 |
182 |
# stdout-json: "664\n644\n" |
183 |
# stderr-json: "" |
184 |
|
185 |
### set umask symbolically |
186 |
rm $TMP/umask-one $TMP/umask-two |
187 |
echo one > $TMP/umask-one |
188 |
umask g-w,o-w |
189 |
echo two > $TMP/umask-two |
190 |
stat -c '%a' $TMP/umask-one $TMP/umask-two |
191 |
# status: 0 |
192 |
# stdout-json: "664\n644\n" |
193 |
# stderr-json: "" |
194 |
|