1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
|
# tests for miscellaneous builtins not tested elsewhere
set +p
set +o posix
ulimit -c 0 2>/dev/null
# check that break breaks loops
for i in a b c; do echo $i; break; echo bad-$i; done
echo end-1
for i in a b c; do echo $i; break 1; echo bad-$i; done
echo end-2
for i in a b c; do
for j in x y z; do
echo $i:$j
break
echo bad-$i
done
echo end-$i
done
echo end-3
# check that break breaks nested loops
for i in a b c; do
for j in x y z; do
echo $i:$j
break 2
echo bad-$i
done
echo end-$i
done
echo end
# check that continue continues loops
for i in a b c; do echo $i; continue; echo bad-$i ; done
echo end-1
for i in a b c; do echo $i; continue 1; echo bad-$i; done
echo end-2
for i in a b c; do
for j in x y z; do
echo $i:$j
continue
echo bad-$i-$j
done
echo end-$i
done
echo end-3
# check that continue breaks out of nested loops
for i in a b c; do
for j in x y z; do
echo $i:$j
continue 2
echo bad-$i-$j
done
echo end-$i
done
echo end
# check that `eval' re-evaluates arguments, but `builtin' and `command' do not
AVAR='$BVAR'
BVAR=foo
echo $AVAR
builtin echo $AVAR
command echo $AVAR
eval echo \$AVAR
eval echo $AVAR
# test out eval with a temp environment
AVAR=bar eval echo \$AVAR
BVAR=xxx eval echo $AVAR
unset -v AVAR BVAR
# test umask
mask=$(umask)
umask 022
umask
umask -S
umask -S u=rwx,g=rwx,o=rx >/dev/null # 002
umask
umask -S
umask -p
umask -p -S
umask 0
umask -S
umask ${mask} # restore original mask
# builtin/command without arguments should do nothing. maybe someday they will
builtin
command
# test enable
enable -ps
enable -aps ; enable -nps
enable -n test
case "$(type -t test)" in
builtin) echo oops -- enable -n test failed ;;
*) echo enable -n test worked ;;
esac
enable test
case "$(type -t test)" in
builtin) echo enable test worked ;;
*) echo oops -- enable test failed ;;
esac
# test options to exec
(exec -a specialname ${THIS_SH} -c 'echo $0' )
(exec -l -a specialname ${THIS_SH} -c 'echo $0' )
# test `clean' environment. if /bin/sh is bash, and the script version of
# printenv is run, there will be variables in the environment that bash
# sets on startup. Also test code that prefixes argv[0] with a dash.
(export FOO=BAR ; exec -c -l printenv ) | grep FOO
(FOO=BAR exec -c printenv ) | grep FOO
(export FOO=BAR ; exec printenv ) | grep FOO
(FOO=BAR exec printenv ) | grep FOO
# ok, forget everything about hashed commands
hash -r
hash
# this had better succeed, since command -p guarantees we will find the
# standard utilties
command -p hash rm
# check out source/.
# sourcing a zero-length-file had better not be an error
rm -f /tmp/zero-length-file
cp /dev/null /tmp/zero-length-file
. /tmp/zero-length-file
echo $?
rm /tmp/zero-length-file
AVAR=AVAR
. ./source1.sub
AVAR=foo . ./source1.sub
. ./source2.sub
echo $?
set -- a b c
. ./source3.sub
# make sure source with arguments does not change the shell's positional
# parameters, but that the sourced file sees the arguments as its
# positional parameters
echo "$@"
. ./source3.sub x y z
echo "$@"
# but if the sourced script sets the positional parameters explicitly, they
# should be reflected in the calling shell's positional parameters. this
# also tests one of the shopt options that controls source using $PATH to
# find the script
echo "$@"
shopt -u sourcepath
. source4.sub
echo "$@"
# this is complicated when the sourced scripts gets its own positional
# parameters from arguments to `.'
set -- a b c
echo "$@"
. source4.sub x y z
echo "$@"
# test out cd and $CDPATH
${THIS_SH} ./builtins1.sub
# test behavior of `.' when given a non-existant file argument
${THIS_SH} ./source5.sub
# in posix mode, assignment statements preceding special builtins are
# reflected in the shell environment. `.' and `eval' need special-case
# code.
set -o posix
echo $AVAR
AVAR=foo . ./source1.sub
echo $AVAR
AVAR=AVAR
echo $AVAR
AVAR=foo eval echo \$AVAR
echo $AVAR
AVAR=AVAR
echo $AVAR
AVAR=foo :
echo $AVAR
set +o posix
# but assignment statements preceding `export' are always reflected in
# the environment
foo="" export foo
declare -p foo
unset foo
# assignment statements preceding `declare' should be displayed correctly,
# but not persist after the command
FOO='$$' declare -p FOO
declare -p FOO
unset FOO
# except for `declare -x', which should be equivalent to `export'
FOO='$$' declare -x FOO
declare -p FOO
unset FOO
# test out kill -l. bash versions prior to 2.01 did `kill -l num' wrong
sigone=$(kill -l | sed -n 's:^ 1) *\([^ ]*\)[ ].*$:\1:p')
case "$(kill -l 1)" in
${sigone/SIG/}) echo ok;;
*) echo oops -- kill -l failure;;
esac
# kill -l and trap -l should display exactly the same output
sigonea=$(trap -l | sed -n 's:^ 1) *\([^ ]*\)[ ].*$:\1:p')
if [ "$sigone" != "$sigonea" ]; then
echo oops -- kill -l and trap -l differ
fi
# POSIX.2 says that exit statuses > 128 are mapped to signal names by
# subtracting 128 so you can find out what signal killed a process
case "$(kill -l $(( 128 + 1)) )" in
${sigone/SIG/}) echo ok;;
*) echo oops -- kill -l 129 failure;;
esac
# out-of-range signal numbers should report the argument in the error
# message, not 128 less than the argument
kill -l 4096
# kill -l NAME should return the signal number
kill -l ${sigone/SIG/}
# test behavior of shopt xpg_echo
${THIS_SH} ./builtins2.sub
# this must be last -- it is a fatal error
exit status
echo after bad exit
|