1 ## oils_failures_allowed: 0
2
3 #### Can read from ENV Obj
4 shopt -s ysh:upgrade
5
6 pp test_ (type(ENV))
7 #pp test_ (ENV)
8
9 # Set by the spec test harness
10
11 if (ENV.SH ~~ '*osh') {
12 echo ok
13 }
14 #echo SH=$[ENV.SH]
15
16 ## STDOUT:
17 (Str) "Obj"
18 ok
19 ## END
20
21 #### ENV works in different modules
22 shopt -s ysh:upgrade
23
24 setglobal ENV.PS4 = '%%% '
25
26 use $[ENV.REPO_ROOT]/spec/testdata/module2/env.ysh
27
28 ## STDOUT:
29 env.ysh
30 OSH ok
31 ## END
32
33 #### bin/ysh doesn't have exported vars (declare -x)
34
35 osh=$SH # this file is run by OSH
36
37 case $osh in
38 *osh)
39 echo 'OSH ok'
40 ;;
41 esac
42
43 var ysh = osh.replace('osh', 'ysh')
44
45 # NOT exported
46 $ysh -c 'echo sh=$[getVar("SH")]'
47
48 ## STDOUT:
49 OSH ok
50 sh=null
51 ## END
52
53 #### Temp bindings A=a B=b my-command push to ENV Obj (ysh:all)
54 shopt -s ysh:all
55
56 _A=a _B=b env | grep '^_' | sort
57
58 ## STDOUT:
59 _A=a
60 _B=b
61 ## END
62
63 #### Nested temp bindings
64
65 f2() {
66 echo " f2 AA=$AA BB=$BB"
67 env | egrep 'AA|BB'
68 }
69
70 f1() {
71 echo "> f1 AA=$AA"
72 AA=aaaa BB=bb f2
73 echo "< f1 AA=$AA"
74 }
75
76 AA=a f1
77
78 #
79 # Now with ysh:upgrade
80 #
81
82 shopt --set ysh:upgrade
83 echo
84
85 proc p2 {
86 echo " p2 AA=$[get(ENV, 'AA')] BB=$[get(ENV, 'BB')]"
87 env | egrep 'AA|BB'
88 }
89
90 proc p1 {
91 echo "> p1 AA=$[get(ENV, 'AA')]"
92 AA=aaaa BB=bb p2
93 echo "< p1 AA=$[get(ENV, 'AA')]"
94 }
95
96 AA=a p1
97
98 #
99 # Now with ysh:all
100 #
101
102 shopt --set ysh:all
103 echo
104
105 AA=a p1
106
107 ## STDOUT:
108 > f1 AA=a
109 f2 AA=aaaa BB=bb
110 AA=aaaa
111 BB=bb
112 < f1 AA=a
113
114 > p1 AA=a
115 p2 AA=aaaa BB=bb
116 AA=aaaa
117 BB=bb
118 < p1 AA=a
119
120 > p1 AA=a
121 p2 AA=aaaa BB=bb
122 AA=aaaa
123 BB=bb
124 < p1 AA=a
125 ## END
126
127 #### Temp bindings can use locals in the same frame,(don't introduce new frame)
128
129 # OSH: FOO can use x, but FOO is also bound
130 shfunc() {
131 local x='zzz'
132 # There is no FOO here, because the argument to echo is evaluated first
133 FOO=$x echo "shfunc x=$x FOO=${FOO:-}"
134 FOO=$x eval 'echo shfunc x=$x FOO=$FOO'
135 }
136
137 shfunc
138 echo
139
140 shopt --set ysh:upgrade
141
142 # YSH: FOO can use x, but FOO is also bound
143 proc p {
144 var x = 'zzz'
145 # There is no ENV.FOO here, because the argument to echo is evaluated first
146 FOO=$x echo "ysh x=$x FOO=${FOO:-} ENV.FOO=$[get(ENV, 'FOO')]"
147 FOO=$x eval 'echo ysh x=$x FOO=${FOO:-} ENV.FOO=$[get(ENV, "FOO")]'
148 FOO=$x redir { echo "ysh x=$x FOO=${FOO:-} ENV.FOO=$[get(ENV, 'FOO')]" }
149 }
150
151 p
152
153 ## STDOUT:
154 shfunc x=zzz FOO=
155 shfunc x=zzz FOO=zzz
156
157 ysh x=zzz FOO= ENV.FOO=null
158 ysh x=zzz FOO= ENV.FOO=zzz
159 ysh x=zzz FOO= ENV.FOO=zzz
160 ## END
161
162
163 #### setglobal ENV.PYTHONPATH = 'foo' changes child process state
164 shopt -s ysh:upgrade
165
166 setglobal ENV.PYTHONPATH = 'foo'
167
168 #pp test_ (ENV)
169 #export PYTHONPATH=zz
170
171 # execute POSIX shell
172 sh -c 'echo pythonpath=$PYTHONPATH'
173
174 ## STDOUT:
175 pythonpath=foo
176 ## END
177
178 #### export builtin is disabled in ysh:all, in favor of setglobal
179 shopt -s ysh:all
180
181 setglobal ENV.ZZ = 'setglobal'
182
183 # execute POSIX shell
184 sh -c 'echo ZZ=$ZZ'
185
186 export ZZ='export' # fails
187
188 sh -c 'echo ZZ=$ZZ' # not reached
189
190 ## status: 1
191 ## STDOUT:
192 ZZ=setglobal
193 ## END
194
195 #### ysh:upgrade can use both export builtin and setglobal ENV
196 shopt -s ysh:upgrade
197
198 export ZZ='export' # fails
199
200 sh -c 'echo ZZ=$ZZ' # not reached
201
202 setglobal ENV.ZZ = 'setglobal' # this takes precedence
203
204 # execute POSIX shell
205 sh -c 'echo ZZ=$ZZ'
206
207 ## STDOUT:
208 ZZ=export
209 ZZ=setglobal
210 ## END
211
212
213 #### PS4 environment variable is respected
214 shopt -s ysh:upgrade
215
216 setglobal ENV.PS4 = '%%% '
217
218 $[ENV.SH] -c 'set -x; echo 1; echo 2'
219
220 ## STDOUT:
221 1
222 2
223 ## END
224 ## STDERR:
225 %%% echo 1
226 %%% echo 2
227 ## END
228
229
230 #### ENV.HOME is respected
231
232 HOME=zz-osh
233 echo ~/src
234
235 shopt --set ysh:upgrade
236
237 setvar ENV.HOME = 'ysh-zz'
238
239 # TODO: this should consult ENV.HOME
240 echo ~/src
241
242 # not set by spec test framework
243 #echo $[ENV.HOME]
244
245 ## STDOUT:
246 zz-osh/src
247 ysh-zz/src
248 ## END
249
250 #### exec builtin respects ENV
251
252 shopt --set ysh:upgrade
253
254 #export ZZ=zzz
255 setglobal ENV.ZZ = 'zz'
256
257 env sh -c 'echo child ZZ=$ZZ'
258
259 exec env sh -c 'echo exec ZZ=$ZZ'
260
261 ## STDOUT:
262 child ZZ=zz
263 exec ZZ=zz
264 ## END
265
266 #### setglobal quirk - do we need setenv?
267 shopt --set ysh:all
268
269 proc p {
270 # quirk: MOST visible Dict is mutated
271 setglobal ENV.perm = 'perm'
272 }
273
274 FOO=bar p
275
276 # quirk: that Dict is gone
277 # we could add 'setenv' to work around this
278 pp test_ (get(ENV, 'perm'))
279
280 p
281 pp test_ (get(ENV, 'perm'))
282
283
284 ## STDOUT:
285 (Null) null
286 (Str) "perm"
287 ## END
288
289 #### try to corrupt ENV var from user code
290 shopt --set ysh:all
291
292 setglobal ENV.AA = 'aa'
293
294 proc p {
295 # this doesn't do anything, because Mem still have self.env_object
296 setglobal ENV = null
297
298 # TODO: there could be other ways to mess it up, and hit e_die()
299 # Right now, it's not possible to mutate 'prototype'. But if so we could
300 # mess up ENV.
301 }
302
303 FOO=bar p
304
305 = ENV.AA
306
307 ## STDOUT:
308 (Str) 'aa'
309 ## END