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 ## STDERR:
104 ## END
105
106 #### type -> not found
107 type zz 2>err.txt
108 echo status=$?
109 grep -o 'not found' err.txt
110 ## STDOUT:
111 status=1
112 not found
113 ## END
114
115 #### type -p and -P builtin -> file
116 touch /tmp/{mv,tar,grep}
117 chmod +x /tmp/{mv,tar,grep}
118 PATH=/tmp:$PATH
119
120 type -p mv tar grep
121 echo --
122 type -P mv tar grep
123 ## STDOUT:
124 /tmp/mv
125 /tmp/tar
126 /tmp/grep
127 --
128 /tmp/mv
129 /tmp/tar
130 /tmp/grep
131 ## END
132
133 #### type -p builtin -> not found
134 type -p FOO BAR NOT_FOUND
135 ## status: 1
136 ## stdout-json: ""
137
138 #### type -p builtin -> not a file
139 type -p cd type builtin command
140 ## stdout-json: ""
141
142 #### type -P builtin -> not found
143 type -P FOO BAR NOT_FOUND
144 ## status: 1
145 ## stdout-json: ""
146
147 #### type -P builtin -> not a file
148 type -P cd type builtin command
149 ## stdout-json: ""
150 ## status: 1
151
152 #### type -P builtin -> not a file but file found
153 touch /tmp/{mv,tar,grep}
154 chmod +x /tmp/{mv,tar,grep}
155 PATH=/tmp:$PATH
156
157 mv () { ls; }
158 tar () { ls; }
159 grep () { ls; }
160 type -P mv tar grep cd builtin command type
161 ## status: 1
162 ## STDOUT:
163 /tmp/mv
164 /tmp/tar
165 /tmp/grep
166 ## END
167
168 #### type -f builtin -> not found
169 type -f FOO BAR NOT FOUND
170 ## status: 1
171
172 #### type -f builtin -> function and file exists
173 touch /tmp/{mv,tar,grep}
174 chmod +x /tmp/{mv,tar,grep}
175 PATH=/tmp:$PATH
176
177 mv () { ls; }
178 tar () { ls; }
179 grep () { ls; }
180 type -f mv tar grep
181 ## STDOUT:
182 /tmp/mv is a file
183 /tmp/tar is a file
184 /tmp/grep is a file
185 ## OK bash STDOUT:
186 mv is /tmp/mv
187 tar is /tmp/tar
188 grep is /tmp/grep
189 ## END
190
191 #### mapfile
192 type mapfile >/dev/null 2>&1 || exit 0
193 printf '%s\n' {1..5..2} | {
194 mapfile
195 echo "n=${#MAPFILE[@]}"
196 printf '[%s]\n' "${MAPFILE[@]}"
197 }
198 ## STDOUT:
199 n=3
200 [1
201 ]
202 [3
203 ]
204 [5
205 ]
206 ## END
207 ## N-I dash/mksh/zsh/ash stdout-json: ""
208
209 #### readarray (synonym for mapfile)
210 type readarray >/dev/null 2>&1 || exit 0
211 printf '%s\n' {1..5..2} | {
212 readarray
213 echo "n=${#MAPFILE[@]}"
214 printf '[%s]\n' "${MAPFILE[@]}"
215 }
216 ## STDOUT:
217 n=3
218 [1
219 ]
220 [3
221 ]
222 [5
223 ]
224 ## END
225 ## N-I dash/mksh/zsh/ash stdout-json: ""
226
227 #### mapfile (array name): arr
228 type mapfile >/dev/null 2>&1 || exit 0
229 printf '%s\n' {1..5..2} | {
230 mapfile arr
231 echo "n=${#arr[@]}"
232 printf '[%s]\n' "${arr[@]}"
233 }
234 ## STDOUT:
235 n=3
236 [1
237 ]
238 [3
239 ]
240 [5
241 ]
242 ## END
243 ## N-I dash/mksh/zsh/ash stdout-json: ""
244
245 #### mapfile (delimiter): -d delim
246 # Note: Bash-4.4+
247 type mapfile >/dev/null 2>&1 || exit 0
248 printf '%s:' {1..5..2} | {
249 mapfile -d : arr
250 echo "n=${#arr[@]}"
251 printf '[%s]\n' "${arr[@]}"
252 }
253 ## STDOUT:
254 n=3
255 [1:]
256 [3:]
257 [5:]
258 ## END
259 ## N-I dash/mksh/zsh/ash stdout-json: ""
260
261 #### mapfile (delimiter): -d '' (null-separated)
262 # Note: Bash-4.4+
263 type mapfile >/dev/null 2>&1 || exit 0
264 printf '%s\0' {1..5..2} | {
265 mapfile -d '' arr
266 echo "n=${#arr[@]}"
267 printf '[%s]\n' "${arr[@]}"
268 }
269 ## STDOUT:
270 n=3
271 [1]
272 [3]
273 [5]
274 ## END
275 ## N-I dash/mksh/zsh/ash stdout-json: ""
276
277 #### mapfile (truncate delim): -t
278 type mapfile >/dev/null 2>&1 || exit 0
279 printf '%s\n' {1..5..2} | {
280 mapfile -t arr
281 echo "n=${#arr[@]}"
282 printf '[%s]\n' "${arr[@]}"
283 }
284 ## STDOUT:
285 n=3
286 [1]
287 [3]
288 [5]
289 ## END
290 ## N-I dash/mksh/zsh/ash stdout-json: ""
291
292 #### mapfile -t doesn't remove \r
293 type mapfile >/dev/null 2>&1 || exit 0
294 printf '%s\r\n' {1..5..2} | {
295 mapfile -t arr
296 argv.py "${arr[@]}"
297 }
298 ## STDOUT:
299 ['1\r', '3\r', '5\r']
300 ## END
301 ## N-I dash/mksh/zsh/ash stdout-json: ""
302
303 #### mapfile (store position): -O start
304 type mapfile >/dev/null 2>&1 || exit 0
305 printf '%s\n' a{0..2} | {
306 arr=(x y z)
307 mapfile -O 2 -t arr
308 echo "n=${#arr[@]}"
309 printf '[%s]\n' "${arr[@]}"
310 }
311 ## STDOUT:
312 n=5
313 [x]
314 [y]
315 [a0]
316 [a1]
317 [a2]
318 ## END
319 ## N-I dash/mksh/zsh/ash stdout-json: ""
320
321 #### mapfile (input range): -s start -n count
322 type mapfile >/dev/null 2>&1 || exit 0
323 printf '%s\n' a{0..10} | {
324 mapfile -s 5 -n 3 -t arr
325 echo "n=${#arr[@]}"
326 printf '[%s]\n' "${arr[@]}"
327 }
328 ## STDOUT:
329 n=3
330 [a5]
331 [a6]
332 [a7]
333 ## END
334 ## N-I dash/mksh/zsh/ash stdout-json: ""
335
336 #### mapfile / readarray stdin TODO: Fix me.
337 shopt -s lastpipe # for bash
338
339 seq 2 | mapfile m
340 seq 3 | readarray r
341 echo ${#m[@]}
342 echo ${#r[@]}
343 ## STDOUT:
344 2
345 3
346 ## END