1 ## compare_shells: bash dash mksh zsh
2
3
4 # Interesting interpretation of constants.
5 #
6 # "Constants with a leading 0 are interpreted as octal numbers. A leading ‘0x’
7 # or ‘0X’ denotes hexadecimal. Otherwise, numbers take the form [base#]n, where
8 # the optional base is a decimal number between 2 and 64 representing the
9 # arithmetic base, and n is a number in that base. If base# is omitted, then
10 # base 10 is used. When specifying n, the digits greater than 9 are represented
11 # by the lowercase letters, the uppercase letters, ‘@’, and ‘_’, in that order.
12 # If base is less than or equal to 36, lowercase and uppercase letters may be
13 # used interchangeably to represent numbers between 10 and 35. "
14 #
15 # NOTE $(( 8#9 )) can fail, and this can be done at parse time...
16
17 #### Side Effect in Array Indexing
18 a=(4 5 6)
19 echo "${a[b=2]} b=$b"
20 ## stdout: 6 b=2
21 ## OK zsh stdout: 5 b=2
22 ## N-I dash stdout-json: ""
23 ## N-I dash status: 2
24
25 #### Add one to var
26 i=1
27 echo $(($i+1))
28 ## stdout: 2
29
30 #### $ is optional
31 i=1
32 echo $((i+1))
33 ## stdout: 2
34
35 #### SimpleVarSub within arith
36 j=0
37 echo $(($j + 42))
38 ## stdout: 42
39
40 #### BracedVarSub within ArithSub
41 echo $((${j:-5} + 1))
42 ## stdout: 6
43
44 #### Arith word part
45 foo=1; echo $((foo+1))bar$(($foo+1))
46 ## stdout: 2bar2
47
48 #### Arith sub with word parts
49 # Making 13 from two different kinds of sub. Geez.
50 echo $((1 + $(echo 1)${undefined:-3}))
51 ## stdout: 14
52
53 #### Constant with quotes like '1'
54 # NOTE: Compare with [[. That is a COMMAND level expression, while this is a
55 # WORD level expression.
56 echo $(('1' + 2))
57 ## status: 0
58 ## N-I bash/zsh status: 1
59 ## N-I dash status: 2
60
61 #### Arith sub within arith sub
62 # This is unnecessary but works in all shells.
63 echo $((1 + $((2 + 3)) + 4))
64 ## stdout: 10
65
66 #### Backticks within arith sub
67 # This is unnecessary but works in all shells.
68 echo $((`echo 1` + 2))
69 ## stdout: 3
70
71 #### Invalid string to int
72 # bash, mksh, and zsh all treat strings that don't look like numbers as zero.
73 shopt -u strict_arith || true
74 s=foo
75 echo $((s+5))
76 ## OK dash stdout-json: ""
77 ## OK dash status: 2
78 ## OK bash/mksh/zsh/osh stdout: 5
79 ## OK bash/mksh/zsh/osh status: 0
80
81 #### Invalid string to int with strict_arith
82 shopt -s strict_arith || true
83 s=foo
84 echo $s
85 echo $((s+5))
86 echo 'should not get here'
87 ## status: 1
88 ## STDOUT:
89 foo
90 ## END
91 ## OK dash status: 2
92 ## N-I bash/mksh/zsh STDOUT:
93 foo
94 5
95 should not get here
96 ## END
97 ## N-I bash/mksh/zsh status: 0
98
99 #### Integer constant parsing
100 echo $(( 0x12A ))
101 echo $(( 0x0A ))
102 echo $(( 0777 ))
103 echo $(( 0010 ))
104 echo $(( 24#ag7 ))
105 ## STDOUT:
106 298
107 10
108 511
109 8
110 6151
111 ## END
112
113 ## N-I dash status: 2
114 ## N-I dash STDOUT:
115 298
116 10
117 511
118 8
119 ## END
120
121 ## BUG zsh STDOUT:
122 298
123 10
124 777
125 10
126 6151
127 ## END
128
129 ## BUG mksh STDOUT:
130 298
131 10
132 777
133 10
134 6151
135 ## END
136
137 #### Integer constant validation
138 check() {
139 $SH -c "shopt --set strict_arith; echo $1"
140 echo status=$?
141 }
142
143 check '$(( 0x1X ))'
144 check '$(( 09 ))'
145 check '$(( 2#A ))'
146 check '$(( 02#0110 ))'
147 ## STDOUT:
148 status=1
149 status=1
150 status=1
151 status=1
152 ## END
153
154 ## OK dash STDOUT:
155 status=2
156 status=2
157 status=2
158 status=2
159 ## END
160
161 ## BUG zsh STDOUT:
162 status=1
163 9
164 status=0
165 status=1
166 6
167 status=0
168 ## END
169
170 ## BUG mksh STDOUT:
171 status=1
172 9
173 status=0
174 status=1
175 6
176 status=0
177 ## END
178
179 #### Newline in the middle of expression
180 echo $((1
181 + 2))
182 ## stdout: 3
183
184 #### Ternary operator
185 a=1
186 b=2
187 echo $((a>b?5:10))
188 ## stdout: 10
189
190 #### Preincrement
191 a=4
192 echo $((++a))
193 echo $a
194 ## stdout-json: "5\n5\n"
195 ## N-I dash status: 0
196 ## N-I dash stdout-json: "4\n4\n"
197
198 #### Postincrement
199 a=4
200 echo $((a++))
201 echo $a
202 ## stdout-json: "4\n5\n"
203 ## N-I dash status: 2
204 ## N-I dash stdout-json: ""
205
206 #### Increment undefined variables
207 shopt -u strict_arith || true
208 (( undef1++ ))
209 (( ++undef2 ))
210 echo "[$undef1][$undef2]"
211 ## stdout: [1][1]
212 ## N-I dash stdout: [][]
213
214 #### Increment and decrement array elements
215 shopt -u strict_arith || true
216 a=(5 6 7 8)
217 (( a[0]++, ++a[1], a[2]--, --a[3] ))
218 (( undef[0]++, ++undef[1], undef[2]--, --undef[3] ))
219 echo "${a[@]}" - "${undef[@]}"
220 ## stdout: 6 7 6 7 - 1 1 -1 -1
221 ## N-I dash stdout-json: ""
222 ## N-I dash status: 2
223 ## BUG zsh stdout: 5 6 7 8 -
224
225 #### Increment undefined variables with nounset
226 set -o nounset
227 (( undef1++ ))
228 (( ++undef2 ))
229 echo "[$undef1][$undef2]"
230 ## stdout-json: ""
231 ## status: 1
232 ## OK dash status: 2
233 ## BUG mksh/zsh status: 0
234 ## BUG mksh/zsh stdout-json: "[1][1]\n"
235
236 #### Comma operator (borrowed from C)
237 a=1
238 b=2
239 echo $((a,(b+1)))
240 ## stdout: 3
241 ## N-I dash status: 2
242 ## N-I dash stdout-json: ""
243
244 #### Augmented assignment
245 a=4
246 echo $((a+=1))
247 echo $a
248 ## stdout-json: "5\n5\n"
249
250 #### Comparison Ops
251 echo $(( 1 == 1 ))
252 echo $(( 1 != 1 ))
253 echo $(( 1 < 1 ))
254 echo $(( 1 <= 1 ))
255 echo $(( 1 > 1 ))
256 echo $(( 1 >= 1 ))
257 ## stdout-json: "1\n0\n0\n1\n0\n1\n"
258
259 #### Logical Ops
260 echo $((1 || 2))
261 echo $((1 && 2))
262 echo $((!(1 || 2)))
263 ## stdout-json: "1\n1\n0\n"
264
265 #### Logical Ops Short Circuit
266 x=11
267 (( 1 || (x = 22) ))
268 echo $x
269 (( 0 || (x = 33) ))
270 echo $x
271 (( 0 && (x = 44) ))
272 echo $x
273 (( 1 && (x = 55) ))
274 echo $x
275 ## stdout-json: "11\n33\n33\n55\n"
276 ## N-I dash stdout-json: "11\n11\n11\n11\n"
277
278 #### Bitwise ops
279 echo $((1|2))
280 echo $((1&2))
281 echo $((1^2))
282 echo $((~(1|2)))
283 ## stdout-json: "3\n0\n3\n-4\n"
284
285 #### Unary minus and plus
286 a=1
287 b=3
288 echo $((- a + + b))
289 ## stdout-json: "2\n"
290
291 #### No floating point
292 echo $((1 + 2.3))
293 ## status: 2
294 ## OK bash/mksh status: 1
295 ## BUG zsh status: 0
296
297 #### Array indexing in arith
298 # zsh does 1-based indexing!
299 array=(1 2 3 4)
300 echo $((array[1] + array[2]*3))
301 ## stdout: 11
302 ## OK zsh stdout: 7
303 ## N-I dash status: 2
304 ## N-I dash stdout-json: ""
305
306 #### Constants in base 36
307 echo $((36#a))-$((36#z))
308 ## stdout: 10-35
309 ## N-I dash stdout-json: ""
310 ## N-I dash status: 2
311
312 #### Constants in bases 2 to 64
313 # This is a truly bizarre syntax. Oh it comes from zsh... which allows 36.
314 echo $((64#a))-$((64#z)), $((64#A))-$((64#Z)), $((64#@)), $(( 64#_ ))
315 ## stdout: 10-35, 36-61, 62, 63
316 ## N-I dash stdout-json: ""
317 ## N-I dash status: 2
318 ## N-I mksh/zsh stdout-json: ""
319 ## N-I mksh/zsh status: 1
320
321 #### Multiple digit constants with base N
322 echo $((10#0123)), $((16#1b))
323 ## stdout: 123, 27
324 ## N-I dash stdout-json: ""
325 ## N-I dash status: 2
326
327 #### Dynamic base constants
328 base=16
329 echo $(( ${base}#a ))
330 ## stdout: 10
331 ## N-I dash stdout-json: ""
332 ## N-I dash status: 2
333
334 #### Octal constant
335 echo $(( 011 ))
336 ## stdout: 9
337 ## N-I mksh/zsh stdout: 11
338
339 #### Dynamic octal constant
340 zero=0
341 echo $(( ${zero}11 ))
342 ## stdout: 9
343 ## N-I mksh/zsh stdout: 11
344
345 #### Dynamic hex constants
346 zero=0
347 echo $(( ${zero}xAB ))
348 ## stdout: 171
349
350 #### Dynamic var names - result of runtime parse/eval
351 foo=5
352 x=oo
353 echo $(( foo + f$x + 1 ))
354 ## stdout: 11
355
356 #### Recursive name evaluation is a result of runtime parse/eval
357 foo=5
358 bar=foo
359 spam=bar
360 eggs=spam
361 echo $((foo+1)) $((bar+1)) $((spam+1)) $((eggs+1))
362 ## stdout: 6 6 6 6
363 ## N-I dash stdout-json: ""
364 ## N-I dash status: 2
365
366 #### nounset with arithmetic
367 set -o nounset
368 x=$(( y + 5 ))
369 echo "should not get here: x=${x:-<unset>}"
370 ## stdout-json: ""
371 ## status: 1
372 ## BUG dash/mksh/zsh stdout: should not get here: x=5
373 ## BUG dash/mksh/zsh status: 0
374
375 #### 64-bit integer doesn't overflow
376
377 a=$(( 1 << 31 ))
378 echo $a
379
380 b=$(( a + a ))
381 echo $b
382
383 c=$(( b + a ))
384 echo $c
385
386 x=$(( 1 << 62 ))
387 y=$(( x - 1 ))
388 echo "max positive = $(( x + y ))"
389
390 #echo "overflow $(( x + x ))"
391
392 ## STDOUT:
393 2147483648
394 4294967296
395 6442450944
396 max positive = 9223372036854775807
397 ## END
398
399 # mksh still uses int!
400 ## BUG mksh STDOUT:
401 -2147483648
402 0
403 -2147483648
404 max positive = 2147483647
405 ## END
406
407 #### More 64-bit ops
408 case $SH in dash) exit ;; esac
409
410 #shopt -s strict_arith
411
412 # This overflows - the extra 9 puts it above 2**31
413 #echo $(( 12345678909 ))
414
415 [[ 12345678909 = $(( 1 << 30 )) ]]
416 echo eq=$?
417 [[ 12345678909 = 12345678909 ]]
418 echo eq=$?
419
420 # Try both [ and [[
421 [ 12345678909 -gt $(( 1 << 30 )) ]
422 echo greater=$?
423 [[ 12345678909 -gt $(( 1 << 30 )) ]]
424 echo greater=$?
425
426 [[ 12345678909 -ge $(( 1 << 30 )) ]]
427 echo ge=$?
428 [[ 12345678909 -ge 12345678909 ]]
429 echo ge=$?
430
431 [[ 12345678909 -le $(( 1 << 30 )) ]]
432 echo le=$?
433 [[ 12345678909 -le 12345678909 ]]
434 echo le=$?
435
436 ## STDOUT:
437 eq=1
438 eq=0
439 greater=0
440 greater=0
441 ge=0
442 ge=0
443 le=1
444 le=0
445 ## END
446 ## N-I dash STDOUT:
447 ## END
448 ## BUG mksh STDOUT:
449 eq=1
450 eq=0
451 greater=1
452 greater=1
453 ge=1
454 ge=0
455 le=0
456 le=0
457 ## END
458
459 # mksh still uses int!
460
461 #### Invalid LValue
462 a=9
463 (( (a + 2) = 3 ))
464 echo $a
465 ## status: 2
466 ## stdout-json: ""
467 ## OK bash/mksh/zsh stdout: 9
468 ## OK bash/mksh/zsh status: 0
469 # dash doesn't implement assignment
470 ## N-I dash status: 2
471 ## N-I dash stdout-json: ""
472
473 #### Invalid LValue that looks like array
474 (( 1[2] = 3 ))
475 echo "status=$?"
476 ## status: 1
477 ## stdout-json: ""
478
479 ## OK bash stdout: status=1
480 ## OK bash status: 0
481
482 ## OK mksh/zsh stdout: status=2
483 ## OK mksh/zsh status: 0
484
485 ## N-I dash stdout: status=127
486 ## N-I dash status: 0
487
488 #### Invalid LValue: two sets of brackets
489 (( a[1][2] = 3 ))
490 echo "status=$?"
491 # shells treat this as a NON-fatal error
492 ## status: 2
493 ## stdout-json: ""
494 ## OK bash stdout: status=1
495 ## OK mksh/zsh stdout: status=2
496 ## OK bash/mksh/zsh status: 0
497 # dash doesn't implement assignment
498 ## N-I dash stdout: status=127
499 ## N-I dash status: 0
500
501 #### Operator Precedence
502 echo $(( 1 + 2*3 - 8/2 ))
503 ## stdout: 3
504
505 #### Exponentiation with **
506 echo $(( 3 ** 0 ))
507 echo $(( 3 ** 1 ))
508 echo $(( 3 ** 2 ))
509 ## STDOUT:
510 1
511 3
512 9
513 ## END
514 ## N-I dash stdout-json: ""
515 ## N-I dash status: 2
516 ## N-I mksh stdout-json: ""
517 ## N-I mksh status: 1
518
519 #### Exponentiation operator has buggy precedence
520 # NOTE: All shells agree on this, but R and Python give -9, which is more
521 # mathematically correct.
522 echo $(( -3 ** 2 ))
523 ## stdout: 9
524 ## N-I dash stdout-json: ""
525 ## N-I dash status: 2
526 ## N-I mksh stdout-json: ""
527 ## N-I mksh status: 1
528
529 #### Negative exponent
530 # bash explicitly disallows negative exponents!
531 echo $(( 2**-1 * 5 ))
532 ## stdout-json: ""
533 ## status: 1
534 ## OK zsh stdout: 2.5
535 ## OK zsh status: 0
536 ## N-I dash stdout-json: ""
537 ## N-I dash status: 2
538
539 #### Comment not allowed in the middle of multiline arithmetic
540 echo $((
541 1 +
542 2 + \
543 3
544 ))
545 echo $((
546 1 + 2 # not a comment
547 ))
548 (( a = 3 + 4 # comment
549 ))
550 echo [$a]
551 ## status: 1
552 ## STDOUT:
553 6
554 ## END
555 ## OK dash/osh status: 2
556 ## OK bash STDOUT:
557 6
558 []
559 ## END
560 ## OK bash status: 0
561
562 #### Add integer to indexed array (a[0] decay)
563 declare -a array=(1 2 3)
564 echo $((array + 5))
565 ## status: 0
566 ## STDOUT:
567 6
568 ## END
569 ## N-I dash status: 2
570 ## N-I dash stdout-json: ""
571 ## N-I mksh/zsh status: 1
572 ## N-I mksh/zsh stdout-json: ""
573
574 #### Add integer to associative array (a[0] decay)
575 typeset -A assoc
576 assoc[0]=42
577 echo $((assoc + 5))
578 ## status: 0
579 ## stdout: 47
580 ## BUG dash status: 0
581 ## BUG dash stdout: 5
582
583 #### Double subscript
584 a=(1 2 3)
585 echo $(( a[1] ))
586 echo $(( a[1][1] ))
587 ## status: 1
588 ## OK osh status: 2
589 ## STDOUT:
590 2
591 ## END
592 ## N-I dash status: 2
593 ## N-I dash stdout-json: ""
594 ## OK zsh STDOUT:
595 1
596 ## END
597
598 #### result of ArithSub -- array[0] decay
599 a=(4 5 6)
600 echo declared
601 b=$(( a ))
602 echo $b
603
604 ## status: 0
605 ## STDOUT:
606 declared
607 4
608 ## END
609 ## N-I dash status: 2
610 ## N-I dash stdout-json: ""
611 ## N-I zsh status: 1
612 ## N-I zsh STDOUT:
613 declared
614 ## END
615
616 #### result of ArithSub -- assoc[0] decay
617 declare -A A=(['foo']=bar ['spam']=eggs)
618 echo declared
619 b=$(( A ))
620 echo $b
621
622 ## status: 0
623 ## STDOUT:
624 declared
625 0
626 ## END
627
628 ## N-I mksh status: 1
629 ## N-I mksh stdout-json: ""
630
631
632 ## N-I dash status: 2
633 ## N-I dash stdout-json: ""
634
635 #### comma operator
636 a=(4 5 6)
637
638 # zsh and osh can't evaluate the array like that
639 # which is consistent with their behavior on $(( a ))
640
641 echo $(( a, last = a[2], 42 ))
642 echo last=$last
643
644 ## status: 0
645 ## STDOUT:
646 42
647 last=6
648 ## END
649 ## N-I dash status: 2
650 ## N-I dash stdout-json: ""
651 ## N-I zsh status: 1
652 ## N-I zsh stdout-json: ""
653
654
655 #### assignment with dynamic var name
656 foo=bar
657 echo $(( x$foo = 42 ))
658 echo xbar=$xbar
659 ## STDOUT:
660 42
661 xbar=42
662 ## END
663
664 #### array assignment with dynamic array name
665 foo=bar
666 echo $(( x$foo[5] = 42 ))
667 echo 'xbar[5]='${xbar[5]}
668 ## STDOUT:
669 42
670 xbar[5]=42
671 ## END
672 ## BUG zsh STDOUT:
673 42
674 xbar[5]=
675 ## END
676 ## N-I dash status: 2
677 ## N-I dash stdout-json: ""
678
679 #### unary assignment with dynamic var name
680 foo=bar
681 xbar=42
682 echo $(( x$foo++ ))
683 echo xbar=$xbar
684 ## STDOUT:
685 42
686 xbar=43
687 ## END
688 ## BUG dash status: 2
689 ## BUG dash stdout-json: ""
690
691 #### unary array assignment with dynamic var name
692 foo=bar
693 xbar[5]=42
694 echo $(( x$foo[5]++ ))
695 echo 'xbar[5]='${xbar[5]}
696 ## STDOUT:
697 42
698 xbar[5]=43
699 ## END
700 ## BUG zsh STDOUT:
701 0
702 xbar[5]=42
703 ## END
704 ## N-I dash status: 2
705 ## N-I dash stdout-json: ""
706
707 #### Dynamic parsing of arithmetic
708 e=1+2
709 echo $(( e + 3 ))
710 [[ e -eq 3 ]] && echo true
711 [ e -eq 3 ]
712 echo status=$?
713 ## STDOUT:
714 6
715 true
716 status=2
717 ## END
718 ## BUG mksh STDOUT:
719 6
720 true
721 status=0
722 ## END
723 ## N-I dash status: 2
724 ## N-I dash stdout-json: ""
725
726 #### Dynamic parsing on empty string
727 a=''
728 echo $(( a ))
729
730 a2=' '
731 echo $(( a2 ))
732 ## STDOUT:
733 0
734 0
735 ## END
736
737 #### nested ternary (bug fix)
738 echo $((1?2?3:4:5))
739 ## STDOUT:
740 3
741 ## END
742
743 #### 1 ? a=1 : b=2 ( bug fix)
744 echo $((1 ? a=1 : 42 ))
745 echo a=$a
746
747 # this does NOT work
748 #echo $((1 ? a=1 : b=2 ))
749
750 ## STDOUT:
751 1
752 a=1
753 ## END
754 ## BUG zsh stdout-json: ""
755 ## BUG zsh status: 1
756
757 #### Invalid constant
758
759 echo $((a + x42))
760 echo status=$?
761
762 # weird asymmetry -- the above is a syntax error, but this isn't
763 $SH -c 'echo $((a + 42x))'
764 echo status=$?
765
766 # regression
767 echo $((a + 42x))
768 echo status=$?
769 ## status: 1
770 ## STDOUT:
771 0
772 status=0
773 status=1
774 ## END
775 ## OK dash status: 2
776 ## OK dash STDOUT:
777 0
778 status=0
779 status=2
780 ## END
781 ## BUG bash status: 0
782 ## BUG bash STDOUT:
783 0
784 status=0
785 status=1
786 status=1
787 ## END
788
789 #### Negative numbers with integer division /
790
791 echo $(( 10 / 3))
792 echo $((-10 / 3))
793 echo $(( 10 / -3))
794 echo $((-10 / -3))
795
796 echo ---
797
798 a=20
799 : $(( a /= 3 ))
800 echo $a
801
802 a=-20
803 : $(( a /= 3 ))
804 echo $a
805
806 a=20
807 : $(( a /= -3 ))
808 echo $a
809
810 a=-20
811 : $(( a /= -3 ))
812 echo $a
813
814 ## STDOUT:
815 3
816 -3
817 -3
818 3
819 ---
820 6
821 -6
822 -6
823 6
824 ## END
825
826 #### Negative numbers with %
827
828 echo $(( 10 % 3))
829 echo $((-10 % 3))
830 echo $(( 10 % -3))
831 echo $((-10 % -3))
832
833 ## STDOUT:
834 1
835 -1
836 1
837 -1
838 ## END
839
840 #### Negative numbers with bit shift
841
842 echo $(( 5 << 1 ))
843 echo $(( 5 << 0 ))
844 $SH -c 'echo $(( 5 << -1 ))' # implementation defined - OSH fails
845 echo ---
846
847 echo $(( 16 >> 1 ))
848 echo $(( 16 >> 0 ))
849 $SH -c 'echo $(( 16 >> -1 ))' # not sure why this is zero
850 $SH -c 'echo $(( 16 >> -2 ))' # also 0
851 echo ---
852
853 ## STDOUT:
854 10
855 5
856 ---
857 8
858 16
859 ---
860 ## END
861
862 ## OK bash/dash/mksh/zsh STDOUT:
863 10
864 5
865 -9223372036854775808
866 ---
867 8
868 16
869 0
870 0
871 ---
872 ## END
873
874 ## BUG mksh STDOUT:
875 10
876 5
877 -2147483648
878 ---
879 8
880 16
881 0
882 0
883 ---
884 ## END
885
886 #### undef[0]
887 case $SH in dash) exit ;; esac
888
889 echo ARITH $(( undef[0] ))
890 echo status=$?
891 echo
892
893 (( undef[0] ))
894 echo status=$?
895 echo
896
897 echo UNDEF ${undef[0]}
898 echo status=$?
899
900 ## STDOUT:
901 ARITH 0
902 status=0
903
904 status=1
905
906 UNDEF
907 status=0
908 ## END
909 ## N-I dash STDOUT:
910 ## END
911
912 #### undef[0] with nounset
913 case $SH in dash) exit ;; esac
914
915 set -o nounset
916 echo UNSET $(( undef[0] ))
917 echo status=$?
918
919 ## status: 1
920 ## STDOUT:
921 ## END
922
923 ## N-I dash status: 0
924
925 ## BUG mksh/zsh status: 0
926 ## BUG mksh/zsh STDOUT:
927 UNSET 0
928 status=0
929 ## END
930
931 ## N-I dash STDOUT:
932 ## END
933
934 #### s[0] with string abc
935 case $SH in dash) exit ;; esac
936
937 s='abc'
938 echo abc $(( s[0] )) $(( s[1] ))
939 echo status=$?
940 echo
941
942 (( s[0] ))
943 echo status=$?
944 echo
945
946 ## STDOUT:
947 abc 0 0
948 status=0
949
950 status=1
951
952 ## END
953 ## N-I dash STDOUT:
954 ## END
955
956 #### s[0] with string 42
957 case $SH in dash) exit ;; esac
958
959 s='42'
960 echo 42 $(( s[0] )) $(( s[1] ))
961 echo status=$?
962
963 ## STDOUT:
964 42 42 0
965 status=0
966 ## END
967 ## N-I dash STDOUT:
968 ## END
969
970 ## BUG zsh STDOUT:
971 42 0 4
972 status=0
973 ## END
974
975 #### s[0] with string '12 34'
976
977 s='12 34'
978 echo '12 34' $(( s[0] )) $(( s[1] ))
979 echo status=$?
980
981 ## status: 1
982 ## STDOUT:
983 ## END
984
985 ## OK dash status: 2
986
987 ## BUG zsh status: 0
988 ## BUG zsh STDOUT:
989 12 34 0 1
990 status=0
991 ## END
992
993 # bash prints an error, but doesn't fail
994
995 ## BUG bash status: 0
996 ## BUG bash STDOUT:
997 status=1
998 ## END