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