1 |
## compare_shells: dash bash mksh zsh ash
|
2 |
## oils_failures_allowed: 2
|
3 |
## oils_cpp_failures_allowed: 1
|
4 |
|
5 |
|
6 |
case $SH in dash) exit ;; esac
|
7 |
|
8 |
show_hex() { od -A n -t c -t x1; }
|
9 |
|
10 |
echo -e '\0-' | show_hex
|
11 |
#echo -e '\x00-'
|
12 |
#echo -e '\000-'
|
13 |
|
14 |
## STDOUT:
|
15 |
\0 - \n
|
16 |
00 2d 0a
|
17 |
## END
|
18 |
|
19 |
## BUG zsh STDOUT:
|
20 |
\0 \n
|
21 |
00 0a
|
22 |
## END
|
23 |
|
24 |
## N-I dash STDOUT:
|
25 |
## END
|
26 |
|
27 |
|
28 |
case $SH in dash|ash) return ;; esac
|
29 |
|
30 |
# Show both printable and hex
|
31 |
show_hex() { od -A n -t c -t x1; }
|
32 |
|
33 |
printf $'x\U0z' | show_hex
|
34 |
echo ---
|
35 |
|
36 |
printf $'x\U00z' | show_hex
|
37 |
echo ---
|
38 |
|
39 |
printf $'\U0z' | show_hex
|
40 |
|
41 |
## STDOUT:
|
42 |
x
|
43 |
78
|
44 |
---
|
45 |
x
|
46 |
78
|
47 |
---
|
48 |
## END
|
49 |
## BUG zsh STDOUT:
|
50 |
x \0 z
|
51 |
78 00 7a
|
52 |
---
|
53 |
x \0 z
|
54 |
78 00 7a
|
55 |
---
|
56 |
\0 z
|
57 |
00 7a
|
58 |
## END
|
59 |
## N-I dash/ash STDOUT:
|
60 |
## END
|
61 |
|
62 |
|
63 |
show_hex() { od -A n -t c -t x1; }
|
64 |
|
65 |
printf '\0\n' | show_hex
|
66 |
## STDOUT:
|
67 |
\0 \n
|
68 |
00 0a
|
69 |
## END
|
70 |
|
71 |
|
72 |
case $SH in dash) exit ;; esac
|
73 |
show_hex() { od -A n -t c -t x1; }
|
74 |
|
75 |
nul=$'\0'
|
76 |
echo "$nul" | show_hex
|
77 |
printf '%s\n' "$nul" | show_hex
|
78 |
|
79 |
## STDOUT:
|
80 |
\n
|
81 |
0a
|
82 |
\n
|
83 |
0a
|
84 |
## END
|
85 |
|
86 |
## OK osh/zsh STDOUT:
|
87 |
\0 \n
|
88 |
00 0a
|
89 |
\0 \n
|
90 |
00 0a
|
91 |
## END
|
92 |
## N-I dash stdout-json: ""
|
93 |
|
94 |
|
95 |
case $SH in dash) exit ;; esac
|
96 |
show_hex() { od -A n -t c -t x1; }
|
97 |
|
98 |
# OSH agrees with ZSH -- so you have the ability to print NUL bytes without
|
99 |
# legacy echo -e
|
100 |
|
101 |
echo $'\0' | show_hex
|
102 |
|
103 |
## STDOUT:
|
104 |
\n
|
105 |
0a
|
106 |
## END
|
107 |
## OK osh/zsh STDOUT:
|
108 |
\0 \n
|
109 |
00 0a
|
110 |
## END
|
111 |
|
112 |
|
113 |
## N-I dash stdout-json: ""
|
114 |
|
115 |
|
116 |
|
117 |
case $SH in dash) exit ;; esac
|
118 |
|
119 |
argv.py $(echo -e '\0')
|
120 |
argv.py "$(echo -e '\0')"
|
121 |
argv.py $(echo -e 'a\0b')
|
122 |
argv.py "$(echo -e 'a\0b')"
|
123 |
|
124 |
## STDOUT:
|
125 |
[]
|
126 |
['']
|
127 |
['ab']
|
128 |
['ab']
|
129 |
## END
|
130 |
## BUG zsh STDOUT:
|
131 |
['', '']
|
132 |
['']
|
133 |
['a', 'b']
|
134 |
['a']
|
135 |
## END
|
136 |
|
137 |
## N-I dash STDOUT:
|
138 |
## END
|
139 |
|
140 |
|
141 |
|
142 |
case $SH in dash) exit ;; esac
|
143 |
|
144 |
# zsh is buggy here, weird
|
145 |
test -n $''
|
146 |
echo status=$?
|
147 |
|
148 |
test -n $'\0'
|
149 |
echo status=$?
|
150 |
|
151 |
|
152 |
## STDOUT:
|
153 |
status=1
|
154 |
status=1
|
155 |
## END
|
156 |
## OK osh STDOUT:
|
157 |
status=1
|
158 |
status=0
|
159 |
## END
|
160 |
## BUG zsh STDOUT:
|
161 |
status=0
|
162 |
status=0
|
163 |
## END
|
164 |
|
165 |
## N-I dash STDOUT:
|
166 |
## END
|
167 |
|
168 |
|
169 |
|
170 |
|
171 |
case $SH in dash) exit ;; esac
|
172 |
|
173 |
|
174 |
test -f $'\0'
|
175 |
echo status=$?
|
176 |
|
177 |
touch foo
|
178 |
test -f $'foo\0'
|
179 |
echo status=$?
|
180 |
|
181 |
test -f $'foo\0bar'
|
182 |
echo status=$?
|
183 |
|
184 |
test -f $'foobar'
|
185 |
echo status=$?
|
186 |
|
187 |
|
188 |
## STDOUT:
|
189 |
status=1
|
190 |
status=0
|
191 |
status=0
|
192 |
status=1
|
193 |
## END
|
194 |
|
195 |
## OK ash STDOUT:
|
196 |
status=1
|
197 |
status=0
|
198 |
status=1
|
199 |
status=1
|
200 |
## END
|
201 |
|
202 |
## N-I dash STDOUT:
|
203 |
## END
|
204 |
|
205 |
|
206 |
|
207 |
|
208 |
case $SH in dash) exit ;; esac
|
209 |
|
210 |
empty=$''
|
211 |
nul=$'\0'
|
212 |
|
213 |
echo empty=${#empty}
|
214 |
echo nul=${#nul}
|
215 |
|
216 |
|
217 |
## STDOUT:
|
218 |
empty=0
|
219 |
nul=0
|
220 |
## END
|
221 |
|
222 |
## OK osh/zsh STDOUT:
|
223 |
empty=0
|
224 |
nul=1
|
225 |
## END
|
226 |
|
227 |
## N-I dash STDOUT:
|
228 |
## END
|
229 |
|
230 |
|
231 |
|
232 |
# https://stackoverflow.com/questions/32722007/is-skipping-ignoring-nul-bytes-on-process-substitution-standardized
|
233 |
# bash contains a warning!
|
234 |
|
235 |
show_bytes() {
|
236 |
echo -n "$1" | od -A n -t x1
|
237 |
}
|
238 |
|
239 |
s=$(printf '.\001.')
|
240 |
echo len=${#s}
|
241 |
show_bytes "$s"
|
242 |
|
243 |
s=$(printf '.\000.')
|
244 |
echo len=${#s}
|
245 |
show_bytes "$s"
|
246 |
|
247 |
s=$(printf '\000')
|
248 |
echo len=${#s}
|
249 |
show_bytes "$s"
|
250 |
|
251 |
## STDOUT:
|
252 |
len=3
|
253 |
2e 01 2e
|
254 |
len=2
|
255 |
2e 2e
|
256 |
len=0
|
257 |
## END
|
258 |
|
259 |
## BUG zsh STDOUT:
|
260 |
len=3
|
261 |
2e 01 2e
|
262 |
len=3
|
263 |
2e 00 2e
|
264 |
len=1
|
265 |
00
|
266 |
## END
|
267 |
|
268 |
|
269 |
|
270 |
# Hm same odd behavior
|
271 |
|
272 |
show_string() {
|
273 |
read s
|
274 |
echo len=${#s}
|
275 |
echo -n "$s" | od -A n -t x1
|
276 |
}
|
277 |
|
278 |
printf '.\001.' | show_string
|
279 |
|
280 |
printf '.\000.' | show_string
|
281 |
|
282 |
printf '\000' | show_string
|
283 |
|
284 |
## STDOUT:
|
285 |
len=3
|
286 |
2e 01 2e
|
287 |
len=2
|
288 |
2e 2e
|
289 |
len=0
|
290 |
## END
|
291 |
|
292 |
## BUG zsh STDOUT:
|
293 |
len=3
|
294 |
2e 01 2e
|
295 |
len=3
|
296 |
2e 00 2e
|
297 |
len=1
|
298 |
00
|
299 |
## END
|
300 |
|
301 |
|
302 |
case $SH in dash) exit ;; esac
|
303 |
|
304 |
show_string() {
|
305 |
read -n 3 s
|
306 |
echo len=${#s}
|
307 |
echo -n "$s" | od -A n -t x1
|
308 |
}
|
309 |
|
310 |
|
311 |
printf '.\001.' | show_string
|
312 |
|
313 |
printf '.\000.' | show_string
|
314 |
|
315 |
printf '\000' | show_string
|
316 |
|
317 |
## STDOUT:
|
318 |
len=3
|
319 |
2e 01 2e
|
320 |
len=2
|
321 |
2e 2e
|
322 |
len=0
|
323 |
## END
|
324 |
|
325 |
## BUG-2 mksh STDOUT:
|
326 |
len=3
|
327 |
2e 01 2e
|
328 |
len=1
|
329 |
2e
|
330 |
len=0
|
331 |
## END
|
332 |
|
333 |
## BUG zsh STDOUT:
|
334 |
len=0
|
335 |
len=1
|
336 |
2e
|
337 |
len=0
|
338 |
## END
|
339 |
|
340 |
## N-I dash STDOUT:
|
341 |
## END
|
342 |
|
343 |
|
344 |
|
345 |
case $SH in dash|mksh|zsh|ash) exit ;; esac
|
346 |
|
347 |
{
|
348 |
printf '.\000.\n'
|
349 |
printf '.\000.\n'
|
350 |
} |
|
351 |
{ mapfile LINES
|
352 |
echo len=${#LINES[@]}
|
353 |
for line in ${LINES[@]}; do
|
354 |
echo -n "$line" | od -A n -t x1
|
355 |
done
|
356 |
}
|
357 |
|
358 |
# bash is INCONSISTENT:
|
359 |
# - it TRUNCATES at \0, with 'mapfile'
|
360 |
# - rather than just IGNORING \0, with 'read'
|
361 |
|
362 |
## STDOUT:
|
363 |
len=2
|
364 |
2e
|
365 |
2e
|
366 |
## END
|
367 |
|
368 |
## N-I dash/mksh/zsh/ash STDOUT:
|
369 |
## END
|
370 |
|
371 |
|
372 |
|
373 |
show_bytes() {
|
374 |
echo -n "$1" | od -A n -t x1
|
375 |
}
|
376 |
|
377 |
s=$(printf '\000.\000')
|
378 |
echo len=${#s}
|
379 |
show_bytes "$s"
|
380 |
|
381 |
echo ---
|
382 |
|
383 |
t=${s#?}
|
384 |
echo len=${#t}
|
385 |
show_bytes "$t"
|
386 |
|
387 |
t=${s##?}
|
388 |
echo len=${#t}
|
389 |
show_bytes "$t"
|
390 |
|
391 |
t=${s%?}
|
392 |
echo len=${#t}
|
393 |
show_bytes "$t"
|
394 |
|
395 |
t=${s%%?}
|
396 |
echo len=${#t}
|
397 |
show_bytes "$t"
|
398 |
|
399 |
## STDOUT:
|
400 |
len=1
|
401 |
2e
|
402 |
---
|
403 |
len=0
|
404 |
len=0
|
405 |
len=0
|
406 |
len=0
|
407 |
## END
|
408 |
|
409 |
## BUG zsh STDOUT:
|
410 |
len=3
|
411 |
00 2e 00
|
412 |
---
|
413 |
len=2
|
414 |
2e 00
|
415 |
len=2
|
416 |
2e 00
|
417 |
len=2
|
418 |
00 2e
|
419 |
len=2
|
420 |
00 2e
|
421 |
## END
|
422 |
|
423 |
|
424 |
|
425 |
show_bytes() {
|
426 |
echo -n "$1" | od -A n -t x1
|
427 |
}
|
428 |
|
429 |
s=$(printf '\000x')
|
430 |
echo len=${#s}
|
431 |
show_bytes "$s"
|
432 |
|
433 |
# strip one char from the front
|
434 |
s=${s#?}
|
435 |
echo len=${#s}
|
436 |
show_bytes "$s"
|
437 |
|
438 |
echo ---
|
439 |
|
440 |
s=$(printf '\001x')
|
441 |
echo len=${#s}
|
442 |
show_bytes "$s"
|
443 |
|
444 |
# strip one char from the front
|
445 |
s=${s#?}
|
446 |
echo len=${#s}
|
447 |
show_bytes "$s"
|
448 |
|
449 |
## STDOUT:
|
450 |
len=1
|
451 |
78
|
452 |
len=0
|
453 |
---
|
454 |
len=2
|
455 |
01 78
|
456 |
len=1
|
457 |
78
|
458 |
## END
|
459 |
|
460 |
## BUG zsh STDOUT:
|
461 |
len=2
|
462 |
00 78
|
463 |
len=1
|
464 |
78
|
465 |
---
|
466 |
len=2
|
467 |
01 78
|
468 |
len=1
|
469 |
78
|
470 |
## END
|
471 |
|
472 |
|
473 |
|
474 |
# https://github.com/oils-for-unix/oils/issues/2269
|
475 |
|
476 |
escape_arg() {
|
477 |
a="$1"
|
478 |
until [ -z "$a" ]; do
|
479 |
case "$a" in
|
480 |
(\'*) printf "'\"'\"'";;
|
481 |
(*) printf %.1s "$a";;
|
482 |
esac
|
483 |
a="${a#?}"
|
484 |
echo len=${#a} >&2
|
485 |
done
|
486 |
}
|
487 |
|
488 |
# encode
|
489 |
phrase="$(escape_arg "that's it!")"
|
490 |
echo escaped "$phrase"
|
491 |
|
492 |
# decode
|
493 |
eval "printf '%s\\n' '$phrase'"
|
494 |
|
495 |
echo ---
|
496 |
|
497 |
# harder input: NUL surrounded with ::
|
498 |
arg="$(printf ':\000:')"
|
499 |
#echo "arg=$arg"
|
500 |
|
501 |
case $SH in
|
502 |
zsh) echo 'writes binary data' ;;
|
503 |
*) echo escaped "$(escape_arg "$arg")" ;;
|
504 |
esac
|
505 |
#echo "arg=$arg"
|
506 |
|
507 |
## STDOUT:
|
508 |
escaped that'"'"'s it!
|
509 |
that's it!
|
510 |
---
|
511 |
escaped ::
|
512 |
## END
|
513 |
|
514 |
## OK zsh STDOUT:
|
515 |
escaped that'"'"'s it!
|
516 |
that's it!
|
517 |
---
|
518 |
writes binary data
|
519 |
## END
|