OILS / spec / builtin-read.test.sh View on Github | oils.pub

1185 lines, 587 significant
1## oils_failures_allowed: 1
2## compare_shells: bash mksh zsh ash
3
4#### read line from here doc
5
6# NOTE: there are TABS below
7read x <<EOF
8A B C D E
9FG
10EOF
11echo "[$x]"
12## stdout: [A B C D E]
13## status: 0
14
15#### read from empty file
16echo -n '' > $TMP/empty.txt
17read x < $TMP/empty.txt
18argv.py "status=$?" "$x"
19
20# No variable name, behaves the same
21read < $TMP/empty.txt
22argv.py "status=$?" "$REPLY"
23
24## STDOUT:
25['status=1', '']
26['status=1', '']
27## END
28## OK dash STDOUT:
29['status=1', '']
30['status=2', '']
31## END
32## status: 0
33
34#### read /dev/null
35read -n 1 </dev/null
36echo $?
37## STDOUT:
381
39## END
40## OK dash stdout: 2
41
42#### read with zero args
43echo | read
44echo status=$?
45## STDOUT:
46status=0
47## END
48## BUG dash STDOUT:
49status=2
50## END
51
52#### read builtin with no newline returns status 1
53
54# This is odd because the variable is populated successfully. OSH/YSH might
55# need a separate put reading feature that doesn't use IFS.
56
57echo -n ZZZ | { read x; echo status=$?; echo $x; }
58
59## STDOUT:
60status=1
61ZZZ
62## END
63## status: 0
64
65#### read builtin splits value across multiple vars
66# NOTE: there are TABS below
67read x y z <<EOF
68A B C D E
69FG
70EOF
71echo "[$x/$y/$z]"
72## stdout: [A/B/C D E]
73## status: 0
74
75#### read builtin with too few variables
76set -o errexit
77set -o nounset # hm this doesn't change it
78read x y z <<EOF
79A B
80EOF
81echo /$x/$y/$z/
82## stdout: /A/B//
83## status: 0
84
85#### read -n (with $REPLY)
86echo 12345 > $TMP/readn.txt
87read -n 4 x < $TMP/readn.txt
88read -n 2 < $TMP/readn.txt # Do it again with no variable
89argv.py $x $REPLY
90## stdout: ['1234', '12']
91## N-I dash/zsh stdout: []
92
93#### IFS= read -n (OSH regression: value saved in tempenv)
94echo XYZ > "$TMP/readn.txt"
95IFS= TMOUT= read -n 1 char < "$TMP/readn.txt"
96argv.py "$char"
97## stdout: ['X']
98## N-I dash/zsh stdout: ['']
99
100#### read -n doesn't strip whitespace (bug fix)
101case $SH in dash|zsh) exit ;; esac
102
103echo ' a b ' | (read -n 4; echo "[$REPLY]")
104echo ' a b ' | (read -n 5; echo "[$REPLY]")
105echo ' a b ' | (read -n 6; echo "[$REPLY]")
106echo
107
108echo 'one var strips whitespace'
109echo ' a b ' | (read -n 4 myvar; echo "[$myvar]")
110echo ' a b ' | (read -n 5 myvar; echo "[$myvar]")
111echo ' a b ' | (read -n 6 myvar; echo "[$myvar]")
112echo
113
114echo 'three vars'
115echo ' a b ' | (read -n 4 x y z; echo "[$x] [$y] [$z]")
116echo ' a b ' | (read -n 5 x y z; echo "[$x] [$y] [$z]")
117echo ' a b ' | (read -n 6 x y z; echo "[$x] [$y] [$z]")
118
119## STDOUT:
120[ a ]
121[ a b]
122[ a b ]
123
124one var strips whitespace
125[a]
126[a b]
127[a b]
128
129three vars
130[a] [] []
131[a] [b] []
132[a] [b] []
133## END
134
135## N-I dash/zsh STDOUT:
136## END
137
138## BUG mksh STDOUT:
139[a]
140[a b]
141[a b]
142
143one var strips whitespace
144[a]
145[a b]
146[a b]
147
148three vars
149[a] [] []
150[a] [b] []
151[a] [b] []
152## END
153
154#### read -d -n - respects delimiter and splits
155
156case $SH in dash|zsh|ash) exit ;; esac
157
158echo 'delim c'
159echo ' a b c ' | (read -d 'c' -n 3; echo "[$REPLY]")
160echo ' a b c ' | (read -d 'c' -n 4; echo "[$REPLY]")
161echo ' a b c ' | (read -d 'c' -n 5; echo "[$REPLY]")
162echo
163
164echo 'one var'
165echo ' a b c ' | (read -d 'c' -n 3 myvar; echo "[$myvar]")
166echo ' a b c ' | (read -d 'c' -n 4 myvar; echo "[$myvar]")
167echo ' a b c ' | (read -d 'c' -n 5 myvar; echo "[$myvar]")
168echo
169
170echo 'three vars'
171echo ' a b c ' | (read -d 'c' -n 3 x y z; echo "[$x] [$y] [$z]")
172echo ' a b c ' | (read -d 'c' -n 4 x y z; echo "[$x] [$y] [$z]")
173echo ' a b c ' | (read -d 'c' -n 5 x y z; echo "[$x] [$y] [$z]")
174
175## STDOUT:
176delim c
177[ a]
178[ a ]
179[ a b]
180
181one var
182[a]
183[a]
184[a b]
185
186three vars
187[a] [] []
188[a] [] []
189[a] [b] []
190## END
191
192## N-I dash/zsh/ash STDOUT:
193## END
194
195## BUG mksh STDOUT:
196delim c
197[a]
198[a]
199[a b]
200
201one var
202[a]
203[a]
204[a b]
205
206three vars
207[a] [] []
208[a] [] []
209[a] [b] []
210## END
211
212
213#### read -n with invalid arg
214read -n not_a_number
215echo status=$?
216## stdout: status=2
217## OK bash stdout: status=1
218## N-I zsh stdout-json: ""
219
220#### read -n from pipe
221case $SH in dash|ash|zsh) exit ;; esac
222
223echo abcxyz | { read -n 3; echo reply=$REPLY; }
224## status: 0
225## stdout: reply=abc
226## N-I dash/ash stdout-json: ""
227
228# zsh appears to hang with -k
229## N-I zsh stdout-json: ""
230
231#### read without args uses $REPLY, no splitting occurs (without -n)
232
233# mksh and zsh implement splitting with $REPLY, bash/ash don't
234
235echo ' a b ' | (read; echo "[$REPLY]")
236echo ' a b ' | (read myvar; echo "[$myvar]")
237
238echo ' a b \
239 line2' | (read; echo "[$REPLY]")
240echo ' a b \
241 line2' | (read myvar; echo "[$myvar]")
242
243# Now test with -r
244echo ' a b \
245 line2' | (read -r; echo "[$REPLY]")
246echo ' a b \
247 line2' | (read -r myvar; echo "[$myvar]")
248
249## STDOUT:
250[ a b ]
251[a b]
252[ a b line2]
253[a b line2]
254[ a b \]
255[a b \]
256## END
257## BUG mksh/zsh STDOUT:
258[a b]
259[a b]
260[a b line2]
261[a b line2]
262[a b \]
263[a b \]
264## END
265## BUG dash STDOUT:
266[]
267[a b ]
268[]
269[a b line2]
270[]
271[a b \]
272## END
273
274#### read -n vs. -N
275# dash, ash and zsh do not implement read -N
276# mksh treats -N exactly the same as -n
277case $SH in dash|ash|zsh) exit ;; esac
278
279# bash docs: https://www.gnu.org/software/bash/manual/html_node/Bash-Builtins.html
280
281echo 'a b c' > $TMP/readn.txt
282
283echo 'read -n'
284read -n 5 A B C < $TMP/readn.txt; echo "'$A' '$B' '$C'"
285read -n 4 A B C < $TMP/readn.txt; echo "'$A' '$B' '$C'"
286echo
287
288echo 'read -N'
289read -N 5 A B C < $TMP/readn.txt; echo "'$A' '$B' '$C'"
290read -N 4 A B C < $TMP/readn.txt; echo "'$A' '$B' '$C'"
291## STDOUT:
292read -n
293'a' 'b' 'c'
294'a' 'b' ''
295
296read -N
297'a b c' '' ''
298'a b ' '' ''
299## END
300## N-I dash/ash/zsh stdout-json: ""
301## BUG mksh STDOUT:
302read -n
303'a' 'b' 'c'
304'a' 'b' ''
305
306read -N
307'a' 'b' 'c'
308'a' 'b' ''
309## END
310
311#### read -N ignores delimiters
312case $SH in dash|ash|zsh) exit ;; esac
313
314echo $'a\nb\nc' > $TMP/read-lines.txt
315
316read -N 3 out < $TMP/read-lines.txt
317echo "$out"
318## STDOUT:
319a
320b
321## END
322## N-I dash/ash/zsh stdout-json: ""
323
324#### read will unset extranous vars
325
326echo 'a b' > $TMP/read-few.txt
327
328c='some value'
329read a b c < $TMP/read-few.txt
330echo "'$a' '$b' '$c'"
331
332case $SH in dash) exit ;; esac # dash does not implement -n
333
334c='some value'
335read -n 3 a b c < $TMP/read-few.txt
336echo "'$a' '$b' '$c'"
337## STDOUT:
338'a' 'b' ''
339'a' 'b' ''
340## END
341## N-I dash STDOUT:
342'a' 'b' ''
343## END
344## BUG zsh STDOUT:
345'a' 'b' ''
346'b' '' ''
347## END
348
349#### read -r ignores backslashes
350echo 'one\ two' > $TMP/readr.txt
351read escaped < $TMP/readr.txt
352read -r raw < $TMP/readr.txt
353argv.py "$escaped" "$raw"
354## stdout: ['one two', 'one\\ two']
355
356#### read -r with other backslash escapes
357echo 'one\ two\x65three' > $TMP/readr.txt
358read escaped < $TMP/readr.txt
359read -r raw < $TMP/readr.txt
360argv.py "$escaped" "$raw"
361# mksh respects the hex escapes here, but other shells don't!
362## stdout: ['one twox65three', 'one\\ two\\x65three']
363## BUG mksh/zsh stdout: ['one twoethree', 'one\\ twoethree']
364
365#### read with line continuation reads multiple physical lines
366# NOTE: osh failing because of file descriptor issue. stdin has to be closed!
367tmp=$TMP/$(basename $SH)-readr.txt
368echo -e 'one\\\ntwo\n' > $tmp
369read escaped < $tmp
370read -r raw < $tmp
371argv.py "$escaped" "$raw"
372## stdout: ['onetwo', 'one\\']
373## N-I dash stdout: ['-e onetwo', '-e one\\']
374
375#### read multiple vars spanning many lines
376read x y << 'EOF'
377one-\
378two three-\
379four five-\
380six
381EOF
382argv.py "$x" "$y" "$z"
383## stdout: ['one-two', 'three-four five-six', '']
384
385#### read -r with \n
386echo '\nline' > $TMP/readr.txt
387read escaped < $TMP/readr.txt
388read -r raw < $TMP/readr.txt
389argv.py "$escaped" "$raw"
390# dash/mksh/zsh are bugs because at least the raw mode should let you read a
391# literal \n.
392## stdout: ['nline', '\\nline']
393## BUG dash/mksh/zsh stdout: ['', '']
394
395#### read -s from pipe, not a terminal
396case $SH in dash|zsh) exit ;; esac
397
398# It's hard to really test this because it requires a terminal. We hit a
399# different code path when reading through a pipe. There can be bugs there
400# too!
401
402echo foo | { read -s; echo $REPLY; }
403echo bar | { read -n 2 -s; echo $REPLY; }
404
405# Hm no exit 1 here? Weird
406echo b | { read -n 2 -s; echo $?; echo $REPLY; }
407## STDOUT:
408foo
409ba
4100
411b
412## END
413## N-I dash/zsh stdout-json: ""
414
415#### read with IFS=$'\n'
416# The leading spaces are stripped if they appear in IFS.
417IFS=$(echo -e '\n')
418read var <<EOF
419 a b c
420 d e f
421EOF
422echo "[$var]"
423## stdout: [ a b c]
424## N-I dash stdout: [a b c]
425
426#### read multiple lines with IFS=:
427# The leading spaces are stripped if they appear in IFS.
428# IFS chars are escaped with :.
429tmp=$TMP/$(basename $SH)-read-ifs.txt
430IFS=:
431cat >$tmp <<'EOF'
432 \\a :b\: c:d\
433 e
434EOF
435read a b c d < $tmp
436# Use printf because echo in dash/mksh interprets escapes, while it doesn't in
437# bash.
438printf "%s\n" "[$a|$b|$c|$d]"
439## stdout: [ \a |b: c|d e|]
440
441#### read with IFS=''
442IFS=''
443read x y <<EOF
444 a b c d
445EOF
446echo "[$x|$y]"
447## stdout: [ a b c d|]
448
449#### read does not respect C backslash escapes
450
451# bash doesn't respect these, but other shells do. Gah! I think bash
452# behavior makes more sense. It only escapes IFS.
453echo '\a \b \c \d \e \f \g \h \x65 \145 \i' > $TMP/read-c.txt
454read line < $TMP/read-c.txt
455echo $line
456## STDOUT:
457a b c d e f g h x65 145 i
458## END
459## BUG ash STDOUT:
460abcdefghx65 145 i
461## END
462## BUG dash/zsh stdout-json: "\u0007 \u0008\n"
463## BUG mksh stdout-json: "\u0007 \u0008 d \u001b \u000c g h e 145 i\n"
464
465#### dynamic scope used to set vars
466f() {
467 read head << EOF
468ref: refs/heads/dev/andy
469EOF
470}
471f
472echo $head
473## STDOUT:
474ref: refs/heads/dev/andy
475## END
476
477#### read -a reads into array
478
479# read -a is used in bash-completion
480# none of these shells implement it
481case $SH in
482 *mksh|*dash|*zsh|*/ash)
483 exit 2;
484 ;;
485esac
486
487read -a myarray <<'EOF'
488a b c\ d
489EOF
490argv.py "${myarray[@]}"
491
492# arguments are ignored here
493read -r -a array2 extra arguments <<'EOF'
494a b c\ d
495EOF
496argv.py "${array2[@]}"
497argv.py "${extra[@]}"
498argv.py "${arguments[@]}"
499## status: 0
500## STDOUT:
501['a', 'b', 'c d']
502['a', 'b', 'c\\', 'd']
503[]
504[]
505## END
506## N-I dash/mksh/zsh/ash status: 2
507## N-I dash/mksh/zsh/ash stdout-json: ""
508
509#### read -d : (colon-separated records)
510printf a,b,c:d,e,f:g,h,i | {
511 IFS=,
512 read -d : v1
513 echo "v1=$v1"
514 read -d : v1 v2
515 echo "v1=$v1 v2=$v2"
516 read -d : v1 v2 v3
517 echo "v1=$v1 v2=$v2 v3=$v3"
518}
519## STDOUT:
520v1=a,b,c
521v1=d v2=e,f
522v1=g v2=h v3=i
523## END
524## N-I dash STDOUT:
525v1=
526v1= v2=
527v1= v2= v3=
528## END
529
530#### read -d '' (null-separated records)
531printf 'a,b,c\0d,e,f\0g,h,i' | {
532 IFS=,
533 read -d '' v1
534 echo "v1=$v1"
535 read -d '' v1 v2
536 echo "v1=$v1 v2=$v2"
537 read -d '' v1 v2 v3
538 echo "v1=$v1 v2=$v2 v3=$v3"
539}
540## STDOUT:
541v1=a,b,c
542v1=d v2=e,f
543v1=g v2=h v3=i
544## END
545## N-I dash STDOUT:
546v1=
547v1= v2=
548v1= v2= v3=
549## END
550
551#### read -rd
552read -rd '' var <<EOF
553foo
554bar
555EOF
556echo "$var"
557## STDOUT:
558foo
559bar
560## END
561## N-I dash STDOUT:
562
563## END
564
565#### read -d when there's no delimiter
566{ read -d : part
567 echo $part $?
568 read -d : part
569 echo $part $?
570} <<EOF
571foo:bar
572EOF
573## STDOUT:
574foo 0
575bar 1
576## END
577## N-I dash STDOUT:
5782
5792
580## END
581
582#### read -t 0 tests if input is available
583case $SH in dash|zsh|mksh) exit ;; esac
584
585# is there input available?
586read -t 0 < /dev/null
587echo $?
588
589# floating point
590read -t 0.0 < /dev/null
591echo $?
592
593# floating point
594echo foo | { read -t 0; echo reply=$REPLY; }
595echo $?
596
597## STDOUT:
5980
5990
600reply=
6010
602## END
603## N-I dash/zsh/mksh stdout-json: ""
604
605#### read -t 0.5
606case $SH in dash) exit ;; esac
607
608read -t 0.5 < /dev/null
609echo $?
610
611## STDOUT:
6121
613## END
614## BUG zsh/mksh STDOUT:
6151
616## END
617## N-I dash stdout-json: ""
618
619#### read -t -0.5 is invalid
620# bash appears to just take the absolute value?
621
622read -t -0.5 < /dev/null
623echo $?
624
625## STDOUT:
6262
627## END
628## BUG bash STDOUT:
6291
630## END
631## BUG zsh stdout-json: ""
632## BUG zsh status: 1
633
634#### read -u
635case $SH in dash|mksh) exit ;; esac
636
637# file descriptor
638read -u 3 3<<EOF
639hi
640EOF
641echo reply=$REPLY
642## STDOUT:
643reply=hi
644## END
645## N-I dash/mksh stdout-json: ""
646
647#### read -u syntax error
648read -u -3
649echo status=$?
650## STDOUT:
651status=2
652## END
653## OK bash/zsh STDOUT:
654status=1
655## END
656
657#### read -u -s
658case $SH in dash|mksh) exit ;; esac
659
660# file descriptor
661read -s -u 3 3<<EOF
662hi
663EOF
664echo reply=$REPLY
665## STDOUT:
666reply=hi
667## END
668## N-I dash/mksh stdout-json: ""
669
670#### read -u 3 -d 5
671case $SH in dash|mksh) exit ;; esac
672
673# file descriptor
674read -u 3 -d 5 3<<EOF
675123456789
676EOF
677echo reply=$REPLY
678## STDOUT:
679reply=1234
680## END
681## N-I dash/mksh stdout-json: ""
682
683#### read -u 3 -d b -N 6
684case $SH in ash|zsh) exit ;; esac
685
686# file descriptor
687read -u 3 -d b -N 4 3<<EOF
688ababababa
689EOF
690echo reply=$REPLY
691# test end on EOF
692read -u 3 -d b -N 6 3<<EOF
693ab
694EOF
695echo reply=$REPLY
696## STDOUT:
697reply=abab
698reply=ab
699## END
700## N-I ash/zsh stdout-json: ""
701## BUG mksh stdout-json: ""
702## BUG mksh status: 2
703
704
705#### read -N doesn't respect delimiter, while read -n does
706case $SH in dash|zsh|ash) exit ;; esac
707
708echo foobar | { read -n 5 -d b; echo $REPLY; }
709echo foobar | { read -N 5 -d b; echo $REPLY; }
710## STDOUT:
711foo
712fooba
713## END
714## OK mksh STDOUT:
715fooba
716fooba
717## END
718## N-I dash/zsh/ash stdout-json: ""
719
720#### read -p (not fully tested)
721
722# hm DISABLED if we're not going to the terminal
723# so we're only testing that it accepts the flag here
724
725case $SH in dash|mksh|zsh) exit ;; esac
726
727echo hi | { read -p 'P'; echo $REPLY; }
728echo hi | { read -p 'P' -n 1; echo $REPLY; }
729## STDOUT:
730hi
731h
732## END
733## stderr-json: ""
734## N-I dash/mksh/zsh stdout-json: ""
735
736#### read usage
737read -n -1
738echo status=$?
739## STDOUT:
740status=2
741## END
742## OK bash stdout: status=1
743## BUG mksh stdout-json: ""
744# zsh gives a fatal error? seems inconsistent
745## BUG zsh stdout-json: ""
746## BUG zsh status: 1
747
748#### read with smooshed args
749echo hi | { read -rn1 var; echo var=$var; }
750## STDOUT:
751var=h
752## END
753## N-I dash/zsh STDOUT:
754var=
755## END
756
757#### read -r -d '' for NUL strings, e.g. find -print0
758
759
760case $SH in dash|zsh|mksh) exit ;; esac # NOT IMPLEMENTED
761
762mkdir -p read0
763cd read0
764rm -f *
765
766touch a\\b\\c\\d # -r is necessary!
767
768find . -type f -a -print0 | { read -r -d ''; echo "[$REPLY]"; }
769
770## STDOUT:
771[./a\b\c\d]
772## END
773## N-I dash/zsh/mksh STDOUT:
774## END
775
776
777#### read from redirected directory is non-fatal error
778
779# This tickles an infinite loop bug in our version of mksh! TODO: upgrade the
780# version and enable this
781case $SH in mksh) return ;; esac
782
783cd $TMP
784mkdir -p dir
785read x < ./dir
786echo status=$?
787
788## STDOUT:
789status=1
790## END
791# OK mksh stdout: status=2
792## OK mksh stdout-json: ""
793
794#### read -n from directory
795
796case $SH in dash|ash) return ;; esac # not implemented
797
798# same hanging bug
799case $SH in mksh) return ;; esac
800
801mkdir -p dir
802read -n 3 x < ./dir
803echo status=$?
804## STDOUT:
805status=1
806## END
807## OK mksh stdout-json: ""
808## N-I dash/ash stdout-json: ""
809
810#### mapfile from directory (bash doesn't handle errors)
811case $SH in dash|ash|mksh|zsh) return ;; esac # not implemented
812
813mkdir -p dir
814mapfile $x < ./dir
815echo status=$?
816
817## STDOUT:
818status=1
819## END
820## BUG bash STDOUT:
821status=0
822## END
823## N-I dash/ash/mksh/zsh stdout-json: ""
824
825#### read -n 0
826case $SH in zsh) exit 99;; esac # read -n not implemented
827
828echo 'a\b\c\d\e\f' | (read -n 0; argv.py "$REPLY")
829
830## STDOUT:
831['']
832## END
833# ash appears to treat 0 as unspecified
834## OK ash STDOUT:
835['abcdef']
836## END
837## N-I zsh status: 99
838## N-I zsh STDOUT:
839## END
840
841#### read -n and backslash escape
842case $SH in zsh) exit 99;; esac # read -n not implemented
843
844echo 'a\b\c\d\e\f' | (read -n 5; argv.py "$REPLY")
845echo 'a\ \ \ \ \ ' | (read -n 5; argv.py "$REPLY")
846
847## STDOUT:
848['abcde']
849['a ']
850## END
851## OK mksh STDOUT:
852['a\x08d\x1b']
853['a ']
854## END
855## OK ash STDOUT:
856['abc']
857['a ']
858## END
859## N-I zsh status: 99
860## N-I zsh STDOUT:
861## END
862
863#### read -n 4 with incomplete backslash
864case $SH in zsh) exit 99;; esac # read -n not implemented
865
866echo 'abc\def\ghijklmn' | (read -n 4; argv.py "$REPLY")
867echo ' \xxx\xxxxxxxx' | (read -n 4; argv.py "$REPLY")
868
869# bash implements "-n NUM" as number of characters
870## STDOUT:
871['abcd']
872[' x']
873## END
874# ash implements "-n NUM" as number of bytes
875## OK-2 ash STDOUT:
876['abc']
877[' ']
878## END
879# mksh implements "-n NUM" as number of bytes, and also "read" (without
880# variable names) in mksh is equivalent to "read REPLY, i.e., consideres IFS.
881## OK-3 mksh STDOUT:
882['abc']
883['']
884## END
885## N-I zsh status: 99
886## N-I zsh STDOUT:
887## END
888
889#### read -n 4 with backslash + delim
890case $SH in zsh) exit 99;; esac # read -n not implemented
891
892echo $'abc\\\ndefg' | (read -n 4; argv.py "$REPLY")
893
894## STDOUT:
895['abcd']
896## END
897# mksh and ash implements "-n NUM" as number of bytes.
898## OK-2 mksh/ash STDOUT:
899['abc']
900## END
901## N-I zsh status: 99
902## N-I zsh STDOUT:
903## END
904
905#### "backslash + newline" should be swallowed regardless of "-d <delim>"
906
907printf '%s\n' 'a b\' 'c d' | (read; argv.py "$REPLY")
908printf '%s\n' 'a b\,c d' | (read; argv.py "$REPLY")
909printf '%s\n' 'a b\' 'c d' | (read -d ,; argv.py "$REPLY")
910printf '%s\n' 'a b\,c d' | (read -d ,; argv.py "$REPLY")
911
912## STDOUT:
913['a bc d']
914['a b,c d']
915['a bc d\n']
916['a b,c d\n']
917## END
918# mksh/zsh swallows "backslash + delim" instead.
919## OK-2 mksh/zsh STDOUT:
920['a bc d']
921['a b,c d']
922['a b\nc d']
923['a bc d']
924## END
925
926#### empty input and splitting
927case $SH in mksh|ash|dash|zsh) exit 99; esac
928echo '' | (read -a a; argv.py "${a[@]}")
929IFS=x
930echo '' | (read -a a; argv.py "${a[@]}")
931IFS=
932echo '' | (read -a a; argv.py "${a[@]}")
933## STDOUT:
934[]
935[]
936[]
937## END
938## N-I mksh/zsh/dash/ash status: 99
939## N-I mksh/zsh/dash/ash STDOUT:
940## END
941
942#### IFS='x ' read -a: trailing spaces (unlimited split)
943case $SH in mksh|ash|dash|zsh) exit 99; esac
944IFS='x '
945echo 'a b' | (read -a a; argv.py "${a[@]}")
946echo 'a b ' | (read -a a; argv.py "${a[@]}")
947echo 'a bx' | (read -a a; argv.py "${a[@]}")
948echo 'a bx ' | (read -a a; argv.py "${a[@]}")
949echo 'a b x' | (read -a a; argv.py "${a[@]}")
950echo 'a b x ' | (read -a a; argv.py "${a[@]}")
951echo 'a b x x' | (read -a a; argv.py "${a[@]}")
952
953## STDOUT:
954['a', 'b']
955['a', 'b']
956['a', 'b']
957['a', 'b']
958['a', 'b']
959['a', 'b']
960['a', 'b', '']
961## END
962## N-I mksh/zsh/dash/ash status: 99
963## N-I mksh/zsh/dash/ash STDOUT:
964## END
965
966#### IFS='x ' read a b: trailing spaces (with max_split)
967echo 'hello world test ' | (read a b; argv.py "$a" "$b")
968echo '-- IFS=x --'
969IFS='x '
970echo 'a ax x ' | (read a b; argv.py "$a" "$b")
971echo 'a ax x x' | (read a b; argv.py "$a" "$b")
972echo 'a ax x x ' | (read a b; argv.py "$a" "$b")
973echo 'a ax x x a' | (read a b; argv.py "$a" "$b")
974## STDOUT:
975['hello', 'world test']
976-- IFS=x --
977['a', 'ax x']
978['a', 'ax x x']
979['a', 'ax x x']
980['a', 'ax x x a']
981## END
982
983#### IFS='x ' read -a: intermediate spaces (unlimited split)
984case $SH in mksh|ash|dash|zsh) exit 99; esac
985IFS='x '
986echo 'a x b' | (read -a a; argv.py "${a[@]}")
987echo 'a xx b' | (read -a a; argv.py "${a[@]}")
988echo 'a xxx b' | (read -a a; argv.py "${a[@]}")
989echo 'a x xb' | (read -a a; argv.py "${a[@]}")
990echo 'a x x b' | (read -a a; argv.py "${a[@]}")
991echo 'ax b' | (read -a a; argv.py "${a[@]}")
992echo 'ax xb' | (read -a a; argv.py "${a[@]}")
993echo 'ax xb' | (read -a a; argv.py "${a[@]}")
994echo 'ax x xb' | (read -a a; argv.py "${a[@]}")
995## STDOUT:
996['a', 'b']
997['a', '', 'b']
998['a', '', '', 'b']
999['a', '', 'b']
1000['a', '', 'b']
1001['a', 'b']
1002['a', '', 'b']
1003['a', '', 'b']
1004['a', '', '', 'b']
1005## END
1006## N-I mksh/zsh/dash/ash status: 99
1007## N-I mksh/zsh/dash/ash STDOUT:
1008## END
1009
1010#### IFS='x ' incomplete backslash
1011echo ' a b \' | (read a; argv.py "$a")
1012echo ' a b \' | (read a b; argv.py "$a" "$b")
1013IFS='x '
1014echo $'a ax x \\\nhello' | (read a b; argv.py "$a" "$b")
1015## STDOUT:
1016['a b']
1017['a', 'b']
1018['a', 'ax x hello']
1019## END
1020
1021#### IFS='\ ' and backslash escaping
1022IFS='\ '
1023echo "hello\ world test" | (read a b; argv.py "$a" "$b")
1024IFS='\'
1025echo "hello\ world test" | (read a b; argv.py "$a" "$b")
1026## STDOUT:
1027['hello world', 'test']
1028['hello world test', '']
1029## END
1030# In mksh/zsh, IFS='\' is stronger than backslash escaping
1031## OK mksh/zsh STDOUT:
1032['hello', 'world test']
1033['hello', ' world test']
1034## END
1035
1036#### max_split and backslash escaping
1037echo 'Aa b \ a\ b' | (read a b; argv.py "$a" "$b")
1038echo 'Aa b \ a\ b' | (read a b c; argv.py "$a" "$b" "$c")
1039echo 'Aa b \ a\ b' | (read a b c d; argv.py "$a" "$b" "$c" "$d")
1040## STDOUT:
1041['Aa', 'b a b']
1042['Aa', 'b', ' a b']
1043['Aa', 'b', ' a b', '']
1044## END
1045
1046#### IFS=x read a b <<< xxxxxx
1047IFS='x '
1048echo x | (read a b; argv.py "$a" "$b")
1049echo xx | (read a b; argv.py "$a" "$b")
1050echo xxx | (read a b; argv.py "$a" "$b")
1051echo xxxx | (read a b; argv.py "$a" "$b")
1052echo xxxxx | (read a b; argv.py "$a" "$b")
1053echo '-- spaces --'
1054echo 'x ' | (read a b; argv.py "$a" "$b")
1055echo 'xx ' | (read a b; argv.py "$a" "$b")
1056echo 'xxx ' | (read a b; argv.py "$a" "$b")
1057echo 'xxxx ' | (read a b; argv.py "$a" "$b")
1058echo 'xxxxx' | (read a b; argv.py "$a" "$b")
1059echo '-- with char --'
1060echo 'xa ' | (read a b; argv.py "$a" "$b")
1061echo 'xax ' | (read a b; argv.py "$a" "$b")
1062echo 'xaxx ' | (read a b; argv.py "$a" "$b")
1063echo 'xaxxx ' | (read a b; argv.py "$a" "$b")
1064echo 'xaxxxx' | (read a b; argv.py "$a" "$b")
1065## STDOUT:
1066['', '']
1067['', '']
1068['', 'xx']
1069['', 'xxx']
1070['', 'xxxx']
1071-- spaces --
1072['', '']
1073['', '']
1074['', 'xx']
1075['', 'xxx']
1076['', 'xxxx']
1077-- with char --
1078['', 'a']
1079['', 'a']
1080['', 'axx']
1081['', 'axxx']
1082['', 'axxxx']
1083## END
1084## OK-2 zsh STDOUT:
1085['', '']
1086['', 'x']
1087['', 'xx']
1088['', 'xxx']
1089['', 'xxxx']
1090-- spaces --
1091['', '']
1092['', 'x']
1093['', 'xx']
1094['', 'xxx']
1095['', 'xxxx']
1096-- with char --
1097['', 'a']
1098['', 'ax']
1099['', 'axx']
1100['', 'axxx']
1101['', 'axxxx']
1102## END
1103
1104#### read and "\ "
1105
1106IFS='x '
1107check() { echo "$1" | (read a b; argv.py "$a" "$b"); }
1108
1109echo '-- xs... --'
1110check 'x '
1111check 'x \ '
1112check 'x \ \ '
1113check 'x \ \ \ '
1114echo '-- xe... --'
1115check 'x\ '
1116check 'x\ \ '
1117check 'x\ \ \ '
1118check 'x\ '
1119check 'x\ '
1120check 'x\ '
1121
1122# check 'xx\ '
1123# check 'xx\ '
1124
1125## STDOUT:
1126-- xs... --
1127['', '']
1128['', ' ']
1129['', ' ']
1130['', ' ']
1131-- xe... --
1132['', ' ']
1133['', ' ']
1134['', ' ']
1135['', ' ']
1136['', ' ']
1137['', ' ']
1138## END
1139## BUG mksh STDOUT:
1140-- xs... --
1141['', '']
1142['', '']
1143['', ' ']
1144['', ' ']
1145-- xe... --
1146['', '']
1147['', ' ']
1148['', ' ']
1149['', '']
1150['', '']
1151['', '']
1152## END
1153## OK-2 zsh/ash STDOUT:
1154-- xs... --
1155['', '']
1156['', '']
1157['', '']
1158['', '']
1159-- xe... --
1160['', '']
1161['', '']
1162['', '']
1163['', '']
1164['', '']
1165['', '']
1166## END
1167
1168#### read bash bug
1169IFS='x '
1170echo 'x\ \ ' | (read a b; argv.py "$a" "$b")
1171## STDOUT:
1172['', ' ']
1173## END
1174## BUG bash STDOUT:
1175['', '\x01']
1176## END
1177## BUG-2 mksh STDOUT:
1178['', ' ']
1179## END
1180## OK-3 zsh/ash STDOUT:
1181['', '']
1182## END
1183## OK-4 osh STDOUT:
1184['', ' ']
1185## END