OILS / spec / command_.test.sh View on Github | oils.pub

246 lines, 122 significant
1## compare_shells: dash bash mksh zsh
2
3# Miscellaneous tests for the command language.
4
5#### Command block
6PATH=/bin
7
8{ which ls; }
9## stdout: /bin/ls
10
11#### Permission denied
12touch $TMP/text-file
13$TMP/text-file
14## status: 126
15
16#### Not a dir
17$TMP/not-a-dir/text-file
18## status: 127
19
20#### Name too long
21./0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
22## status: 127
23## OK dash status: 2
24## OK bash status: 126
25
26#### External programs don't have _OVM in environment
27# bug fix for leakage
28env | grep _OVM
29echo status=$?
30## stdout: status=1
31
32#### File with no shebang is executed
33# most shells execute /bin/sh; bash may execute itself
34echo 'echo hi' > $TMP/no-shebang
35chmod +x $TMP/no-shebang
36$SH -c '$TMP/no-shebang'
37## stdout: hi
38## status: 0
39
40#### File with relative path and no shebang is executed
41cd $TMP
42echo 'echo hi' > no-shebang
43chmod +x no-shebang
44"$SH" -c './no-shebang'
45## stdout: hi
46## status: 0
47
48#### File in relative subdirectory and no shebang is executed
49cd $TMP
50mkdir -p test-no-shebang
51echo 'echo hi' > test-no-shebang/script
52chmod +x test-no-shebang/script
53"$SH" -c 'test-no-shebang/script'
54## stdout: hi
55## status: 0
56
57#### $PATH lookup
58cd $TMP
59mkdir -p one two
60echo 'echo one' > one/mycmd
61echo 'echo two' > two/mycmd
62chmod +x one/mycmd two/mycmd
63
64PATH='one:two'
65mycmd
66## STDOUT:
67one
68## END
69
70#### filling $PATH cache, then insert the same command earlier in cache
71cd $TMP
72PATH="one:two:$PATH"
73mkdir -p one two
74rm -f one/* two/*
75echo 'echo two' > two/mycmd
76chmod +x two/mycmd
77mycmd
78
79# Insert earlier in the path
80echo 'echo one' > one/mycmd
81chmod +x one/mycmd
82mycmd # still runs the cached 'two'
83
84# clear the cache
85hash -r
86mycmd # now it runs the new 'one'
87
88## STDOUT:
89two
90two
91one
92## END
93
94# zsh doesn't do caching!
95## OK zsh STDOUT:
96two
97one
98one
99## END
100
101#### filling $PATH cache, then deleting command
102cd $TMP
103PATH="one:two:$PATH"
104mkdir -p one two
105rm -f one/mycmd two/mycmd
106
107echo 'echo two' > two/mycmd
108chmod +x two/mycmd
109mycmd
110echo status=$?
111
112# Insert earlier in the path
113echo 'echo one' > one/mycmd
114chmod +x one/mycmd
115rm two/mycmd
116mycmd # still runs the cached 'two'
117echo status=$?
118
119## STDOUT:
120two
121status=0
122status=127
123## END
124
125# mksh and zsh correctly searches for the executable again!
126## OK zsh/mksh STDOUT:
127two
128status=0
129one
130status=0
131## END
132
133#### Non-executable on $PATH
134
135# shells differ in whether they actually execve('one/cmd') and get EPERM
136
137mkdir -p one two
138PATH="one:two:$PATH"
139
140rm -f one/mycmd two/mycmd
141echo 'echo one' > one/mycmd
142echo 'echo two' > two/mycmd
143
144# only make the second one executable
145chmod +x two/mycmd
146mycmd
147echo status=$?
148
149## STDOUT:
150two
151status=0
152## END
153
154#### hash without args prints the cache
155whoami >/dev/null
156hash
157echo status=$?
158## STDOUT:
159/usr/bin/whoami
160status=0
161## END
162
163# bash uses a weird table. Although we could use TSV2.
164## OK bash stdout-json: "hits\tcommand\n 1\t/usr/bin/whoami\nstatus=0\n"
165
166## OK mksh/zsh STDOUT:
167whoami=/usr/bin/whoami
168status=0
169## END
170
171#### hash with args
172hash whoami
173echo status=$?
174hash | grep -o /whoami # prints it twice
175hash _nonexistent_
176echo status=$?
177## STDOUT:
178status=0
179/whoami
180status=1
181## END
182
183# mksh doesn't fail
184## BUG mksh STDOUT:
185status=0
186/whoami
187status=0
188## END
189
190#### hash -r doesn't allow additional args
191hash -r whoami >/dev/null # avoid weird output with mksh
192echo status=$?
193## stdout: status=1
194## OK osh stdout: status=2
195## BUG dash/bash stdout: status=0
196
197#### Executing command with same name as directory in PATH (#2429)
198
199# Make the following directory structure. File type and permission bits are
200# given on the left.
201# [drwxr-xr-x] _tmp
202# +-- [drwxr-xr-x] bin
203# |   \-- [-rwxr-xr-x] hello
204# +-- [drwxr-xr-x] notbin
205# |   \-- [-rw-r--r--] hello
206# \-- [drwxr-xr-x] dir
207# \-- [drwxr-xr-x] hello
208mkdir -p _tmp/bin
209mkdir -p _tmp/bin2
210mkdir -p _tmp/notbin
211mkdir -p _tmp/dir/hello
212printf '#!/usr/bin/env sh\necho hi\n' >_tmp/notbin/hello
213printf '#!/usr/bin/env sh\necho hi\n' >_tmp/bin/hello
214chmod +x _tmp/bin/hello
215
216DIR=$PWD/_tmp/dir
217BIN=$PWD/_tmp/bin
218NOTBIN=$PWD/_tmp/notbin
219
220# The command resolution will search the path for matching *files* (not
221# directories) WITH the execute bit set.
222
223# Should find executable hello right away and run it
224PATH="$BIN:$PATH" hello
225echo status=$?
226
227hash -r # Needed to clear the PATH cache
228
229# Will see hello dir, skip it and then find&run the hello exe
230PATH="$DIR:$BIN:$PATH" hello
231echo status=$?
232
233hash -r # Needed to clear the PATH cache
234
235# Will see hello (non-executable) file, skip it and then find&run the hello exe
236PATH="$NOTBIN:$BIN:$PATH" hello
237echo status=$?
238
239## STDOUT:
240hi
241status=0
242hi
243status=0
244hi
245status=0
246## END