1 #!/usr/bin/env bash
2
3 ### Env value doesn't persist
4 FOO=foo printenv.py FOO
5 echo [$FOO]
6 # STDOUT:
7 foo
8 []
9 ## END
10
11 ### Env value with equals
12 FOO=foo=foo printenv.py FOO
13 ## stdout: foo=foo
14
15 ### Env binding can use preceding bindings, but not subsequent ones
16 # This means that for ASSIGNMENT_WORD, on the RHS you invoke the parser again!
17 # Could be any kind of quoted string.
18 FOO="foo" BAR="[$FOO][$BAZ]" BAZ=baz printenv.py FOO BAR BAZ
19 ## STDOUT:
20 foo
21 [foo][]
22 baz
23 ## BUG mksh STDOUT:
24 foo
25 [][]
26 baz
27 ## END
28
29 ### Env value with two quotes
30 FOO='foo'"adjacent" printenv.py FOO
31 # stdout: fooadjacent
32
33 ### Env value with escaped <
34 FOO=foo\<foo printenv.py FOO
35 ## stdout: foo<foo
36
37 ### FOO=foo echo [foo]
38 FOO=foo echo "[$foo]"
39 ## stdout: []
40
41 ### FOO=foo func
42 func() {
43 echo "[$FOO]"
44 }
45 FOO=foo func
46 ## stdout: [foo]
47
48 ### Multiple temporary envs on the stack
49 g() {
50 echo "$F" "$G1" "$G2"
51 echo '--- g() ---'
52 P=p printenv.py F G1 G2 A P
53 }
54 f() {
55 # NOTE: G1 doesn't pick up binding f, but G2 picks up a.
56 # I don't quite understand why this is, but bash and OSH agree!
57 G1=[$f] G2=[$a] g
58 echo '--- f() ---'
59 printenv.py F G1 G2 A P
60 }
61 a=A
62 F=f f
63 ## STDOUT:
64 f [] [A]
65 --- g() ---
66 f
67 []
68 [A]
69 None
70 p
71 --- f() ---
72 f
73 None
74 None
75 None
76 None
77 ## END
78 ## OK mksh STDOUT:
79 # G1 and G2 somehow persist. I think that is a bug. They should be local to
80 # the G call.
81 f [] [A]
82 --- g() ---
83 f
84 []
85 [A]
86 None
87 p
88 --- f() ---
89 f
90 []
91 [A]
92 None
93 None
94 ## END
95 ## BUG dash STDOUT:
96 # dash sets even less stuff. Doesn't appear correct.
97 f [] [A]
98 --- g() ---
99 None
100 None
101 None
102 None
103 p
104 --- f() ---
105 None
106 None
107 None
108 None
109 None
110 ## END
111
112 ### Escaped = in command name
113 # foo=bar is in the 'spec/bin' dir.
114 foo\=bar
115 ## stdout: HI
116
117 ### Env binding not allowed before compound command
118 # bash gives exit code 2 for syntax error, because of 'do'.
119 # dash gives 0 because there is stuff after for? Should really give an error.
120 # mksh gives acceptable error of 1.
121 FOO=bar for i in a b; do printenv.py $FOO; done
122 ## BUG dash status: 0
123 ## OK mksh status: 1
124 ## status: 2
125
126 ### Trying to run keyword 'for'
127 FOO=bar for
128 ## status: 127
129
130 ### Empty env binding
131 EMPTY= printenv.py EMPTY
132 ## stdout:
133
134 ### Assignment doesn't do word splitting
135 words='one two'
136 a=$words
137 argv.py "$a"
138 ## stdout: ['one two']
139
140 ### Assignment doesn't do glob expansion
141 touch _tmp/z.Z _tmp/zz.Z
142 a=_tmp/*.Z
143 argv.py "$a"
144 # stdout: ['_tmp/*.Z']
145
146 ### Env binding in readonly/declare disallowed
147 # I'm disallowing this in the oil shell, because it doesn't work in bash!
148 # (v=None vs v=foo)
149 # assert status 2 for parse error, but allow stdout v=None/status 0 for
150 # existing implementations.
151 FOO=foo readonly v=$(printenv.py FOO)
152 echo "v=$v"
153 # OK bash/dash/mksh stdout: v=None
154 # OK bash/dash/mksh status: 0
155 # status: 2
156
157 ### local -a
158 # nixpkgs setup.sh uses this (issue #26)
159 f() {
160 local -a array=(x y z)
161 argv.py "${array[@]}"
162 }
163 f
164 # stdout: ['x', 'y', 'z']
165 # N-I dash stdout-json: ""
166 # N-I dash status: 2
167 # N-I mksh stdout-json: ""
168 # N-I mksh status: 1
169
170 ### declare -a
171 # nixpkgs setup.sh uses this (issue #26)
172 declare -a array=(x y z)
173 argv.py "${array[@]}"
174 # stdout: ['x', 'y', 'z']
175 # N-I dash stdout-json: ""
176 # N-I dash status: 2
177 # N-I mksh stdout-json: ""
178 # N-I mksh status: 1
179
180 ### typeset -a a[1]=a a[3]=c
181 # declare works the same way in bash, but not mksh.
182 # spaces are NOT allowed here.
183 typeset -a a[1*1]=x a[1+2]=z
184 argv.py "${a[@]}"
185 # stdout: ['x', 'z']
186 # N-I dash stdout-json: ""
187 # N-I dash status: 2
188
189 ### indexed LHS without spaces is allowed
190 a[1 * 1]=x a[ 1 + 2 ]=z
191 argv.py "${a[@]}"
192 # stdout: ['x', 'z']
193 # N-I dash stdout-json: ""
194 # N-I dash status: 2
195
196 ### declare -f
197 func2=x # var names are NOT found
198 declare -f myfunc func2
199 echo $?
200
201 myfunc() { echo myfunc; }
202 # This prints the source code.
203 declare -f myfunc func2 > /dev/null
204 echo $?
205
206 func2() { echo func2; }
207 declare -f myfunc func2 > /dev/null
208 echo $?
209 ## STDOUT:
210 1
211 1
212 0
213 ## END
214 ## N-I dash/mksh STDOUT:
215 127
216 127
217 127
218 ## END
219
220 ### declare -p
221 var1() { echo func; } # function names are NOT found.
222 declare -p var1 var2 >/dev/null
223 echo $?
224
225 var1=x
226 declare -p var1 var2 >/dev/null
227 echo $?
228
229 var2=y
230 declare -p var1 var2 >/dev/null
231 echo $?
232 ## STDOUT:
233 1
234 1
235 0
236 ## N-I dash/mksh STDOUT:
237 127
238 127
239 127
240 ## END
241
242 ### typeset -f
243 # mksh implement typeset but not declare
244 typeset -f myfunc func2
245 echo $?
246
247 myfunc() { echo myfunc; }
248 # This prints the source code.
249 typeset -f myfunc func2 > /dev/null
250 echo $?
251
252 func2() { echo func2; }
253 typeset -f myfunc func2 > /dev/null
254 echo $?
255 ## STDOUT:
256 1
257 1
258 0
259 ## END
260 ## N-I dash STDOUT:
261 127
262 127
263 127
264 ## END
265
266 ### typeset -p
267 var1() { echo func; } # function names are NOT found.
268 typeset -p var1 var2 >/dev/null
269 echo $?
270
271 var1=x
272 typeset -p var1 var2 >/dev/null
273 echo $?
274
275 var2=y
276 typeset -p var1 var2 >/dev/null
277 echo $?
278 ## STDOUT:
279 1
280 1
281 0
282 ## BUG mksh STDOUT:
283 # mksh doesn't respect exit codes
284 0
285 0
286 0
287 ## END
288 ## N-I dash STDOUT:
289 127
290 127
291 127
292 ## END
293
294 ### typeset -r makes a string readonly
295 typeset -r s1='12'
296 typeset -r s2='34'
297
298 s1='c'
299 echo status=$?
300 s2='d'
301 echo status=$?
302
303 s1+='e'
304 echo status=$?
305 s2+='f'
306 echo status=$?
307
308 unset s1
309 echo status=$?
310 unset s2
311 echo status=$?
312
313 ## status: 1
314 ## stdout-json: ""
315 ## OK mksh status: 2
316 ## OK bash status: 0
317 ## OK bash STDOUT:
318 status=1
319 status=1
320 status=1
321 status=1
322 status=1
323 status=1
324 ## END
325 ## OK dash status: 0
326 ## N-I dash STDOUT:
327 status=0
328 status=0
329 status=127
330 status=127
331 status=0
332 status=0
333 ## END
334
335 ### typeset -ar makes it readonly
336 typeset -a -r array1=(1 2)
337 typeset -ar array2=(3 4)
338
339 array1=('c')
340 echo status=$?
341 array2=('d')
342 echo status=$?
343
344 array1+=('e')
345 echo status=$?
346 array2+=('f')
347 echo status=$?
348
349 unset array1
350 echo status=$?
351 unset array2
352 echo status=$?
353
354 ## status: 1
355 ## stdout-json: ""
356 ## OK bash status: 0
357 ## OK bash STDOUT:
358 status=1
359 status=1
360 status=1
361 status=1
362 status=1
363 status=1
364 ## END
365 # N-I dash status: 2
366 # N-I dash stdout-json: ""
367 # N-I mksh status: 1
368 # N-I mksh stdout-json: ""
369
370 ### typeset -x makes it exported
371 typeset -rx PYTHONPATH=lib/
372 printenv.py PYTHONPATH
373 ## STDOUT:
374 lib/
375 ## END
376 # N-I dash stdout: None
377