1 |
#!/bin/bash |
2 |
# |
3 |
# Extended assignment language, e.g. typeset, declare, arrays, etc. |
4 |
# Things that dash doesn't support. |
5 |
|
6 |
#### local -a |
7 |
# nixpkgs setup.sh uses this (issue #26) |
8 |
f() { |
9 |
local -a array=(x y z) |
10 |
argv.py "${array[@]}" |
11 |
} |
12 |
f |
13 |
## stdout: ['x', 'y', 'z'] |
14 |
## N-I mksh stdout-json: "" |
15 |
## N-I mksh status: 1 |
16 |
|
17 |
#### declare -a |
18 |
# nixpkgs setup.sh uses this (issue #26) |
19 |
declare -a array=(x y z) |
20 |
argv.py "${array[@]}" |
21 |
## stdout: ['x', 'y', 'z'] |
22 |
## N-I mksh stdout-json: "" |
23 |
## N-I mksh status: 1 |
24 |
|
25 |
#### indexed LHS with spaces (not allowed in OSH) |
26 |
a[1 * 1]=x a[ 1 + 2 ]=z |
27 |
echo status=$? |
28 |
argv.py "${a[@]}" |
29 |
## STDOUT: |
30 |
status=0 |
31 |
['x', 'z'] |
32 |
## END |
33 |
## N-I osh STDOUT: |
34 |
status=127 |
35 |
[] |
36 |
## END |
37 |
|
38 |
#### declare -f exit code indicates function existence |
39 |
func2=x # var names are NOT found |
40 |
declare -f myfunc func2 |
41 |
echo $? |
42 |
|
43 |
myfunc() { echo myfunc; } |
44 |
# This prints the source code. |
45 |
declare -f myfunc func2 > /dev/null |
46 |
echo $? |
47 |
|
48 |
func2() { echo func2; } |
49 |
declare -f myfunc func2 > /dev/null |
50 |
echo $? |
51 |
## STDOUT: |
52 |
1 |
53 |
1 |
54 |
0 |
55 |
## END |
56 |
## N-I mksh STDOUT: |
57 |
127 |
58 |
127 |
59 |
127 |
60 |
## END |
61 |
|
62 |
#### declare -F prints function names |
63 |
add () { expr 4 + 4; } |
64 |
div () { expr 6 / 2; } |
65 |
ek () { echo hello; } |
66 |
__ec () { echo hi; } |
67 |
_ab () { expr 10 % 3; } |
68 |
|
69 |
declare -F |
70 |
## STDOUT: |
71 |
declare -f __ec |
72 |
declare -f _ab |
73 |
declare -f add |
74 |
declare -f div |
75 |
declare -f ek |
76 |
## END |
77 |
## N-I mksh stdout-json: "" |
78 |
## N-I mksh status: 127 |
79 |
|
80 |
#### declare -p |
81 |
var1() { echo func; } # function names are NOT found. |
82 |
declare -p var1 var2 >/dev/null |
83 |
echo $? |
84 |
|
85 |
var1=x |
86 |
declare -p var1 var2 >/dev/null |
87 |
echo $? |
88 |
|
89 |
var2=y |
90 |
declare -p var1 var2 >/dev/null |
91 |
echo $? |
92 |
## STDOUT: |
93 |
1 |
94 |
1 |
95 |
0 |
96 |
## N-I mksh STDOUT: |
97 |
127 |
98 |
127 |
99 |
127 |
100 |
## END |
101 |
|
102 |
#### typeset -f |
103 |
# mksh implement typeset but not declare |
104 |
typeset -f myfunc func2 |
105 |
echo $? |
106 |
|
107 |
myfunc() { echo myfunc; } |
108 |
# This prints the source code. |
109 |
typeset -f myfunc func2 > /dev/null |
110 |
echo $? |
111 |
|
112 |
func2() { echo func2; } |
113 |
typeset -f myfunc func2 > /dev/null |
114 |
echo $? |
115 |
## STDOUT: |
116 |
1 |
117 |
1 |
118 |
0 |
119 |
## END |
120 |
|
121 |
#### typeset -p |
122 |
var1() { echo func; } # function names are NOT found. |
123 |
typeset -p var1 var2 >/dev/null |
124 |
echo $? |
125 |
|
126 |
var1=x |
127 |
typeset -p var1 var2 >/dev/null |
128 |
echo $? |
129 |
|
130 |
var2=y |
131 |
typeset -p var1 var2 >/dev/null |
132 |
echo $? |
133 |
## STDOUT: |
134 |
1 |
135 |
1 |
136 |
0 |
137 |
## BUG mksh STDOUT: |
138 |
# mksh doesn't respect exit codes |
139 |
0 |
140 |
0 |
141 |
0 |
142 |
## END |
143 |
|
144 |
#### typeset -r makes a string readonly |
145 |
typeset -r s1='12' |
146 |
typeset -r s2='34' |
147 |
|
148 |
s1='c' |
149 |
echo status=$? |
150 |
s2='d' |
151 |
echo status=$? |
152 |
|
153 |
s1+='e' |
154 |
echo status=$? |
155 |
s2+='f' |
156 |
echo status=$? |
157 |
|
158 |
unset s1 |
159 |
echo status=$? |
160 |
unset s2 |
161 |
echo status=$? |
162 |
|
163 |
## status: 1 |
164 |
## stdout-json: "" |
165 |
## OK mksh status: 2 |
166 |
## OK bash status: 0 |
167 |
## OK bash STDOUT: |
168 |
status=1 |
169 |
status=1 |
170 |
status=1 |
171 |
status=1 |
172 |
status=1 |
173 |
status=1 |
174 |
## END |
175 |
|
176 |
#### typeset -ar makes it readonly |
177 |
typeset -a -r array1=(1 2) |
178 |
typeset -ar array2=(3 4) |
179 |
|
180 |
array1=('c') |
181 |
echo status=$? |
182 |
array2=('d') |
183 |
echo status=$? |
184 |
|
185 |
array1+=('e') |
186 |
echo status=$? |
187 |
array2+=('f') |
188 |
echo status=$? |
189 |
|
190 |
unset array1 |
191 |
echo status=$? |
192 |
unset array2 |
193 |
echo status=$? |
194 |
|
195 |
## status: 1 |
196 |
## stdout-json: "" |
197 |
## OK bash status: 0 |
198 |
## OK bash STDOUT: |
199 |
status=1 |
200 |
status=1 |
201 |
status=1 |
202 |
status=1 |
203 |
status=1 |
204 |
status=1 |
205 |
## END |
206 |
## N-I mksh status: 1 |
207 |
## N-I mksh stdout-json: "" |
208 |
|
209 |
#### typeset -x makes it exported |
210 |
typeset -rx PYTHONPATH=lib/ |
211 |
printenv.py PYTHONPATH |
212 |
## STDOUT: |
213 |
lib/ |
214 |
## END |
215 |
|
216 |
#### Multiple assignments / array assignments on a line |
217 |
a=1 b[0+0]=2 c=3 |
218 |
echo $a ${b[@]} $c |
219 |
## stdout: 1 2 3 |
220 |
|
221 |
#### Env bindings shouldn't contain array assignments |
222 |
a=1 b[0]=2 c=3 printenv.py a b c |
223 |
## status: 2 |
224 |
## stdout-json: "" |
225 |
## OK bash STDOUT: |
226 |
1 |
227 |
None |
228 |
3 |
229 |
## END |
230 |
## OK bash status: 0 |
231 |
## BUG mksh STDOUT: |
232 |
1 |
233 |
2 |
234 |
3 |
235 |
## END |
236 |
## OK mksh status: 0 |
237 |
|
238 |
#### syntax error in array assignment |
239 |
a=x b[0+]=y c=z |
240 |
echo $a $b $c |
241 |
## status: 2 |
242 |
## stdout-json: "" |
243 |
## BUG bash stdout: x |
244 |
## BUG bash status: 0 |
245 |
## OK mksh stdout-json: "" |
246 |
## OK mksh status: 1 |
247 |
|
248 |
#### declare -g (bash-specific; bash-completion uses it) |
249 |
f() { |
250 |
declare -g G=42 |
251 |
declare L=99 |
252 |
|
253 |
declare -Ag dict |
254 |
dict["foo"]=bar |
255 |
|
256 |
declare -A localdict |
257 |
localdict["spam"]=Eggs |
258 |
|
259 |
# For bash-completion |
260 |
eval 'declare -Ag ev' |
261 |
ev["ev1"]=ev2 |
262 |
} |
263 |
f |
264 |
argv.py "$G" "$L" |
265 |
argv.py "${dict["foo"]}" "${localdict["spam"]}" |
266 |
argv.py "${ev["ev1"]}" |
267 |
## STDOUT: |
268 |
['42', ''] |
269 |
['bar', ''] |
270 |
['ev2'] |
271 |
## END |
272 |
## N-I mksh STDOUT: |
273 |
['', ''] |
274 |
## END |
275 |
## N-I mksh status: 1 |
276 |
|
277 |
#### myvar=typeset (another form of dynamic assignment) |
278 |
myvar=typeset |
279 |
x='a b' |
280 |
$myvar x=$x |
281 |
echo $x |
282 |
## STDOUT: |
283 |
a |
284 |
## END |
285 |
## OK osh STDOUT: |
286 |
a b |
287 |
## END |
288 |
|
289 |
#### dynamic array parsing is not allowed |
290 |
code='x=(1 2 3)' |
291 |
typeset -a "$code" # note: -a flag is required |
292 |
echo status=$? |
293 |
argv.py "$x" |
294 |
## STDOUT: |
295 |
status=1 |
296 |
[''] |
297 |
## END |
298 |
## OK mksh STDOUT: |
299 |
status=0 |
300 |
['(1 2 3)'] |
301 |
## END |
302 |
# bash allows it |
303 |
## OK bash STDOUT: |
304 |
status=0 |
305 |
['1'] |
306 |
## END |
307 |
|
308 |
#### dynamic flag in array in assign builtin |
309 |
typeset b |
310 |
b=(unused1 unused2) # this works in mksh |
311 |
|
312 |
a=(x 'foo=F' 'bar=B') |
313 |
typeset -"${a[@]}" |
314 |
echo foo=$foo |
315 |
echo bar=$bar |
316 |
printenv.py foo |
317 |
printenv.py bar |
318 |
|
319 |
# syntax error in mksh! But works in bash and zsh. |
320 |
#typeset -"${a[@]}" b=(spam eggs) |
321 |
#echo "length of b = ${#b[@]}" |
322 |
#echo "b[0]=${b[0]}" |
323 |
#echo "b[1]=${b[1]}" |
324 |
|
325 |
## STDOUT: |
326 |
foo=F |
327 |
bar=B |
328 |
F |
329 |
B |
330 |
## END |
331 |
|
332 |
#### typeset +x |
333 |
export e=E |
334 |
printenv.py e |
335 |
typeset +x e=E2 |
336 |
printenv.py e # no longer exported |
337 |
## STDOUT: |
338 |
E |
339 |
None |
340 |
## END |
341 |
|
342 |
#### typeset +r removes read-only attribute |
343 |
readonly r=r1 |
344 |
echo r=$r |
345 |
|
346 |
# clear the readonly flag. Why is this accepted in bash/mksh, but doesn't do |
347 |
# anything? |
348 |
typeset +r r=r2 |
349 |
echo r=$r |
350 |
|
351 |
r=r3 |
352 |
echo r=$r |
353 |
|
354 |
## status: 0 |
355 |
## STDOUT: |
356 |
r=r1 |
357 |
r=r2 |
358 |
r=r3 |
359 |
## END |
360 |
|
361 |
# bash doesn't allow you to unset |
362 |
## OK mksh status: 2 |
363 |
## OK mksh STDOUT: |
364 |
r=r1 |
365 |
## END |
366 |
|
367 |
# bash doesn't allow you to unset |
368 |
## OK bash status: 0 |
369 |
## OK bash STDOUT: |
370 |
r=r1 |
371 |
r=r1 |
372 |
r=r1 |
373 |
## END |