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