1 ## compare_shells: dash bash mksh zsh
2
3 # Miscellaneous tests for the command language.
4
5 #### Command block
6 PATH=/bin
7
8 { which ls; }
9 ## stdout: /bin/ls
10
11 #### Permission denied
12 touch $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
28 env | grep _OVM
29 echo status=$?
30 ## stdout: status=1
31
32 #### File with no shebang is executed
33 # most shells execute /bin/sh; bash may execute itself
34 echo 'echo hi' > $TMP/no-shebang
35 chmod +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
41 cd $TMP
42 echo 'echo hi' > no-shebang
43 chmod +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
49 cd $TMP
50 mkdir -p test-no-shebang
51 echo 'echo hi' > test-no-shebang/script
52 chmod +x test-no-shebang/script
53 "$SH" -c 'test-no-shebang/script'
54 ## stdout: hi
55 ## status: 0
56
57 #### $PATH lookup
58 cd $TMP
59 mkdir -p one two
60 echo 'echo one' > one/mycmd
61 echo 'echo two' > two/mycmd
62 chmod +x one/mycmd two/mycmd
63
64 PATH='one:two'
65 mycmd
66 ## STDOUT:
67 one
68 ## END
69
70 #### filling $PATH cache, then insert the same command earlier in cache
71 cd $TMP
72 PATH="one:two:$PATH"
73 mkdir -p one two
74 rm -f one/* two/*
75 echo 'echo two' > two/mycmd
76 chmod +x two/mycmd
77 mycmd
78
79 # Insert earlier in the path
80 echo 'echo one' > one/mycmd
81 chmod +x one/mycmd
82 mycmd # still runs the cached 'two'
83
84 # clear the cache
85 hash -r
86 mycmd # now it runs the new 'one'
87
88 ## STDOUT:
89 two
90 two
91 one
92 ## END
93
94 # zsh doesn't do caching!
95 ## OK zsh STDOUT:
96 two
97 one
98 one
99 ## END
100
101 #### filling $PATH cache, then deleting command
102 cd $TMP
103 PATH="one:two:$PATH"
104 mkdir -p one two
105 rm -f one/mycmd two/mycmd
106
107 echo 'echo two' > two/mycmd
108 chmod +x two/mycmd
109 mycmd
110 echo status=$?
111
112 # Insert earlier in the path
113 echo 'echo one' > one/mycmd
114 chmod +x one/mycmd
115 rm two/mycmd
116 mycmd # still runs the cached 'two'
117 echo status=$?
118
119 ## STDOUT:
120 two
121 status=0
122 status=127
123 ## END
124
125 # mksh and zsh correctly searches for the executable again!
126 ## OK zsh/mksh STDOUT:
127 two
128 status=0
129 one
130 status=0
131 ## END
132
133 #### Non-executable on $PATH
134
135 # shells differ in whether they actually execve('one/cmd') and get EPERM
136
137 mkdir -p one two
138 PATH="one:two:$PATH"
139
140 rm -f one/mycmd two/mycmd
141 echo 'echo one' > one/mycmd
142 echo 'echo two' > two/mycmd
143
144 # only make the second one executable
145 chmod +x two/mycmd
146 mycmd
147 echo status=$?
148
149 ## STDOUT:
150 two
151 status=0
152 ## END
153
154 #### hash without args prints the cache
155 whoami >/dev/null
156 hash
157 echo status=$?
158 ## STDOUT:
159 /usr/bin/whoami
160 status=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:
167 whoami=/usr/bin/whoami
168 status=0
169 ## END
170
171 #### hash with args
172 hash whoami
173 echo status=$?
174 hash | grep -o /whoami # prints it twice
175 hash _nonexistent_
176 echo status=$?
177 ## STDOUT:
178 status=0
179 /whoami
180 status=1
181 ## END
182
183 # mksh doesn't fail
184 ## BUG mksh STDOUT:
185 status=0
186 /whoami
187 status=0
188 ## END
189
190 #### hash -r doesn't allow additional args
191 hash -r whoami >/dev/null # avoid weird output with mksh
192 echo status=$?
193 ## stdout: status=1
194 ## OK osh stdout: status=2
195 ## BUG dash/bash stdout: status=0