1 |
#!/usr/bin/env bash |
2 |
|
3 |
### zero args: [ ] |
4 |
[ ] || echo false |
5 |
# stdout: false |
6 |
|
7 |
### one arg: [ x ] where x is one of '=' '!' '(' ']' |
8 |
[ = ] |
9 |
echo status=$? |
10 |
[ ] ] |
11 |
echo status=$? |
12 |
[ '!' ] |
13 |
echo status=$? |
14 |
[ '(' ] |
15 |
echo status=$? |
16 |
# stdout-json: "status=0\nstatus=0\nstatus=0\nstatus=0\n" |
17 |
|
18 |
### one arg: empty string is false. Equivalent to -n. |
19 |
test 'a' && echo true |
20 |
test '' || echo false |
21 |
# stdout-json: "true\nfalse\n" |
22 |
|
23 |
### -a as unary operator (alias of -e) |
24 |
# NOT IMPLEMENTED FOR OSH, but could be later. See comment in core/id_kind.py. |
25 |
[ -a / ] |
26 |
echo status=$? |
27 |
[ -a /nonexistent ] |
28 |
echo status=$? |
29 |
# stdout-json: "status=0\nstatus=1\n" |
30 |
# N-I dash stdout-json: "status=2\nstatus=2\n" |
31 |
|
32 |
### two args: -z with = ! ( ] |
33 |
[ -z = ] |
34 |
echo status=$? |
35 |
[ -z ] ] |
36 |
echo status=$? |
37 |
[ -z '!' ] |
38 |
echo status=$? |
39 |
[ -z '(' ] |
40 |
echo status=$? |
41 |
# stdout-json: "status=1\nstatus=1\nstatus=1\nstatus=1\n" |
42 |
|
43 |
### three args |
44 |
[ foo = '' ] |
45 |
echo status=$? |
46 |
[ foo -a '' ] |
47 |
echo status=$? |
48 |
[ foo -o '' ] |
49 |
echo status=$? |
50 |
[ ! -z foo ] |
51 |
echo status=$? |
52 |
[ \( foo \) ] |
53 |
echo status=$? |
54 |
# stdout-json: "status=1\nstatus=1\nstatus=0\nstatus=0\nstatus=0\n" |
55 |
|
56 |
### four args |
57 |
[ ! foo = foo ] |
58 |
echo status=$? |
59 |
[ \( -z foo \) ] |
60 |
echo status=$? |
61 |
# stdout-json: "status=1\nstatus=1\n" |
62 |
|
63 |
### test with extra args is syntax error |
64 |
test -n x ] |
65 |
echo status=$? |
66 |
test -n x y |
67 |
echo status=$? |
68 |
## STDOUT: |
69 |
status=2 |
70 |
status=2 |
71 |
## END |
72 |
|
73 |
### ] syntax errors |
74 |
[ |
75 |
echo status=$? |
76 |
test # not a syntax error |
77 |
echo status=$? |
78 |
[ -n x # missing ] |
79 |
echo status=$? |
80 |
[ -n x ] y # extra arg after ] |
81 |
echo status=$? |
82 |
[ -n x y # extra arg |
83 |
echo status=$? |
84 |
## STDOUT: |
85 |
status=2 |
86 |
status=1 |
87 |
status=2 |
88 |
status=2 |
89 |
status=2 |
90 |
## END |
91 |
|
92 |
### -n |
93 |
test -n 'a' && echo true |
94 |
test -n '' || echo false |
95 |
# stdout-json: "true\nfalse\n" |
96 |
|
97 |
### ! -a |
98 |
[ -z '' -a ! -z x ] |
99 |
echo status=$? |
100 |
# stdout: status=0 |
101 |
|
102 |
### -o |
103 |
[ -z x -o ! -z x ] |
104 |
echo status=$? |
105 |
# stdout: status=0 |
106 |
|
107 |
### ( ) |
108 |
[ -z '' -a '(' ! -z x ')' ] |
109 |
echo status=$? |
110 |
# stdout: status=0 |
111 |
|
112 |
### ( ) ! -a -o with system version of [ |
113 |
command [ --version |
114 |
command [ -z '' -a '(' ! -z x ')' ] && echo true |
115 |
# stdout: true |
116 |
|
117 |
### == is alias for = |
118 |
[ a = a ] && echo true |
119 |
[ a == a ] && echo true |
120 |
# stdout-json: "true\ntrue\n" |
121 |
# BUG dash stdout-json: "true\n" |
122 |
# BUG dash status: 2 |
123 |
|
124 |
### == and = does not do glob |
125 |
[ abc = 'a*' ] |
126 |
echo status=$? |
127 |
[ abc == 'a*' ] |
128 |
echo status=$? |
129 |
# stdout-json: "status=1\nstatus=1\n" |
130 |
# N-I dash stdout-json: "status=1\nstatus=2\n" |
131 |
|
132 |
### [ with op variable |
133 |
# OK -- parsed AFTER evaluation of vars |
134 |
op='=' |
135 |
[ a $op a ] && echo true |
136 |
[ a $op b ] || echo false |
137 |
# status: 0 |
138 |
# stdout-json: "true\nfalse\n" |
139 |
|
140 |
### [ with unquoted empty var |
141 |
empty='' |
142 |
[ $empty = '' ] && echo true |
143 |
# status: 2 |
144 |
|
145 |
### [ compare with literal -f |
146 |
# Hm this is the same |
147 |
var=-f |
148 |
[ $var = -f ] && echo true |
149 |
[ '-f' = $var ] && echo true |
150 |
# stdout-json: "true\ntrue\n" |
151 |
|
152 |
### [ '(' foo ] is runtime syntax error |
153 |
[ '(' foo ] |
154 |
echo status=$? |
155 |
# stdout: status=2 |
156 |
|
157 |
### -z '>' implies two token lookahead |
158 |
[ -z ] && echo true # -z is operand |
159 |
[ -z '>' ] || echo false # -z is operator |
160 |
[ -z '>' -- ] && echo true # -z is operand |
161 |
# stdout-json: "true\nfalse\ntrue\n" |
162 |
|
163 |
### operator/operand ambiguity with ] |
164 |
# bash parses this as '-z' AND ']', which is true. It's a syntax error in |
165 |
# dash/mksh. |
166 |
[ -z -a ] ] |
167 |
echo status=$? |
168 |
# stdout: status=0 |
169 |
# OK mksh stdout: status=2 |
170 |
# OK dash stdout: status=2 |
171 |
|
172 |
### operator/operand ambiguity with -a |
173 |
# bash parses it as '-z' AND '-a'. It's a syntax error in mksh but somehow a |
174 |
# runtime error in dash. |
175 |
[ -z -a -a ] |
176 |
echo status=$? |
177 |
# stdout: status=0 |
178 |
# OK mksh stdout: status=2 |
179 |
# OK dash stdout: status=1 |
180 |
|
181 |
### -d |
182 |
test -d $TMP |
183 |
echo status=$? |
184 |
test -d $TMP/__nonexistent_Z_Z__ |
185 |
echo status=$? |
186 |
# stdout-json: "status=0\nstatus=1\n" |
187 |
|
188 |
### -x |
189 |
rm -f $TMP/x |
190 |
echo 'echo hi' > $TMP/x |
191 |
test -x $TMP/x || echo 'no' |
192 |
chmod +x $TMP/x |
193 |
test -x $TMP/x && echo 'yes' |
194 |
test -x $TMP/__nonexistent__ || echo 'bad' |
195 |
# stdout-json: "no\nyes\nbad\n" |
196 |
|
197 |
### -r |
198 |
echo '1' > $TMP/testr_yes |
199 |
echo '2' > $TMP/testr_no |
200 |
chmod -r $TMP/testr_no # remove read permission |
201 |
test -r $TMP/testr_yes && echo 'yes' |
202 |
test -r $TMP/testr_no || echo 'no' |
203 |
# stdout-json: "yes\nno\n" |
204 |
|
205 |
### -w |
206 |
rm -f $TMP/testw_* |
207 |
echo '1' > $TMP/testw_yes |
208 |
echo '2' > $TMP/testw_no |
209 |
chmod -w $TMP/testw_no # remove write permission |
210 |
test -w $TMP/testw_yes && echo 'yes' |
211 |
test -w $TMP/testw_no || echo 'no' |
212 |
# stdout-json: "yes\nno\n" |
213 |
|
214 |
### -h and -L test for symlink |
215 |
touch $TMP/zz |
216 |
ln -s -f $TMP/zz $TMP/symlink |
217 |
ln -s -f $TMP/__nonexistent_ZZ__ $TMP/dangling |
218 |
test -L $TMP/zz || echo no |
219 |
test -h $TMP/zz || echo no |
220 |
test -f $TMP/symlink && echo is-file |
221 |
test -L $TMP/symlink && echo symlink |
222 |
test -h $TMP/symlink && echo symlink |
223 |
test -L $TMP/dangling && echo dangling |
224 |
test -h $TMP/dangling && echo dangling |
225 |
test -f $TMP/dangling || echo 'dangling is not file' |
226 |
## STDOUT: |
227 |
no |
228 |
no |
229 |
is-file |
230 |
symlink |
231 |
symlink |
232 |
dangling |
233 |
dangling |
234 |
dangling is not file |
235 |
## END |
236 |
|
237 |
### -t 1 for stdout |
238 |
# There isn't way to get a terminal in the test environment? |
239 |
[ -t 1 ] |
240 |
echo status=$? |
241 |
## stdout: status=1 |
242 |
|
243 |
### [ -t invalid ] |
244 |
[ -t invalid ] |
245 |
echo status=$? |
246 |
## stdout: status=2 |
247 |
## BUG bash stdout: status=1 |
248 |
|
249 |
### -ot and -nt |
250 |
touch -d 2017/12/31 $TMP/x |
251 |
touch -d 2018/01/01 > $TMP/y |
252 |
test $TMP/x -ot $TMP/y && echo 'older' |
253 |
test $TMP/x -nt $TMP/y || echo 'not newer' |
254 |
test $TMP/x -ot $TMP/x || echo 'not older than itself' |
255 |
test $TMP/x -nt $TMP/x || echo 'not newer than itself' |
256 |
## STDOUT: |
257 |
older |
258 |
not newer |
259 |
not older than itself |
260 |
not newer than itself |
261 |
## END |