1 ## oils_failures_allowed: 0
2 ## compare_shells: dash bash mksh zsh
3
4
5
6 #### command -v
7 myfunc() { echo x; }
8 command -v echo
9 echo $?
10
11 command -v myfunc
12 echo $?
13
14 command -v nonexistent # doesn't print anything
15 echo nonexistent=$?
16
17 command -v '' # BUG FIX, shouldn't succeed
18 echo empty=$?
19
20 command -v for
21 echo $?
22
23 ## STDOUT:
24 echo
25 0
26 myfunc
27 0
28 nonexistent=1
29 empty=1
30 for
31 0
32 ## OK dash STDOUT:
33 echo
34 0
35 myfunc
36 0
37 nonexistent=127
38 empty=127
39 for
40 0
41 ## END
42
43 #### command -v with multiple names
44 # ALL FOUR SHELLS behave differently here!
45 #
46 # bash chooses to swallow the error! We agree with zsh if ANY word lookup
47 # fails, then the whole thing fails.
48
49 myfunc() { echo x; }
50 command -v echo myfunc ZZZ for
51 echo status=$?
52
53 ## STDOUT:
54 echo
55 myfunc
56 for
57 status=1
58 ## BUG bash STDOUT:
59 echo
60 myfunc
61 for
62 status=0
63 ## BUG dash STDOUT:
64 echo
65 status=0
66 ## OK mksh STDOUT:
67 echo
68 myfunc
69 status=1
70 ## END
71
72 #### command -v doesn't find non-executable file
73 # PATH resolution is different
74
75 PATH="_tmp:$PATH"
76 touch _tmp/non-executable _tmp/executable
77 chmod +x _tmp/executable
78
79 command -v _tmp/non-executable
80 echo status=$?
81
82 command -v _tmp/executable
83 echo status=$?
84
85 ## STDOUT:
86 status=1
87 _tmp/executable
88 status=0
89 ## END
90
91 ## BUG dash STDOUT:
92 _tmp/non-executable
93 status=0
94 _tmp/executable
95 status=0
96 ## END
97
98 #### command -V
99 myfunc() { echo x; }
100
101 shopt -s expand_aliases
102 alias ll='ls -l'
103
104 backtick=\`
105 command -V ll | sed "s/$backtick/'/g"
106 echo status=$?
107
108 command -V echo
109 echo status=$?
110
111 command -V myfunc
112 echo status=$?
113
114 command -V nonexistent # doesn't print anything
115 echo status=$?
116
117 command -V for
118 echo status=$?
119
120 ## STDOUT:
121 ll is an alias for "ls -l"
122 status=0
123 echo is a shell builtin
124 status=0
125 myfunc is a shell function
126 status=0
127 status=1
128 for is a shell keyword
129 status=0
130 ## END
131
132 ## OK zsh STDOUT:
133 ll is an alias for ls -l
134 status=0
135 echo is a shell builtin
136 status=0
137 myfunc is a shell function
138 status=0
139 nonexistent not found
140 status=1
141 for is a reserved word
142 status=0
143 ## END
144
145 ## OK bash STDOUT:
146 ll is aliased to 'ls -l'
147 status=0
148 echo is a shell builtin
149 status=0
150 myfunc is a function
151 myfunc ()
152 {
153 echo x
154 }
155 status=0
156 status=1
157 for is a shell keyword
158 status=0
159 ## END
160
161 ## OK mksh STDOUT:
162 ll is an alias for 'ls -l'
163 status=0
164 echo is a shell builtin
165 status=0
166 myfunc is a function
167 status=0
168 nonexistent not found
169 status=1
170 for is a reserved word
171 status=0
172 ## END
173
174 ## OK dash STDOUT:
175 ll is an alias for ls -l
176 status=0
177 echo is a shell builtin
178 status=0
179 myfunc is a shell function
180 status=0
181 nonexistent: not found
182 status=127
183 for is a shell keyword
184 status=0
185 ## END
186
187 #### command -V nonexistent
188 command -V nonexistent 2>err.txt
189 echo status=$?
190 fgrep -o 'nonexistent: not found' err.txt || true
191
192 ## STDOUT:
193 status=1
194 nonexistent: not found
195 ## END
196
197 ## OK zsh/mksh STDOUT:
198 nonexistent not found
199 status=1
200 ## END
201
202 ## BUG dash STDOUT:
203 nonexistent: not found
204 status=127
205 ## END
206
207
208 #### command skips function lookup
209 seq() {
210 echo "$@"
211 }
212 command # no-op
213 seq 3
214 command seq 3
215 # subshell shouldn't fork another process (but we don't have a good way of
216 # testing it)
217 ( command seq 3 )
218 ## STDOUT:
219 3
220 1
221 2
222 3
223 1
224 2
225 3
226 ## END
227
228 #### command command seq 3
229 command command seq 3
230 ## STDOUT:
231 1
232 2
233 3
234 ## END
235 ## N-I zsh stdout-json: ""
236 ## N-I zsh status: 127
237
238 #### command command -v seq
239 seq() {
240 echo 3
241 }
242 command command -v seq
243 ## stdout: seq
244 ## N-I zsh stdout-json: ""
245 ## N-I zsh status: 127
246
247 #### command -p (override existing program)
248 # Tests whether command -p overrides the path
249 # tr chosen because we need a simple non-builtin
250 mkdir -p $TMP/bin
251 echo "echo wrong" > $TMP/bin/tr
252 chmod +x $TMP/bin/tr
253 PATH="$TMP/bin:$PATH"
254 echo aaa | tr "a" "b"
255 echo aaa | command -p tr "a" "b"
256 rm $TMP/bin/tr
257 ## STDOUT:
258 wrong
259 bbb
260 ## END
261
262 #### command -p (hide tool in custom path)
263 mkdir -p $TMP/bin
264 echo "echo hello" > $TMP/bin/hello
265 chmod +x $TMP/bin/hello
266 export PATH=$TMP/bin
267 command -p hello
268 ## status: 127
269
270 #### command -p (find hidden tool in default path)
271 export PATH=''
272 command -p ls
273 ## status: 0
274
275
276 #### $(command type ls)
277 type() { echo FUNCTION; }
278 type
279 s=$(command type echo)
280 echo $s | grep builtin > /dev/null
281 echo status=$?
282 ## STDOUT:
283 FUNCTION
284 status=0
285 ## END
286 ## N-I zsh STDOUT:
287 FUNCTION
288 status=1
289 ## END
290 ## N-I mksh STDOUT:
291 status=1
292 ## END
293
294 #### builtin
295 cd () { echo "hi"; }
296 cd
297 builtin cd / && pwd
298 unset -f cd
299 ## STDOUT:
300 hi
301 /
302 ## END
303 ## N-I dash STDOUT:
304 hi
305 ## END
306
307 #### builtin ls not found
308 builtin ls
309 ## status: 1
310 ## N-I dash status: 127
311
312 #### builtin no args
313 builtin
314 ## status: 0
315 ## N-I dash status: 127
316
317 #### builtin command echo hi
318 builtin command echo hi
319 ## status: 0
320 ## stdout: hi
321 ## N-I dash status: 127
322 ## N-I dash stdout-json: ""