1 |
#!/bin/bash |
2 |
# |
3 |
# Test set flags, sh flags. |
4 |
|
5 |
### can continue after unknown option |
6 |
# dash and mksh make this a fatal error no matter what. |
7 |
set -o errexit |
8 |
set -o STRICT || true # unknown option |
9 |
echo hello |
10 |
# stdout: hello |
11 |
# status: 0 |
12 |
# BUG dash/mksh stdout-json: "" |
13 |
# BUG dash status: 2 |
14 |
# BUG mksh status: 1 |
15 |
|
16 |
### set with both options and argv |
17 |
set -o errexit a b c |
18 |
echo "$@" |
19 |
false |
20 |
echo done |
21 |
# stdout: a b c |
22 |
# status: 1 |
23 |
|
24 |
### nounset |
25 |
echo "[$unset]" |
26 |
set -o nounset |
27 |
echo "[$unset]" |
28 |
echo end # never reached |
29 |
# stdout: [] |
30 |
# status: 1 |
31 |
# OK dash status: 2 |
32 |
|
33 |
### -u is nounset |
34 |
echo "[$unset]" |
35 |
set -u |
36 |
echo "[$unset]" |
37 |
echo end # never reached |
38 |
# stdout: [] |
39 |
# status: 1 |
40 |
# OK dash status: 2 |
41 |
|
42 |
### reset option with long flag |
43 |
set -o errexit |
44 |
set +o errexit |
45 |
echo "[$unset]" |
46 |
# stdout: [] |
47 |
# status: 0 |
48 |
|
49 |
### reset option with short flag |
50 |
set -u |
51 |
set +u |
52 |
echo "[$unset]" |
53 |
# stdout: [] |
54 |
# status: 0 |
55 |
|
56 |
### sh -c |
57 |
$SH -c 'echo hi' |
58 |
# stdout: hi |
59 |
# status: 0 |
60 |
|
61 |
### -n for no execution (useful with --ast-output) |
62 |
# NOTE: set +n doesn't work because nothing is executed! |
63 |
echo 1 |
64 |
set -n |
65 |
echo 2 |
66 |
set +n |
67 |
echo 3 |
68 |
# stdout-json: "1\n" |
69 |
# status: 0 |
70 |
|
71 |
### xtrace |
72 |
echo 1 |
73 |
set -o xtrace |
74 |
echo 2 |
75 |
# stdout-json: "1\n2\n" |
76 |
# stderr: + echo 2 |
77 |
|
78 |
### errexit aborts early |
79 |
set -o errexit |
80 |
false |
81 |
echo done |
82 |
# stdout-json: "" |
83 |
# status: 1 |
84 |
|
85 |
### errexit aborts early on pipeline |
86 |
set -o errexit |
87 |
echo hi | grep nonexistent |
88 |
echo two |
89 |
# stdout-json: "" |
90 |
# status: 1 |
91 |
|
92 |
### errexit with { } |
93 |
# This aborts because it's not part of an if statement. |
94 |
set -o errexit |
95 |
{ echo one; false; echo two; } |
96 |
# stdout: one |
97 |
# status: 1 |
98 |
|
99 |
### errexit with if and { } |
100 |
set -o errexit |
101 |
if { echo one; false; echo two; }; then |
102 |
echo three |
103 |
fi |
104 |
echo four |
105 |
# stdout-json: "one\ntwo\nthree\nfour\n" |
106 |
# status: 0 |
107 |
|
108 |
### errexit with || |
109 |
set -o errexit |
110 |
echo hi | grep nonexistent || echo ok |
111 |
# stdout: ok |
112 |
# status: 0 |
113 |
|
114 |
### errexit with && |
115 |
set -o errexit |
116 |
echo ok && echo hi | grep nonexistent |
117 |
# stdout: ok |
118 |
# status: 1 |
119 |
|
120 |
### errexit with ! |
121 |
set -o errexit |
122 |
echo one |
123 |
! true |
124 |
echo two |
125 |
! false |
126 |
echo three |
127 |
# stdout-json: "one\ntwo\nthree\n" |
128 |
# status: 0 |
129 |
|
130 |
### errexit with while/until |
131 |
set -o errexit |
132 |
while false; do |
133 |
echo ok |
134 |
done |
135 |
until false; do |
136 |
echo ok # do this once then exit loop |
137 |
break |
138 |
done |
139 |
# stdout: ok |
140 |
# status: 0 |
141 |
|
142 |
### errexit with (( )) |
143 |
# from http://mywiki.wooledge.org/BashFAQ/105, this changed between verisons. |
144 |
set -o errexit |
145 |
i=0 |
146 |
(( i++ )) |
147 |
echo done |
148 |
# stdout-json: "" |
149 |
# status: 1 |
150 |
# N-I dash status: 127 |
151 |
# N-I dash stdout-json: "" |
152 |
|
153 |
### errexit with subshell |
154 |
set -o errexit |
155 |
( echo one; false; echo two; ) |
156 |
# stdout: one |
157 |
# status: 1 |
158 |
|
159 |
### errexit with command sub |
160 |
# This is the bash-specific bug here: |
161 |
# https://blogs.janestreet.com/when-bash-scripts-bite/ |
162 |
set -o errexit |
163 |
s=$(echo one; false; echo two;) |
164 |
echo "$s" |
165 |
# stdout-json: "" |
166 |
# status: 1 |
167 |
# BUG bash status: 0 |
168 |
# BUG bash stdout-json: "one\ntwo\n" |
169 |
|
170 |
### errexit with local |
171 |
# I've run into this problem a lot. |
172 |
# https://blogs.janestreet.com/when-bash-scripts-bite/ |
173 |
set -o errexit |
174 |
f() { |
175 |
echo good |
176 |
local x=$(echo bad; false) |
177 |
echo $x |
178 |
} |
179 |
f |
180 |
# stdout-json: "good\n" |
181 |
# status: 1 |
182 |
# BUG bash/dash/mksh stdout-json: "good\nbad\n" |
183 |
# BUG bash/dash/mksh status: 0 |
184 |
|
185 |
### setting errexit while it's being ignored |
186 |
# ignored and then set again |
187 |
set -o errexit |
188 |
# osh aborts early here |
189 |
if { echo 1; false; echo 2; set -o errexit; echo 3; false; echo 4; }; then |
190 |
echo 5; |
191 |
fi |
192 |
echo 6 |
193 |
false # this is the one that makes other shells fail |
194 |
echo 7 |
195 |
# status: 1 |
196 |
# stdout-json: "1\n2\n" |
197 |
# OK dash/bash/mksh stdout-json: "1\n2\n3\n4\n5\n6\n" |
198 |
|
199 |
### setting errexit in a subshell works but doesn't affect parent shell |
200 |
( echo 1; false; echo 2; set -o errexit; echo 3; false; echo 4; ) |
201 |
echo 5 |
202 |
false |
203 |
echo 6 |
204 |
# stdout-json: "1\n2\n3\n5\n6\n" |
205 |
# status: 0 |
206 |
|
207 |
### setting errexit while it's being ignored in a subshell |
208 |
set -o errexit |
209 |
if ( echo 1; false; echo 2; set -o errexit; echo 3; false; echo 4 ); then |
210 |
echo 5; |
211 |
fi |
212 |
echo 6 # This is executed because the subshell just returns false |
213 |
false |
214 |
echo 7 |
215 |
# status: 1 |
216 |
# stdout-json: "1\n2\n6\n" |
217 |
# OK dash/bash/mksh stdout-json: "1\n2\n3\n4\n5\n6\n" |
218 |
|
219 |
### errexit double quard |
220 |
# OSH bug fix. ErrExit needs a counter, not a boolean. |
221 |
set -o errexit |
222 |
if { ! false; false; true; } then |
223 |
echo true |
224 |
fi |
225 |
false |
226 |
echo done |
227 |
# status: 1 |
228 |
# stdout-json: "true\n" |
229 |
|
230 |
### pipefail |
231 |
# NOTE: the sleeps are because osh can fail non-deterministically because of a |
232 |
# bug. Same problem as PIPESTATUS. |
233 |
{ sleep 0.01; exit 9; } | { sleep 0.02; exit 2; } | { sleep 0.03; exit 0; } |
234 |
echo $? |
235 |
set -o pipefail |
236 |
{ sleep 0.01; exit 9; } | { sleep 0.02; exit 2; } | { sleep 0.03; exit 0; } |
237 |
echo $? |
238 |
# stdout-json: "0\n2\n" |
239 |
# status: 0 |
240 |
# N-I dash stdout-json: "0\n" |
241 |
# N-I dash status: 2 |