OILS / spec / command-sub.test.sh View on Github | oilshell.org

285 lines, 75 significant
1
2#### case
3foo=a; case $foo in [0-9]) echo number;; [a-z]) echo letter;; esac
4## stdout: letter
5
6#### case in subshell
7# Hm this subhell has to know about the closing ) and stuff like that.
8# case_clause is a compound_command, which is a command. And a subshell
9# takes a compound_list, which is a list of terms, which has and_ors in them
10# ... which eventually boils down to a command.
11echo $(foo=a; case $foo in [0-9]) echo number;; [a-z]) echo letter;; esac)
12## stdout: letter
13
14#### Command sub word part
15# "The token shall not be delimited by the end of the substitution."
16foo=FOO; echo $(echo $foo)bar$(echo $foo)
17## stdout: FOObarFOO
18
19#### Backtick
20foo=FOO; echo `echo $foo`bar`echo $foo`
21## stdout: FOObarFOO
22
23#### Backtick 2
24echo `echo -n l; echo -n s`
25## stdout: ls
26
27#### Nested backticks
28# Inner `` are escaped! Not sure how to do triple.. Seems like an unlikely
29# use case. Not sure if I even want to support this!
30echo X > $TMP/000000-first
31echo `\`echo -n l; echo -n s\` $TMP | grep 000000-first`
32## stdout: 000000-first
33
34#### Making command out of command sub should work
35# Works in bash and dash!
36$(echo ec)$(echo ho) split builtin
37## stdout: split builtin
38
39#### Making keyword out of command sub should NOT work
40$(echo f)$(echo or) i in a b c; do echo $i; done
41echo status=$?
42## stdout-json: ""
43## status: 2
44## OK mksh status: 1
45
46#### Command sub with here doc
47echo $(<<EOF tac
48one
49two
50EOF
51)
52## stdout: two one
53
54#### Here doc with pipeline
55<<EOF tac | tr '\n' 'X'
56one
57two
58EOF
59## stdout-json: "twoXoneX"
60
61#### Command Sub word split
62argv.py $(echo 'hi there') "$(echo 'hi there')"
63## stdout: ['hi', 'there', 'hi there']
64
65#### Command Sub trailing newline removed
66s=$(python2 -c 'print("ab\ncd\n")')
67argv.py "$s"
68## stdout: ['ab\ncd']
69
70#### Command Sub trailing whitespace not removed
71s=$(python2 -c 'print("ab\ncd\n ")')
72argv.py "$s"
73## stdout: ['ab\ncd\n ']
74
75#### Command Sub and exit code
76# A command resets the exit code, but an assignment doesn't.
77echo $(echo x; exit 33)
78echo $?
79x=$(echo x; exit 33)
80echo $?
81## STDOUT:
82x
830
8433
85## END
86
87#### Command Sub in local sets exit code
88# A command resets the exit code, but an assignment doesn't.
89f() {
90 echo $(echo x; exit 33)
91 echo $?
92 local x=$(echo x; exit 33)
93 echo $?
94}
95f
96## STDOUT:
97x
980
990
100## END
101
102#### Double Quotes in Command Sub in Double Quotes
103# virtualenv's bin/activate uses this.
104# This is weird! Double quotes within `` is different than double quotes
105# within $()! All shells agree.
106# I think this is related to the nested backticks case!
107echo "x $(echo hi)"
108echo "x $(echo "hi")"
109echo "x $(echo \"hi\")"
110echo "x `echo hi`"
111echo "x `echo "hi"`"
112echo "x `echo \"hi\"`"
113## STDOUT:
114x hi
115x hi
116x "hi"
117x hi
118x hi
119x hi
120## END
121
122#### Escaped quote in [[ ]]
123file=$TMP/command-sub-dbracket
124#rm -f $file
125echo "123 `[[ $(echo \\" > $file) ]]` 456";
126cat $file
127## STDOUT:
128123 456
129"
130## END
131
132#### Quoting " within ``
133echo 1 `echo \"`
134#echo 2 `echo \\"`
135#echo 3 `echo \\\"`
136#echo 4 `echo \\\\"`
137
138## STDOUT:
1391 "
140## END
141
142#### Quoting $ within ``
143echo 1 `echo $`
144echo 2 `echo \$`
145echo 3 `echo \\$`
146echo 4 `echo \\\$`
147echo 5 `echo \\\\$`
148## STDOUT:
1491 $
1502 $
1513 $
1524 $
1535 \$
154## END
155
156#### Quoting $ within `` within double quotes
157echo "1 `echo $`"
158echo "2 `echo \$`"
159echo "3 `echo \\$`"
160echo "4 `echo \\\$`"
161echo "5 `echo \\\\$`"
162## STDOUT:
1631 $
1642 $
1653 $
1664 $
1675 \$
168## END
169
170#### Quoting \ within ``
171# You need FOUR backslashes to make a literal \.
172echo [1 `echo \ `]
173echo [2 `echo \\ `]
174echo [3 `echo \\\\ `]
175## STDOUT:
176[1 ]
177[2 ]
178[3 \]
179## END
180
181#### Quoting \ within `` within double quotes
182echo "[1 `echo \ `]"
183echo "[2 `echo \\ `]"
184echo "[3 `echo \\\\ `]"
185## STDOUT:
186[1 ]
187[2 ]
188[3 \]
189## END
190
191#### Quoting ( within ``
192echo 1 `echo \(`
193echo 2 `echo \\(`
194echo 3 `echo \\ \\(`
195## STDOUT:
1961 (
1972 (
1983 (
199## END
200
201#### Quoting ( within `` within double quotes
202echo "1 `echo \(`"
203echo "2 `echo \\(`"
204echo "3 `echo \\ \\(`"
205## STDOUT:
2061 (
2072 (
2083 (
209## END
210
211#### Quoting non-special characters within ``
212echo [1 `echo \z]`
213echo [2 `echo \\z]`
214echo [3 `echo \\\z]`
215echo [4 `echo \\\\z]`
216## STDOUT:
217[1 z]
218[2 z]
219[3 \z]
220[4 \z]
221## END
222
223#### Quoting non-special characters within `` within double quotes
224echo "[1 `echo \z`]"
225echo "[2 `echo \\z`]"
226echo "[3 `echo \\\z`]"
227echo "[4 `echo \\\\z`]"
228## STDOUT:
229[1 z]
230[2 z]
231[3 \z]
232[4 \z]
233## END
234
235#### Quoting double quotes within backticks
236echo \"foo\" # for comparison
237echo `echo \"foo\"`
238echo `echo \\"foo\\"`
239## STDOUT:
240"foo"
241"foo"
242"foo"
243## END
244
245#### More levels of double quotes in backticks
246# Shells don't agree here, some of them give you form feeds!
247# There are two levels of processing I don't understand.
248echo BUG
249exit
250echo `echo \\\"foo\\\"`
251echo `echo \\\\"foo\\\\"`
252echo `echo \\\\\"foo\\\\\"`
253## BUG bash/dash/mksh/osh STDOUT:
254BUG
255## END
256
257#### Syntax errors with double quotes within backticks
258
259# bash does print syntax errors but somehow it exits 0
260
261$SH -c 'echo `echo "`'
262echo status=$?
263$SH -c 'echo `echo \\\\"`'
264echo status=$?
265
266## STDOUT:
267status=2
268status=2
269## END
270## OK mksh STDOUT:
271status=1
272status=1
273## END
274## OK bash stdout-json: "\nstatus=0\n\nstatus=0\n"
275
276
277#### Empty command sub $() (command::NoOp)
278
279# IMPORTANT: catch assert() failure in child process!!!
280shopt -s command_sub_errexit
281
282echo -$()- ".$()."
283## STDOUT:
284-- ..
285## END