1 ## compare_shells: bash dash mksh zsh
2
3 #### ~ expansion in assignment
4 HOME=/home/bob
5 a=~/src
6 echo $a
7 ## stdout: /home/bob/src
8
9 #### ~ expansion in readonly assignment
10 # dash fails here!
11 # http://stackoverflow.com/questions/8441473/tilde-expansion-doesnt-work-when-i-logged-into-gui
12 HOME=/home/bob
13 readonly const=~/src
14 echo $const
15 ## stdout: /home/bob/src
16 ## BUG dash stdout: ~/src
17
18 #### No ~ expansion in dynamic assignment
19 HOME=/home/bob
20 binding='const=~/src'
21 readonly "$binding"
22 echo $const
23 ## stdout: ~/src
24
25 #### No tilde expansion in word that looks like assignment but isn't
26 # bash and mksh mistakenly expand here!
27 # bash fixes this in POSIX mode (gah).
28 # http://lists.gnu.org/archive/html/bug-bash/2016-06/msg00001.html
29 HOME=/home/bob
30 echo x=~
31 ## stdout: x=~
32 ## BUG bash/mksh stdout: x=/home/bob
33
34 #### tilde expansion of word after redirect
35 HOME=$TMP
36 echo hi > ~/tilde1.txt
37 cat $HOME/tilde1.txt | wc -c
38 ## stdout: 3
39 ## status: 0
40
41 #### other user
42 echo ~nonexistent
43 ## stdout: ~nonexistent
44 # zsh doesn't like nonexistent
45 ## OK zsh stdout-json: ""
46 ## OK zsh status: 1
47
48 #### ${undef:-~}
49 HOME=/home/bar
50 echo ${undef:-~}
51 echo ${HOME:+~/z}
52 echo "${undef:-~}"
53 echo ${undef:-"~"}
54 ## STDOUT:
55 /home/bar
56 /home/bar/z
57 ~
58 ~
59 ## END
60
61 #### ${x//~/~root}
62 HOME=/home/bar
63 x=~
64 echo ${x//~/~root}
65
66 # gah there is some expansion, what the hell
67 echo ${HOME//~/~root}
68
69 x=[$HOME]
70 echo ${x//~/~root}
71
72 ## STDOUT:
73 /root
74 /root
75 [/root]
76 ## END
77 ## N-I dash status: 2
78 ## N-I dash stdout-json: ""
79
80 #### x=foo:~ has tilde expansion
81 HOME=/home/bar
82 x=foo:~
83 echo $x
84 echo "$x" # quotes don't matter, the expansion happens on assignment?
85 x='foo:~'
86 echo $x
87
88 x=foo:~, # comma ruins it, must be /
89 echo $x
90
91 x=~:foo
92 echo $x
93
94 # no tilde expansion here
95 echo foo:~
96 ## STDOUT:
97 foo:/home/bar
98 foo:/home/bar
99 foo:~
100 foo:~,
101 /home/bar:foo
102 foo:~
103 ## END
104
105 #### a[x]=foo:~ has tilde expansion
106 case $SH in (dash|zsh) exit ;; esac
107
108 HOME=/home/bar
109 declare -a a
110 a[0]=foo:~
111 echo ${a[0]}
112
113 declare -A A
114 A['x']=foo:~
115 echo ${A['x']}
116
117 ## STDOUT:
118 foo:/home/bar
119 foo:/home/bar
120 ## END
121 ## N-I dash/zsh stdout-json: ""
122
123 #### tilde expansion an assignment keyword
124 HOME=/home/bar
125 f() {
126 local x=foo:~
127 echo $x
128 }
129 f
130 ## STDOUT:
131 foo:/home/bar
132 ## END
133 ## BUG dash STDOUT:
134 foo:~
135 ## END
136
137 #### x=${undef-~:~}
138 HOME=/home/bar
139
140 x=~:${undef-~:~}
141 echo $x
142
143 # Most shells agree on a different behavior, but with the OSH parsing model,
144 # it's easier to agree with yash. bash disagrees in a different way
145
146 ## STDOUT:
147 /home/bar:/home/bar:/home/bar
148 ## END
149 ## OK osh/yash STDOUT:
150 /home/bar:~:~
151 ## END
152
153 #### strict tilde
154 echo ~nonexistent
155
156 shopt -s strict_tilde
157 echo ~nonexistent
158
159 echo status=$?
160 ## status: 1
161 ## STDOUT:
162 ~nonexistent
163 ## END
164 ## N-I bash/dash/mksh status: 0
165 ## N-I bash/dash/mksh STDOUT:
166 ~nonexistent
167 ~nonexistent
168 status=0
169 ## END
170 ## OK zsh stdout-json: ""
171
172 #### temp assignment x=~ env
173
174 HOME=/home/bar
175
176 xx=~ env | grep xx=
177
178 # Does it respect the colon rule too?
179 xx=~root:~:~ env | grep xx=
180
181 ## STDOUT:
182 xx=/home/bar
183 xx=/root:/home/bar:/home/bar
184 ## END