1 #!/bin/bash
2
3 ### cd and $PWD
4 cd /
5 echo $PWD
6 # stdout: /
7
8 ### $OLDPWD
9 cd /
10 cd $TMP
11 echo "old: $OLDPWD"
12 cd -
13 # stdout-json: "old: /\n/\n"
14
15 ### pushd/popd
16 set -o errexit
17 cd /
18 pushd $TMP
19 popd
20 pwd
21 # status: 0
22 # N-I dash/mksh status: 127
23
24 ### Source
25 lib=$TMP/spec-test-lib.sh
26 echo 'LIBVAR=libvar' > $lib
27 . $lib # dash doesn't have source
28 echo $LIBVAR
29 # stdout: libvar
30
31 ### time block
32 # bash and mksh work; dash does't. TODO: test substring
33 { time { sleep 0.01; sleep 0.02; } } 2>_tmp/time.txt
34 cat _tmp/time.txt | grep --only-matching real
35 # Just check that we found 'real'.
36 # This is fiddly:
37 # | sed -n -E -e 's/.*(0m0\.03).*/\1/'
38 #
39 # status: 0
40 # stdout: real
41 # BUG dash status: 2
42 # BUG dash stdout-json: ""
43
44 ### Exit builtin
45 exit 3
46 # status: 3
47
48 ### Exit builtin with invalid arg
49 exit invalid
50 # Rationale: runtime errors are 1
51 # status: 1
52 # OK dash/bash status: 2
53
54 ### Export sets a global variable
55 # Even after you do export -n, it still exists.
56 f() { export GLOBAL=X; }
57 f
58 echo $GLOBAL
59 printenv.py GLOBAL
60 # stdout-json: "X\nX\n"
61
62 ### Export sets a global variable that persists after export -n
63 f() { export GLOBAL=X; }
64 f
65 echo $GLOBAL
66 printenv.py GLOBAL
67 export -n GLOBAL
68 echo $GLOBAL
69 printenv.py GLOBAL
70 # stdout-json: "X\nX\nX\nNone\n"
71 # N-I mksh/dash stdout-json: "X\nX\n"
72
73 ### Export a global variable and unset it
74 f() { export GLOBAL=X; }
75 f
76 echo $GLOBAL
77 printenv.py GLOBAL
78 unset GLOBAL
79 echo $GLOBAL
80 printenv.py GLOBAL
81 # stdout-json: "X\nX\n\nNone\n"
82
83 ### Export existing global variables
84 G1=g1
85 G2=g2
86 export G1 G2
87 printenv.py G1 G2
88 # stdout-json: "g1\ng2\n"
89
90 ### Export existing local variable
91 f() {
92 local L1=local1
93 export L1
94 printenv.py L1
95 }
96 f
97 printenv.py L1
98 # stdout-json: "local1\nNone\n"
99
100 ### Export a local that shadows a global
101 V=global
102 f() {
103 local V=local1
104 export V
105 printenv.py V
106 }
107 f
108 printenv.py V # exported local out of scope; global isn't exported yet
109 export V
110 printenv.py V # now it's exported
111 # stdout-json: "local1\nNone\nglobal\n"
112
113 ### Export a variable before defining it
114 export U
115 U=u
116 printenv.py U
117 # stdout: u
118
119 ### Exporting a parent func variable (dynamic scope)
120 # The algorithm is to walk up the stack and export that one.
121 inner() {
122 export outer_var
123 echo "inner: $outer_var"
124 printenv.py outer_var
125 }
126 outer() {
127 local outer_var=X
128 echo "before inner"
129 printenv.py outer_var
130 inner
131 echo "after inner"
132 printenv.py outer_var
133 }
134 outer
135 # stdout-json: "before inner\nNone\ninner: X\nX\nafter inner\nX\n"