1 ## compare_shells: bash-4.4 mksh zsh
2
3 #### (( )) result
4 (( 1 )) && echo True
5 (( 0 )) || echo False
6 ## STDOUT:
7 True
8 False
9 ## END
10
11 #### negative number is true
12 (( -1 )) && echo True
13 ## stdout: True
14
15 #### (( )) in if statement
16 if (( 3 > 2)); then
17 echo True
18 fi
19 ## stdout: True
20
21 #### (( ))
22 # What is the difference with this and let? One difference: spaces are allowed.
23 (( x = 1 ))
24 (( y = x + 2 ))
25 echo $x $y
26 ## stdout: 1 3
27
28 #### (( )) with arrays
29 a=(4 5 6)
30 (( sum = a[0] + a[1] + a[2] ))
31 echo $sum
32 ## stdout: 15
33 ## OK zsh stdout: 9
34
35 #### (( )) with error
36 (( a = 0 )) || echo false
37 (( b = 1 )) && echo true
38 (( c = -1 )) && echo true
39 echo $((a + b + c))
40 ## STDOUT:
41 false
42 true
43 true
44 0
45 ## END
46
47
48 #### bash and mksh: V in (( a[K] = V )) gets coerced to integer
49 shopt -u strict_arith || true
50 K=key
51 V=value
52 typeset -a a
53 (( a[K] = V ))
54
55 # not there!
56 echo a[\"key\"]=${a[$K]}
57
58 echo keys = ${!a[@]}
59 echo values = ${a[@]}
60 ## STDOUT:
61 a["key"]=0
62 keys = 0
63 values = 0
64 ## END
65 ## N-I zsh status: 1
66 ## N-I zsh stdout-json: ""
67
68 #### bash: K in (( A[K] = V )) is a constant string
69 K=5
70 V=42
71 typeset -A A
72 (( A[K] = V ))
73
74 echo A["5"]=${A["5"]}
75 echo keys = ${!A[@]}
76 echo values = ${A[@]}
77 ## STDOUT:
78 A[5]=
79 keys = K
80 values = 42
81 ## END
82 ## OK osh status: 1
83 ## OK osh stdout-json: ""
84 ## N-I zsh status: 1
85 ## N-I zsh stdout-json: ""
86 ## N-I mksh status: 1
87 ## N-I mksh stdout-json: ""
88
89 #### BUG: (( V = A[K] )) doesn't retrieve the right value
90 typeset -A A
91 K=5
92 V=42
93 A["$K"]=$V
94 A["K"]=oops
95 A[K]=oops2
96
97 # We don't neither 42 nor "oops". Bad!
98 (( V = A[K] ))
99
100 echo V=$V
101 ## status: 1
102 ## stdout-json: ""
103 ## BUG bash/zsh status: 0
104 ## BUG bash/zsh STDOUT:
105 V=0
106 ## END
107
108 #### bash: V in (( A["K"] = V )) gets coerced to integer
109 shopt -u strict_arith || true
110 K=key
111 V=value
112 typeset -A A || exit 1
113 (( A["K"] = V ))
114
115 # not there!
116 echo A[\"key\"]=${A[$K]}
117
118 echo keys = ${!A[@]}
119 echo values = ${A[@]}
120 ## STDOUT:
121 A["key"]=
122 keys = K
123 values = 0
124 ## END
125 ## N-I zsh stdout-json: ""
126 ## N-I zsh status: 1
127 ## N-I mksh stdout-json: ""
128 ## N-I mksh status: 1
129
130 #### literal strings inside (( ))
131 declare -A A
132 A['x']=42
133 (( x = A['x'] ))
134 (( A['y'] = 'y' )) # y is a variable, gets coerced to 0
135 echo $x ${A['y']}
136 ## STDOUT:
137 42 0
138 ## END
139 ## N-I mksh status: 0
140 ## N-I mksh STDOUT:
141 0
142 ## END
143 ## N-I zsh status: 0
144 ## N-I zsh STDOUT:
145 42
146 ## END
147
148 #### (( )) with redirect
149 (( a = $(stdout_stderr.py 42) + 10 )) 2>$TMP/x.txt
150 echo $a
151 echo --
152 cat $TMP/x.txt
153 ## STDOUT:
154 52
155 --
156 STDERR
157 ## END
158
159 #### Assigning whole raray (( b = a ))
160 a=(4 5 6)
161 (( b = a ))
162
163 echo "${a[@]}"
164
165 # OSH doesn't like this
166 echo "${b[@]}"
167
168 ## status: 0
169 ## STDOUT:
170 4 5 6
171 4
172 ## END
173 ## BUG zsh status: 0
174 ## BUG zsh STDOUT:
175 4 5 6
176
177 ## END
178
179 #### set associative array
180 declare -A A=(['foo']=bar ['spam']=42)
181 (( x = A['spam'] ))
182 echo $x
183 ## STDOUT:
184 42
185 ## END
186 ## N-I mksh status: 1
187 ## N-I mksh stdout-json: ""
188 ## N-I zsh STDOUT:
189 0
190 ## END
191
192 #### Example of incrementing associative array entry with var key (ble.sh)
193 declare -A A=(['foo']=42)
194 key='foo'
195
196 # note: in bash, (( A[\$key] += 1 )) works the same way.
197
198 set -- 1 2
199 (( A[$key] += $2 ))
200
201 echo foo=${A['foo']}
202
203 ## STDOUT:
204 foo=44
205 ## END
206 ## N-I mksh/zsh status: 1
207 ## N-I mksh/zsh stdout-json: ""
208