1 #!/usr/bin/env bash
2
3 #### Lazy Evaluation of Alternative
4 i=0
5 x=x
6 echo ${x:-$((i++))}
7 echo $i
8 echo ${undefined:-$((i++))}
9 echo $i # i is one because the alternative was only evaluated once
10 ## status: 0
11 ## stdout-json: "x\n0\n0\n1\n"
12 ## N-I dash status: 2
13 ## N-I dash stdout-json: "x\n0\n"
14
15 #### Default value when empty
16 empty=''
17 echo ${empty:-is empty}
18 ## stdout: is empty
19
20 #### Default value when unset
21 echo ${unset-is unset}
22 ## stdout: is unset
23
24 #### Unquoted with array as default value
25 set -- '1 2' '3 4'
26 argv.py X${unset=x"$@"x}X
27 argv.py X${unset=x$@x}X # If you want OSH to split, write this
28 # osh
29 ## STDOUT:
30 ['Xx1', '2', '3', '4xX']
31 ['Xx1', '2', '3', '4xX']
32 ## END
33 ## OK osh STDOUT:
34 ['Xx1 2', '3 4xX']
35 ['Xx1', '2', '3', '4xX']
36 ## END
37
38 #### Quoted with array as default value
39 set -- '1 2' '3 4'
40 argv.py "X${unset=x"$@"x}X"
41 argv.py "X${unset=x$@x}X" # OSH is the same here
42 ## STDOUT:
43 ['Xx1 2 3 4xX']
44 ['Xx1 2 3 4xX']
45 ## END
46 ## BUG bash STDOUT:
47 ['Xx1', '2', '3', '4xX']
48 ['Xx1 2 3 4xX']
49 ## END
50 ## OK osh STDOUT:
51 ['Xx1 2', '3 4xX']
52 ['Xx1 2 3 4xX']
53 ## END
54
55 #### Assign default with array
56 set -- '1 2' '3 4'
57 argv.py X${unset=x"$@"x}X
58 argv.py "$unset"
59 ## STDOUT:
60 ['Xx1', '2', '3', '4xX']
61 ['x1 2 3 4x']
62 ## END
63 ## OK osh STDOUT:
64 ['Xx1 2', '3 4xX']
65 ['x1 2 3 4x']
66 ## END
67
68 #### Assign default value when empty
69 empty=''
70 ${empty:=is empty}
71 echo $empty
72 ## stdout: is empty
73
74 #### Assign default value when unset
75 ${unset=is unset}
76 echo $unset
77 ## stdout: is unset
78
79 #### Alternative value when empty
80 v=foo
81 empty=''
82 echo ${v:+v is not empty} ${empty:+is not empty}
83 ## stdout: v is not empty
84
85 #### Alternative value when unset
86 v=foo
87 echo ${v+v is not unset} ${unset:+is not unset}
88 ## stdout: v is not unset
89
90 #### Error when empty
91 empty=''
92 echo ${empty:?'is em'pty} # test eval of error
93 echo should not get here
94 ## stdout-json: ""
95 ## status: 1
96 ## OK dash status: 2
97
98 #### Error when unset
99 echo ${unset?is empty}
100 echo should not get here
101 ## stdout-json: ""
102 ## status: 1
103 ## OK dash status: 2
104
105 #### Error when unset
106 v=foo
107 echo ${v+v is not unset} ${unset:+is not unset}
108 ## stdout: v is not unset
109
110 #### ${var=x} dynamic scope
111 f() { : "${hello:=x}"; echo $hello; }
112 f
113 echo hello=$hello
114
115 f() { hello=x; }
116 f
117 echo hello=$hello
118 ## STDOUT:
119 x
120 hello=x
121 hello=x
122 ## END
123
124 #### array ${arr[0]=x}
125 arr=()
126 echo ${#arr[@]}
127 : ${arr[0]=x}
128 echo ${#arr[@]}
129 ## STDOUT:
130 0
131 1
132 ## END
133 ## N-I dash status: 2
134 ## N-I dash stdout-json: ""
135
136 #### assoc array ${arr["k"]=x}
137 # note: this also works in zsh
138
139 declare -A arr=()
140 echo ${#arr[@]}
141 : ${arr['k']=x}
142 echo ${#arr[@]}
143 ## STDOUT:
144 0
145 1
146 ## END
147 ## N-I dash status: 2
148 ## N-I dash stdout-json: ""
149 ## N-I mksh status: 1
150 ## N-I mksh stdout-json: ""
151
152 #### "\z" as arg
153 echo "${undef-\$}"
154 echo "${undef-\(}"
155 echo "${undef-\z}"
156 echo "${undef-\"}"
157 echo "${undef-\`}"
158 echo "${undef-\\}"
159 ## STDOUT:
160 $
161 \(
162 \z
163 "
164 `
165 \
166 ## END
167 ## BUG yash STDOUT:
168 $
169 (
170 z
171 "
172 `
173 \
174 ## END
175
176 #### "\e" as arg
177 echo "${undef-\e}"
178 ## STDOUT:
179 \e
180 ## END
181 ## BUG zsh/mksh stdout-repr: '\x1b\n'
182 ## BUG yash stdout: e
183