1 #!/bin/bash
2
3 # NOTE on bash bug: After setting IFS to array, it never splits anymore? Even
4 # if you assign IFS again.
5
6 ### IFS is scoped
7 IFS=b
8 word=abcd
9 f() { local IFS=c; argv.py $word; }
10 f
11 argv.py $word
12 # stdout-json: "['ab', 'd']\n['a', 'cd']\n"
13
14 ### Tilde sub is not split, but var sub is
15 HOME="foo bar"
16 argv.py ~
17 argv.py $HOME
18 # stdout-json: "['foo bar']\n['foo', 'bar']\n"
19
20 ### Word splitting
21 a="1 2"
22 b="3 4"
23 argv.py $a"$b"
24 # stdout-json: "['1', '23 4']\n"
25
26 ### Word splitting 2
27 a="1 2"
28 b="3 4"
29 c="5 6"
30 d="7 8"
31 argv.py $a"$b"$c"$d"
32 # stdout-json: "['1', '23 45', '67 8']\n"
33
34 # Has tests on differences between $* "$*" $@ "$@"
35 # http://stackoverflow.com/questions/448407/bash-script-to-receive-and-repass-quoted-parameters
36
37 ### $*
38 func() { argv.py -$*-; }
39 func "a 1" "b 2" "c 3"
40 # stdout: ['-a', '1', 'b', '2', 'c', '3-']
41
42 ### "$*"
43 func() { argv.py "-$*-"; }
44 func "a 1" "b 2" "c 3"
45 # stdout: ['-a 1 b 2 c 3-']
46
47 ### $@
48 # How does this differ from $* ? I don't think it does.
49 func() { argv.py -$@-; }
50 func "a 1" "b 2" "c 3"
51 # stdout: ['-a', '1', 'b', '2', 'c', '3-']
52
53 ### "$@"
54 func() { argv.py "-$@-"; }
55 func "a 1" "b 2" "c 3"
56 # stdout: ['-a 1', 'b 2', 'c 3-']
57
58 ### Word elision with space
59 s1=' '
60 argv.py $s1
61 # stdout: []
62
63 ### Word elision with non-whitespace IFS
64 # Treated differently than the default IFS. What is the rule here?
65 IFS=_
66 s1='_'
67 argv.py $s1
68 # stdout: ['']
69
70 ### empty $@ and $* is elided
71 func() { argv.py 1 $@ $* 2; }
72 func
73 # stdout: ['1', '2']
74
75 ### unquoted empty arg is elided
76 empty=""
77 argv.py 1 $empty 2
78 # stdout: ['1', '2']
79
80 ### unquoted whitespace arg is elided
81 space=" "
82 argv.py 1 $space 2
83 # stdout: ['1', '2']
84
85 ### empty literals are not elided
86 space=" "
87 argv.py 1 $space"" 2
88 # stdout: ['1', '', '2']
89
90 ### no splitting when IFS is empty
91 IFS=""
92 foo="a b"
93 argv.py $foo
94 # stdout: ['a b']
95
96 ### default value can yield multiple words
97 argv.py 1 ${undefined:-"2 3" "4 5"} 6
98 # stdout: ['1', '2 3', '4 5', '6']
99
100 ### default value can yield multiple words with part joining
101 argv.py 1${undefined:-"2 3" "4 5"}6
102 # stdout: ['12 3', '4 56']
103
104 ### default value with unquoted IFS char
105 IFS=_
106 argv.py 1${undefined:-"2_3"x_x"4_5"}6
107 # stdout: ['12_3x', 'x4_56']
108
109
110 # TODO:
111 # - unquoted args of whitespace are not elided (when IFS = null)
112 # - empty quoted args are kept
113 # - Test ${@:1} and so forth?
114 #
115 # - $* $@ with empty IFS
116 # - $* $@ with custom IFS
117 #
118 # - no splitting when IFS is empty
119 # - word splitting removes leading and trailing whitespace
120
121 # TODO: test framework needs common setup
122
123 # Test IFS and $@ $* on all these
124 ### TODO
125 empty=""
126 space=" "
127 AB="A B"
128 X="X"
129 Yspaces=" Y "