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