1 |
#!/usr/bin/env bash |
2 |
# |
3 |
# NOTES: |
4 |
# - osh is using the external binary. |
5 |
# - because ! -a -o ( ) are the same, we can share logic with [[. |
6 |
|
7 |
### zero args: [ ] |
8 |
[ ] || echo false |
9 |
# stdout: false |
10 |
|
11 |
### one arg: [ x ] where x is one of '=' '!' '(' ']' |
12 |
[ = ] |
13 |
echo status=$? |
14 |
[ ] ] |
15 |
echo status=$? |
16 |
[ '!' ] |
17 |
echo status=$? |
18 |
[ '(' ] |
19 |
echo status=$? |
20 |
# stdout-json: "status=0\nstatus=0\nstatus=0\nstatus=0\n" |
21 |
|
22 |
### one arg: empty string is false. Equivalent to -n. |
23 |
test 'a' && echo true |
24 |
test '' || echo false |
25 |
# stdout-json: "true\nfalse\n" |
26 |
|
27 |
### -a as unary operator (alias of -e) |
28 |
# NOT IMPLEMENTED FOR OSH, but could be later. See comment in core/id_kind.py. |
29 |
[ -a / ] |
30 |
echo status=$? |
31 |
[ -a /nonexistent ] |
32 |
echo status=$? |
33 |
# stdout-json: "status=0\nstatus=1\n" |
34 |
# N-I dash/osh stdout-json: "status=2\nstatus=2\n" |
35 |
|
36 |
### two args: -z with = ! ( ] |
37 |
[ -z = ] |
38 |
echo status=$? |
39 |
[ -z ] ] |
40 |
echo status=$? |
41 |
[ -z '!' ] |
42 |
echo status=$? |
43 |
[ -z '(' ] |
44 |
echo status=$? |
45 |
# stdout-json: "status=1\nstatus=1\nstatus=1\nstatus=1\n" |
46 |
|
47 |
### three args |
48 |
[ foo = '' ] |
49 |
echo status=$? |
50 |
[ foo -a '' ] |
51 |
echo status=$? |
52 |
[ foo -o '' ] |
53 |
echo status=$? |
54 |
[ ! -z foo ] |
55 |
echo status=$? |
56 |
[ \( foo \) ] |
57 |
echo status=$? |
58 |
# stdout-json: "status=1\nstatus=1\nstatus=0\nstatus=0\nstatus=0\n" |
59 |
|
60 |
### four args |
61 |
[ ! foo = foo ] |
62 |
echo status=$? |
63 |
[ \( -z foo \) ] |
64 |
echo status=$? |
65 |
# stdout-json: "status=1\nstatus=1\n" |
66 |
|
67 |
### test with extra args is syntax error |
68 |
test -n x ] |
69 |
echo status=$? |
70 |
test -n x y |
71 |
echo status=$? |
72 |
# stdout-json: "status=2\nstatus=2\n" |
73 |
|
74 |
### ] syntax errors |
75 |
[ -n x # missing ] |
76 |
echo status=$? |
77 |
[ -n x ] y # extra arg after ] |
78 |
echo status=$? |
79 |
[ -n x y # extra arg |
80 |
echo status=$? |
81 |
# stdout-json: "status=2\nstatus=2\nstatus=2\n" |
82 |
|
83 |
### -n |
84 |
test -n 'a' && echo true |
85 |
test -n '' || echo false |
86 |
# stdout-json: "true\nfalse\n" |
87 |
|
88 |
### ! -a -o |
89 |
[ -z '' -a ! -z x ] |
90 |
echo status=$? |
91 |
# stdout: status=0 |
92 |
|
93 |
### ( ) |
94 |
[ -z '' -a '(' ! -z x ')' ] |
95 |
echo status=$? |
96 |
# stdout: status=0 |
97 |
|
98 |
### ( ) ! -a -o with system version of [ |
99 |
command [ --version |
100 |
command [ -z '' -a '(' ! -z x ')' ] && echo true |
101 |
# stdout: true |
102 |
|
103 |
### == is alias for = |
104 |
[ a = a ] && echo true |
105 |
[ a == a ] && echo true |
106 |
# stdout-json: "true\ntrue\n" |
107 |
# BUG dash stdout-json: "true\n" |
108 |
# BUG dash status: 2 |
109 |
|
110 |
### == and = does not do glob |
111 |
[ abc = 'a*' ] |
112 |
echo status=$? |
113 |
[ abc == 'a*' ] |
114 |
echo status=$? |
115 |
# stdout-json: "status=1\nstatus=1\n" |
116 |
# N-I dash stdout-json: "status=1\nstatus=2\n" |
117 |
|
118 |
### [ with op variable |
119 |
# OK -- parsed AFTER evaluation of vars |
120 |
op='=' |
121 |
[ a $op a ] && echo true |
122 |
[ a $op b ] || echo false |
123 |
# status: 0 |
124 |
# stdout-json: "true\nfalse\n" |
125 |
|
126 |
### [ with unquoted empty var |
127 |
empty='' |
128 |
[ $empty = '' ] && echo true |
129 |
# status: 2 |
130 |
|
131 |
### [ compare with literal -f |
132 |
# Hm this is the same |
133 |
var=-f |
134 |
[ $var = -f ] && echo true |
135 |
[ '-f' = $var ] && echo true |
136 |
# stdout-json: "true\ntrue\n" |
137 |
|
138 |
### [ '(' foo ] is runtime syntax error |
139 |
[ '(' foo ] |
140 |
echo status=$? |
141 |
# stdout: status=2 |
142 |
|
143 |
### -z '>' implies two token lookahead |
144 |
[ -z ] && echo true # -z is operand |
145 |
[ -z '>' ] || echo false # -z is operator |
146 |
[ -z '>' -- ] && echo true # -z is operand |
147 |
# stdout-json: "true\nfalse\ntrue\n" |
148 |
|
149 |
### operator/operand ambiguity with ] |
150 |
# bash parses this as '-z' AND ']', which is true. It's a syntax error in |
151 |
# dash/mksh. |
152 |
[ -z -a ] ] |
153 |
echo status=$? |
154 |
# stdout: status=0 |
155 |
# OK mksh stdout: status=2 |
156 |
# OK dash stdout: status=2 |
157 |
|
158 |
### operator/operand ambiguity with -a |
159 |
# bash parses it as '-z' AND '-a'. It's a syntax error in mksh but somehow a |
160 |
# runtime error in dash. |
161 |
[ -z -a -a ] |
162 |
echo status=$? |
163 |
# stdout: status=0 |
164 |
# OK mksh stdout: status=2 |
165 |
# OK dash stdout: status=1 |
166 |
|
167 |
### -d |
168 |
test -d $TMP |
169 |
echo status=$? |
170 |
test -d $TMP/__nonexistent_Z_Z__ |
171 |
echo status=$? |
172 |
# stdout-json: "status=0\nstatus=1\n" |
173 |
|
174 |
### -x |
175 |
rm -f $TMP/x |
176 |
echo 'echo hi' > $TMP/x |
177 |
test -x $TMP/x || echo 'no' |
178 |
chmod +x $TMP/x |
179 |
test -x $TMP/x && echo 'yes' |
180 |
test -x $TMP/__nonexistent__ || echo 'bad' |
181 |
# stdout-json: "no\nyes\nbad\n" |