OILS / spec / builtin-meta.test.sh View on Github | oilshell.org

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