1 # builtins specific to bash and OSH
2
3 #### help
4 help
5 echo status=$? >&2
6 help help
7 echo status=$? >&2
8 help -- help
9 echo status=$? >&2
10 ## STDERR:
11 status=0
12 status=0
13 status=0
14 ## END
15
16 #### bad help topic
17 help ZZZ 2>$TMP/err.txt
18 echo "help=$?"
19 cat $TMP/err.txt | grep -i 'no help topics' >/dev/null
20 echo "grep=$?"
21 ## STDOUT:
22 help=1
23 grep=0
24 ## END
25
26 #### type -t -> function
27 f() { echo hi; }
28 type -t f
29 ## stdout: function
30
31 #### type -t -> alias
32 shopt -s expand_aliases
33 alias foo=bar
34 type -t foo
35 ## stdout: alias
36
37 #### type -t -> builtin
38 type -t echo read : [ declare local
39 ## STDOUT:
40 builtin
41 builtin
42 builtin
43 builtin
44 builtin
45 builtin
46 ## END
47
48 #### type -t -> keyword
49 type -t for time ! fi do {
50 ## STDOUT:
51 keyword
52 keyword
53 keyword
54 keyword
55 keyword
56 keyword
57 ## END
58
59 #### type -t control flow
60
61 # this differs from bash, but don't lie!
62 type -t break continue return exit
63 ## STDOUT:
64 keyword
65 keyword
66 keyword
67 keyword
68 ## END
69 ## OK bash STDOUT:
70 builtin
71 builtin
72 builtin
73 builtin
74 ## END
75
76
77 #### type -t -> file
78 type -t find xargs
79 ## STDOUT:
80 file
81 file
82 ## END
83
84 #### type -t doesn't find non-executable (like command -v)
85 PATH="$TMP:$PATH"
86 touch $TMP/non-executable
87 type -t non-executable
88 ## stdout-json: ""
89 ## status: 1
90 ## BUG bash STDOUT:
91 file
92 ## END
93 ## BUG bash status: 0
94
95 #### type -t -> not found
96 type -t echo ZZZ find =
97 echo status=$?
98 ## STDOUT:
99 builtin
100 file
101 status=1
102 ## END
103
104 #### type -p and -P builtin -> file
105 touch /tmp/{mv,tar,grep}
106 chmod +x /tmp/{mv,tar,grep}
107 PATH=/tmp:$PATH
108
109 type -p mv tar grep
110 echo --
111 type -P mv tar grep
112 ## STDOUT:
113 /tmp/mv
114 /tmp/tar
115 /tmp/grep
116 --
117 /tmp/mv
118 /tmp/tar
119 /tmp/grep
120 ## END
121
122 #### type -p builtin -> not found
123 type -p FOO BAR NOT_FOUND
124 ## status: 1
125 ## stdout-json: ""
126
127 #### type -p builtin -> not a file
128 type -p cd type builtin command
129 ## stdout-json: ""
130
131 #### type -P builtin -> not found
132 type -P FOO BAR NOT_FOUND
133 ## status: 1
134 ## stdout-json: ""
135
136 #### type -P builtin -> not a file
137 type -P cd type builtin command
138 ## stdout-json: ""
139 ## status: 1
140
141 #### type -P builtin -> not a file but file found
142 touch /tmp/{mv,tar,grep}
143 chmod +x /tmp/{mv,tar,grep}
144 PATH=/tmp:$PATH
145
146 mv () { ls; }
147 tar () { ls; }
148 grep () { ls; }
149 type -P mv tar grep cd builtin command type
150 ## status: 1
151 ## STDOUT:
152 /tmp/mv
153 /tmp/tar
154 /tmp/grep
155 ## END
156
157 #### type -f builtin -> not found
158 type -f FOO BAR NOT FOUND
159 ## status: 1
160
161 #### type -f builtin -> function and file exists
162 touch /tmp/{mv,tar,grep}
163 chmod +x /tmp/{mv,tar,grep}
164 PATH=/tmp:$PATH
165
166 mv () { ls; }
167 tar () { ls; }
168 grep () { ls; }
169 type -f mv tar grep
170 ## STDOUT:
171 /tmp/mv is a file
172 /tmp/tar is a file
173 /tmp/grep is a file
174 ## OK bash STDOUT:
175 mv is /tmp/mv
176 tar is /tmp/tar
177 grep is /tmp/grep
178 ## END
179
180 #### mapfile
181 type mapfile >/dev/null 2>&1 || exit 0
182 printf '%s\n' {1..5..2} | {
183 mapfile
184 echo "n=${#MAPFILE[@]}"
185 printf '[%s]\n' "${MAPFILE[@]}"
186 }
187 ## STDOUT:
188 n=3
189 [1
190 ]
191 [3
192 ]
193 [5
194 ]
195 ## END
196 ## N-I dash/mksh/zsh/ash stdout-json: ""
197
198 #### readarray (synonym for mapfile)
199 type readarray >/dev/null 2>&1 || exit 0
200 printf '%s\n' {1..5..2} | {
201 readarray
202 echo "n=${#MAPFILE[@]}"
203 printf '[%s]\n' "${MAPFILE[@]}"
204 }
205 ## STDOUT:
206 n=3
207 [1
208 ]
209 [3
210 ]
211 [5
212 ]
213 ## END
214 ## N-I dash/mksh/zsh/ash stdout-json: ""
215
216 #### mapfile (array name): arr
217 type mapfile >/dev/null 2>&1 || exit 0
218 printf '%s\n' {1..5..2} | {
219 mapfile arr
220 echo "n=${#arr[@]}"
221 printf '[%s]\n' "${arr[@]}"
222 }
223 ## STDOUT:
224 n=3
225 [1
226 ]
227 [3
228 ]
229 [5
230 ]
231 ## END
232 ## N-I dash/mksh/zsh/ash stdout-json: ""
233
234 #### mapfile (delimiter): -d delim
235 # Note: Bash-4.4+
236 type mapfile >/dev/null 2>&1 || exit 0
237 printf '%s:' {1..5..2} | {
238 mapfile -d : arr
239 echo "n=${#arr[@]}"
240 printf '[%s]\n' "${arr[@]}"
241 }
242 ## STDOUT:
243 n=3
244 [1:]
245 [3:]
246 [5:]
247 ## END
248 ## N-I dash/mksh/zsh/ash stdout-json: ""
249
250 #### mapfile (delimiter): -d '' (null-separated)
251 # Note: Bash-4.4+
252 type mapfile >/dev/null 2>&1 || exit 0
253 printf '%s\0' {1..5..2} | {
254 mapfile -d '' arr
255 echo "n=${#arr[@]}"
256 printf '[%s]\n' "${arr[@]}"
257 }
258 ## STDOUT:
259 n=3
260 [1]
261 [3]
262 [5]
263 ## END
264 ## N-I dash/mksh/zsh/ash stdout-json: ""
265
266 #### mapfile (truncate delim): -t
267 type mapfile >/dev/null 2>&1 || exit 0
268 printf '%s\n' {1..5..2} | {
269 mapfile -t arr
270 echo "n=${#arr[@]}"
271 printf '[%s]\n' "${arr[@]}"
272 }
273 ## STDOUT:
274 n=3
275 [1]
276 [3]
277 [5]
278 ## END
279 ## N-I dash/mksh/zsh/ash stdout-json: ""
280
281 #### mapfile -t doesn't remove \r
282 type mapfile >/dev/null 2>&1 || exit 0
283 printf '%s\r\n' {1..5..2} | {
284 mapfile -t arr
285 argv.py "${arr[@]}"
286 }
287 ## STDOUT:
288 ['1\r', '3\r', '5\r']
289 ## END
290 ## N-I dash/mksh/zsh/ash stdout-json: ""
291
292 #### mapfile (store position): -O start
293 type mapfile >/dev/null 2>&1 || exit 0
294 printf '%s\n' a{0..2} | {
295 arr=(x y z)
296 mapfile -O 2 -t arr
297 echo "n=${#arr[@]}"
298 printf '[%s]\n' "${arr[@]}"
299 }
300 ## STDOUT:
301 n=5
302 [x]
303 [y]
304 [a0]
305 [a1]
306 [a2]
307 ## END
308 ## N-I dash/mksh/zsh/ash stdout-json: ""
309
310 #### mapfile (input range): -s start -n count
311 type mapfile >/dev/null 2>&1 || exit 0
312 printf '%s\n' a{0..10} | {
313 mapfile -s 5 -n 3 -t arr
314 echo "n=${#arr[@]}"
315 printf '[%s]\n' "${arr[@]}"
316 }
317 ## STDOUT:
318 n=3
319 [a5]
320 [a6]
321 [a7]
322 ## END
323 ## N-I dash/mksh/zsh/ash stdout-json: ""
324
325 #### mapfile / readarray stdin TODO: Fix me.
326 shopt -s lastpipe # for bash
327
328 seq 2 | mapfile m
329 seq 3 | readarray r
330 echo ${#m[@]}
331 echo ${#r[@]}
332 ## STDOUT:
333 2
334 3
335 ## END