1 ## oils_failures_allowed: 6
2 ## compare_shells: dash bash mksh zsh
3
4 #### command -v
5 myfunc() { echo x; }
6 command -v echo
7 echo $?
8
9 command -v myfunc
10 echo $?
11
12 command -v nonexistent # doesn't print anything
13 echo nonexistent=$?
14
15 command -v '' # BUG FIX, shouldn't succeed
16 echo empty=$?
17
18 command -v for
19 echo $?
20
21 ## STDOUT:
22 echo
23 0
24 myfunc
25 0
26 nonexistent=1
27 empty=1
28 for
29 0
30 ## OK dash STDOUT:
31 echo
32 0
33 myfunc
34 0
35 nonexistent=127
36 empty=127
37 for
38 0
39 ## END
40
41 #### command -v with multiple names
42 # ALL FOUR SHELLS behave differently here!
43 #
44 # bash chooses to swallow the error! We agree with zsh if ANY word lookup
45 # fails, then the whole thing fails.
46
47 myfunc() { echo x; }
48 command -v echo myfunc ZZZ for
49 echo status=$?
50
51 ## STDOUT:
52 echo
53 myfunc
54 for
55 status=1
56 ## BUG bash STDOUT:
57 echo
58 myfunc
59 for
60 status=0
61 ## BUG dash STDOUT:
62 echo
63 status=0
64 ## OK mksh STDOUT:
65 echo
66 myfunc
67 status=1
68 ## END
69
70 #### command -v doesn't find non-executable file
71 # PATH resolution is different
72
73 PATH="_tmp:$PATH"
74 touch _tmp/non-executable _tmp/executable
75 chmod +x _tmp/executable
76
77 command -v _tmp/non-executable
78 echo status=$?
79
80 command -v _tmp/executable
81 echo status=$?
82
83 ## STDOUT:
84 status=1
85 _tmp/executable
86 status=0
87 ## END
88
89 ## BUG dash STDOUT:
90 _tmp/non-executable
91 status=0
92 _tmp/executable
93 status=0
94 ## END
95
96 #### command -V
97 myfunc() { echo x; }
98
99 shopt -s expand_aliases
100 alias ll='ls -l'
101
102 backtick=\`
103 command -V ll | sed "s/$backtick/'/g"
104 echo status=$?
105
106 command -V echo
107 echo status=$?
108
109 command -V myfunc
110 echo status=$?
111
112 command -V nonexistent # doesn't print anything
113 echo status=$?
114
115 command -V for
116 echo status=$?
117
118 ## STDOUT:
119 ll is an alias for "ls -l"
120 status=0
121 echo is a shell builtin
122 status=0
123 myfunc is a shell function
124 status=0
125 status=1
126 for is a shell keyword
127 status=0
128 ## END
129
130 ## OK zsh STDOUT:
131 ll is an alias for ls -l
132 status=0
133 echo is a shell builtin
134 status=0
135 myfunc is a shell function
136 status=0
137 nonexistent not found
138 status=1
139 for is a reserved word
140 status=0
141 ## END
142
143 ## OK bash STDOUT:
144 ll is aliased to 'ls -l'
145 status=0
146 echo is a shell builtin
147 status=0
148 myfunc is a function
149 myfunc ()
150 {
151 echo x
152 }
153 status=0
154 status=1
155 for is a shell keyword
156 status=0
157 ## END
158
159 ## OK mksh STDOUT:
160 ll is an alias for 'ls -l'
161 status=0
162 echo is a shell builtin
163 status=0
164 myfunc is a function
165 status=0
166 nonexistent not found
167 status=1
168 for is a reserved word
169 status=0
170 ## END
171
172 ## OK dash STDOUT:
173 ll is an alias for ls -l
174 status=0
175 echo is a shell builtin
176 status=0
177 myfunc is a shell function
178 status=0
179 nonexistent: not found
180 status=127
181 for is a shell keyword
182 status=0
183 ## END
184
185 #### command -V nonexistent
186 command -V nonexistent 2>err.txt
187 echo status=$?
188 fgrep -o 'nonexistent: not found' err.txt || true
189
190 ## STDOUT:
191 status=1
192 nonexistent: not found
193 ## END
194
195 ## OK zsh/mksh STDOUT:
196 nonexistent not found
197 status=1
198 ## END
199
200 ## BUG dash STDOUT:
201 nonexistent: not found
202 status=127
203 ## END
204
205
206 #### command skips function lookup
207 seq() {
208 echo "$@"
209 }
210 command # no-op
211 seq 3
212 command seq 3
213 # subshell shouldn't fork another process (but we don't have a good way of
214 # testing it)
215 ( command seq 3 )
216 ## STDOUT:
217 3
218 1
219 2
220 3
221 1
222 2
223 3
224 ## END
225
226 #### command command seq 3
227 command command seq 3
228 ## STDOUT:
229 1
230 2
231 3
232 ## END
233 ## N-I zsh stdout-json: ""
234 ## N-I zsh status: 127
235
236 #### command command -v seq
237 seq() {
238 echo 3
239 }
240 command command -v seq
241 ## stdout: seq
242 ## N-I zsh stdout-json: ""
243 ## N-I zsh status: 127
244
245 #### command -p (override existing program)
246 # Tests whether command -p overrides the path
247 # tr chosen because we need a simple non-builtin
248 mkdir -p $TMP/bin
249 echo "echo wrong" > $TMP/bin/tr
250 chmod +x $TMP/bin/tr
251 PATH="$TMP/bin:$PATH"
252 echo aaa | tr "a" "b"
253 echo aaa | command -p tr "a" "b"
254 rm $TMP/bin/tr
255 ## STDOUT:
256 wrong
257 bbb
258 ## END
259
260 #### command -p (hide tool in custom path)
261 mkdir -p $TMP/bin
262 echo "echo hello" > $TMP/bin/hello
263 chmod +x $TMP/bin/hello
264 export PATH=$TMP/bin
265 command -p hello
266 ## status: 127
267
268 #### command -p (find hidden tool in default path)
269 export PATH=''
270 command -p ls
271 ## status: 0
272
273
274 #### $(command type ls)
275 type() { echo FUNCTION; }
276 type
277 s=$(command type echo)
278 echo $s | grep builtin > /dev/null
279 echo status=$?
280 ## STDOUT:
281 FUNCTION
282 status=0
283 ## END
284 ## N-I zsh STDOUT:
285 FUNCTION
286 status=1
287 ## END
288 ## N-I mksh STDOUT:
289 status=1
290 ## END
291
292 #### builtin
293 cd () { echo "hi"; }
294 cd
295 builtin cd / && pwd
296 unset -f cd
297 ## STDOUT:
298 hi
299 /
300 ## END
301 ## N-I dash STDOUT:
302 hi
303 ## END
304
305 #### builtin ls not found
306 builtin ls
307 ## status: 1
308 ## N-I dash status: 127
309
310 #### builtin no args
311 builtin
312 ## status: 0
313 ## N-I dash status: 127
314
315 #### builtin command echo hi
316 builtin command echo hi
317 ## status: 0
318 ## stdout: hi
319 ## N-I dash status: 127
320 ## N-I dash stdout-json: ""
321
322 #### builtin typeset / export / readonly
323 case $SH in dash) exit ;; esac
324
325 builtin typeset s=typeset
326 echo s=$s
327
328 builtin export s=export
329 echo s=$s
330
331 builtin readonly s=readonly
332 echo s=$s
333
334 echo --
335
336 builtin builtin typeset s2=typeset
337 echo s2=$s2
338
339 builtin builtin export s2=export
340 echo s2=$s2
341
342 builtin builtin readonly s2=readonly
343 echo s2=$s2
344
345 ## STDOUT:
346 s=typeset
347 s=export
348 s=readonly
349 --
350 s2=typeset
351 s2=export
352 s2=readonly
353 ## END
354 ## N-I dash STDOUT:
355 ## END
356
357 #### builtin declare / local
358 case $SH in dash|mksh) exit ;; esac
359
360 builtin declare s=declare
361 echo s=$s
362
363 f() {
364 builtin local s=local
365 echo s=$s
366 }
367
368 f
369
370 ## STDOUT:
371 s=declare
372 s=local
373 ## END
374 ## N-I dash/mksh STDOUT:
375 ## END
376
377 #### builtin declare etc. with array is not parsed
378
379 $SH -c 'builtin declare a=(x y)'
380 test $? -ne 0 && echo 'fail'
381
382 $SH -c 'builtin declare -a a=(x y)'
383 test $? -ne 0 && echo 'fail'
384
385 ## STDOUT:
386 fail
387 fail
388 ## END
389
390 #### command export / readonly
391 case $SH in zsh) exit ;; esac
392
393 # dash doesn't have declare typeset
394
395 command export c=export
396 echo c=$c
397
398 command readonly c=readonly
399 echo c=$c
400
401 echo --
402
403 command command export cc=export
404 echo cc=$cc
405
406 command command readonly cc=readonly
407 echo cc=$cc
408
409 ## STDOUT:
410 c=export
411 c=readonly
412 --
413 cc=export
414 cc=readonly
415 ## END
416 ## N-I zsh STDOUT:
417 ## END
418
419 #### command local
420
421 f() {
422 command local s=local
423 echo s=$s
424 }
425
426 f
427
428 ## STDOUT:
429 s=local
430 ## END
431 ## BUG dash/mksh/zsh STDOUT:
432 s=
433 ## END
434
435
436 #### static builtin command ASSIGN, command builtin ASSIGN
437 case $SH in dash|zsh) exit ;; esac
438
439 # dash doesn't have declare typeset
440
441 builtin command export bc=export
442 echo bc=$bc
443
444 builtin command readonly bc=readonly
445 echo bc=$bc
446
447 echo --
448
449 command builtin export cb=export
450 echo cb=$cb
451
452 command builtin readonly cb=readonly
453 echo cb=$cb
454
455 ## STDOUT:
456 bc=export
457 bc=readonly
458 --
459 cb=export
460 cb=readonly
461 ## END
462 ## N-I dash/zsh STDOUT:
463 ## END
464
465 #### dynamic builtin command ASSIGN, command builtin ASSIGN
466 case $SH in dash|zsh) exit ;; esac
467
468 b=builtin
469 c=command
470 e=export
471 r=readonly
472
473 $b $c export bc=export
474 echo bc=$bc
475
476 $b $c readonly bc=readonly
477 echo bc=$bc
478
479 echo --
480
481 $c $b export cb=export
482 echo cb=$cb
483
484 $c $b readonly cb=readonly
485 echo cb=$cb
486
487 echo --
488
489 $b $c $e bce=export
490 echo bce=$bce
491
492 $b $c $r bcr=readonly
493 echo bcr=$bcr
494
495 echo --
496
497 $c $b $e cbe=export
498 echo cbe=$cbe
499
500 $c $b $r cbr=readonly
501 echo cbr=$cbr
502
503 ## STDOUT:
504 bc=export
505 bc=readonly
506 --
507 cb=export
508 cb=readonly
509 --
510 bce=export
511 bcr=readonly
512 --
513 cbe=export
514 cbr=readonly
515 ## END
516 ## N-I dash/zsh STDOUT:
517 ## END