1 ## compare_shells: bash
2 ## oils_failures_allowed: 8
3
4 #### sh -i
5 # Notes:
6 # - OSH prompt goes to stdout and bash goes to stderr
7 # - This test seems to fail on the system bash, but succeeds with spec-bin/bash
8 echo 'echo foo' | PS1='[prompt] ' $SH --rcfile /dev/null -i >out.txt 2>err.txt
9 fgrep -q '[prompt]' out.txt err.txt
10 echo match=$?
11 ## STDOUT:
12 match=0
13 ## END
14
15 #### \[\] are non-printing
16 PS1='\[foo\]\$'
17 echo "${PS1@P}"
18 ## STDOUT:
19 foo$
20 ## END
21
22 #### literal escapes
23 PS1='\a\e\r\n'
24 echo "${PS1@P}"
25 ## stdout-json: "\u0007\u001b\r\n\n"
26
27 #### special case for $
28 # NOTE: This might be broken for # but it's hard to tell since we don't have
29 # root. Could inject __TEST_EUID or something.
30 PS1='$'
31 echo "${PS1@P}"
32 PS1='\$'
33 echo "${PS1@P}"
34 PS1='\\$'
35 echo "${PS1@P}"
36 PS1='\\\$'
37 echo "${PS1@P}"
38 PS1='\\\\$'
39 echo "${PS1@P}"
40 ## STDOUT:
41 $
42 $
43 $
44 \$
45 \$
46 ## END
47
48 #### PS1 evaluation order
49 x='\'
50 y='h'
51 PS1='$x$y'
52 echo "${PS1@P}"
53 ## STDOUT:
54 \h
55 ## END
56
57 #### PS1 evaluation order 2
58 foo=foo_value
59 dir=$TMP/'$foo' # Directory name with a dollar!
60 mkdir -p $dir
61 cd $dir
62 PS1='\w $foo'
63 test "${PS1@P}" = "$PWD foo_value"
64 echo status=$?
65 ## STDOUT:
66 status=0
67 ## END
68
69 #### \1004
70 PS1='\1004$'
71 echo "${PS1@P}"
72 ## STDOUT:
73 @4$
74 ## END
75
76 #### \001 octal literals are supported
77 PS1='[\045]'
78 echo "${PS1@P}"
79 ## STDOUT:
80 [%]
81 ## END
82
83 #### \555 is beyond max octal byte of \377 and wrapped to m
84 PS1='\555$'
85 echo "${PS1@P}"
86 ## STDOUT:
87 m$
88 ## END
89
90 #### \x55 hex literals not supported
91 PS1='[\x55]'
92 echo "${PS1@P}"
93 ## STDOUT:
94 [\x55]
95 ## END
96
97 #### Single backslash
98 PS1='\'
99 echo "${PS1@P}"
100 ## STDOUT:
101 \
102 ## END
103
104 #### Escaped backslash
105 PS1='\\'
106 echo "${PS1@P}"
107 ## STDOUT:
108 \
109 ## END
110
111 #### \0001 octal literals are not supported
112 PS1='[\0455]'
113 echo "${PS1@P}"
114 ## STDOUT:
115 [%5]
116 ## END
117
118 #### \u0001 unicode literals not supported
119 PS1='[\u0001]'
120 USER=$(whoami)
121 test "${PS1@P}" = "[${USER}0001]"
122 echo status=$?
123 ## STDOUT:
124 status=0
125 ## END
126
127 #### constant string
128 PS1='$ '
129 echo "${PS1@P}"
130 ## STDOUT:
131 $
132 ## END
133
134 #### hostname
135
136 # NOTE: This test is not hermetic. On my machine the short and long host name
137 # are the same.
138
139 PS1='\h '
140 test "${PS1@P}" = "$(hostname -s) " # short name
141 echo status=$?
142 PS1='\H '
143 test "${PS1@P}" = "$(hostname) "
144 echo status=$?
145 ## STDOUT:
146 status=0
147 status=0
148 ## END
149
150 #### username
151 PS1='\u '
152 USER=$(whoami)
153 test "${PS1@P}" = "${USER} "
154 echo status=$?
155 ## STDOUT:
156 status=0
157 ## END
158
159 #### current working dir
160 PS1='\w '
161 test "${PS1@P}" = "${PWD} "
162 echo status=$?
163 ## STDOUT:
164 status=0
165 ## END
166
167 #### \W is basename of working dir
168 PS1='\W '
169 test "${PS1@P}" = "$(basename $PWD) "
170 echo status=$?
171 ## STDOUT:
172 status=0
173 ## END
174
175 #### \t for 24h time (HH:MM:SS)
176 PS1='foo \t bar'
177 echo "${PS1@P}" | egrep -q 'foo [0-2][0-9]:[0-5][0-9]:[0-5][0-9] bar'
178 echo matched=$?
179
180 ## STDOUT:
181 matched=0
182 ## END
183
184 #### \T for 12h time (HH:MM:SS)
185 PS1='foo \T bar'
186 echo "${PS1@P}" | egrep -q 'foo [0-1][0-9]:[0-5][0-9]:[0-5][0-9] bar'
187 echo matched=$?
188
189 ## STDOUT:
190 matched=0
191 ## END
192
193 #### \@ for 12h time (HH:MM AM/PM)
194 PS1='foo \@ bar'
195 echo "${PS1@P}" | egrep -q 'foo [0-1][0-9]:[0-5][0-9] (A|P)M bar'
196 echo matched=$?
197
198 ## STDOUT:
199 matched=0
200 ## END
201
202 #### \A for 24h time (HH:MM)
203 PS1='foo \A bar'
204 echo "${PS1@P}" | egrep -q 'foo [0-2][0-9]:[0-5][0-9] bar'
205 echo matched=$?
206 ## STDOUT:
207 matched=0
208 ## END
209
210 #### \d for date
211 PS1='foo \d bar'
212 echo "${PS1@P}" | egrep -q 'foo [A-Z][a-z]+ [A-Z][a-z]+ [0-9]+ bar'
213 echo matched=$?
214
215 ## STDOUT:
216 matched=0
217 ## END
218
219 #### \D{%H:%M} for strftime
220 PS1='foo \D{%H:%M} bar'
221 echo "${PS1@P}" | egrep -q 'foo [0-9][0-9]:[0-9][0-9] bar'
222 echo matched=$?
223
224 PS1='foo \D{%H:%M:%S} bar'
225 echo "${PS1@P}" | egrep -q 'foo [0-9][0-9]:[0-9][0-9]:[0-9][0-9] bar'
226 echo matched=$?
227
228 ## STDOUT:
229 matched=0
230 matched=0
231 ## END
232
233 #### \D{} for locale specific strftime
234
235 # In bash y.tab.c uses %X when string is empty
236 # This doesn't seem to match exactly, but meh for now.
237
238 PS1='foo \D{} bar'
239 echo "${PS1@P}" | egrep -q '^foo [0-9][0-9]:[0-9][0-9]:[0-9][0-9]( ..)? bar$'
240 echo matched=$?
241 ## STDOUT:
242 matched=0
243 ## END
244
245 #### \s for shell, \v for major.minor version, and \V for full version
246 PS1='foo \s bar'
247 echo "${PS1@P}" | egrep -q '^foo (bash|osh) bar$'
248 echo match=$?
249
250 PS1='foo \v bar'
251 echo "${PS1@P}" | egrep -q '^foo [0-9]+\.[0-9]+ bar$'
252 echo match=$?
253
254 PS1='foo \V bar'
255 echo "${PS1@P}" | egrep -q '^foo [0-9]+\.[0-9]+\.[0-9]+ bar$'
256 echo match=$?
257
258 ## STDOUT:
259 match=0
260 match=0
261 match=0
262 ## END
263
264
265 #### \j for number of jobs
266 set -m # enable job control
267 PS1='foo \j bar'
268 echo "${PS1@P}" | egrep -q 'foo 0 bar'
269 echo matched=$?
270 sleep 5 &
271 echo "${PS1@P}" | egrep -q 'foo 1 bar'
272 echo matched=$?
273 kill %%
274 fg
275 echo "${PS1@P}" | egrep -q 'foo 0 bar'
276 echo matched=$?
277
278 ## STDOUT:
279 matched=0
280 matched=0
281 sleep 5
282 matched=0
283 ## END
284
285 #### \l for TTY device basename
286 PS1='foo \l bar'
287 # FIXME this never an actual TTY when using ./test/spec.sh
288 tty="$(tty)"
289 if [[ "$tty" == "not a tty" ]]; then
290 expected="tty"
291 else
292 expected="$(basename "$tty")"
293 fi
294 echo "${PS1@P}" | egrep -q "foo $expected bar"
295 echo matched=$?
296
297 ## STDOUT:
298 matched=0
299 ## END
300
301 #### \! for history number
302 set -o history # enable history
303 PS1='foo \! bar'
304 history -c # clear history
305 echo "${PS1@P}" | egrep -q "foo 1 bar"
306 echo matched=$?
307 echo "_${PS1@P}" | egrep -q "foo 3 bar"
308 echo matched=$?
309
310 ## STDOUT:
311 matched=0
312 matched=0
313 ## END
314
315 #### \# for command number
316 PS1='foo \# bar'
317 prev_cmd_num="$(echo "${PS1@P}" | egrep -o 'foo [0-9]+ bar' | sed -E 's/foo ([0-9]+) bar/\1/')"
318 echo "${PS1@P}" | egrep -q "foo $((prev_cmd_num + 1)) bar"
319 echo matched=$?
320
321 ## STDOUT:
322 matched=0
323 ## END
324
325 #### @P with array
326 $SH -c 'echo ${@@P}' dummy a b c
327 echo status=$?
328 $SH -c 'echo ${*@P}' dummy a b c
329 echo status=$?
330 $SH -c 'a=(x y); echo ${a@P}' dummy a b c
331 echo status=$?
332 ## STDOUT:
333 a b c
334 status=0
335 a b c
336 status=0
337 x
338 status=0
339 ## END
340
341 #### default PS1
342 #flags='--norc --noprofile'
343 flags='--rcfile /dev/null'
344
345 $SH $flags -i -c 'echo "_${PS1}_"'
346
347 ## STDOUT:
348 _\s-\v\$ _
349 ## END