OILS / spec / alias.test.sh View on Github | oils.pub

573 lines, 297 significant
1## compare_shells: bash dash mksh zsh
2
3
4# Alias is in POSIX.
5#
6# http://pubs.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_03_01
7#
8# Bash is the only one that doesn't support aliases by default!
9
10#### Usage of builtins
11shopt -s expand_aliases || true
12alias -- foo=echo
13echo status=$?
14foo x
15unalias -- foo
16foo x
17## status: 127
18## STDOUT:
19status=0
20x
21## END
22# dash doesn't accept --
23## BUG dash STDOUT:
24status=1
25x
26## END
27
28#### Basic alias
29shopt -s expand_aliases # bash requires this
30alias hi='echo hello world'
31hi || echo 'should not run this'
32echo hi # second word is not
33'hi' || echo 'expected failure'
34## STDOUT:
35hello world
36hi
37expected failure
38## END
39
40#### define and use alias on a single line
41shopt -s expand_aliases
42alias e=echo; e one # this is not alias-expanded because we parse lines at once
43e two; e three
44## STDOUT:
45two
46three
47## END
48
49#### alias can override builtin
50shopt -s expand_aliases
51alias echo='echo foo'
52echo bar
53## stdout: foo bar
54
55#### defining multiple aliases, then unalias
56shopt -s expand_aliases # bash requires this
57x=x
58y=y
59alias echo-x='echo $x' echo-y='echo $y'
60echo status=$?
61echo-x X
62echo-y Y
63unalias echo-x echo-y
64echo status=$?
65echo-x X || echo undefined
66echo-y Y || echo undefined
67## STDOUT:
68status=0
69x X
70y Y
71status=0
72undefined
73undefined
74## END
75
76#### alias not defined
77alias e='echo' nonexistentZ
78echo status=$?
79## STDOUT:
80status=1
81## END
82## OK mksh STDOUT:
83nonexistentZ alias not found
84status=1
85## END
86
87#### unalias not defined
88alias e=echo ll='ls -l'
89unalias e nonexistentZ ll
90echo status=$?
91## STDOUT:
92status=1
93## END
94
95#### unalias -a
96
97alias foo=bar
98alias spam=eggs
99
100alias | egrep 'foo|spam' | wc -l
101
102unalias -a
103
104alias
105echo status=$?
106
107## STDOUT:
1082
109status=0
110## END
111
112#### List aliases by providing names
113
114alias e=echo ll='ls -l'
115alias e ll
116
117## STDOUT:
118alias e='echo'
119alias ll='ls -l'
120## END
121## OK mksh/zsh STDOUT:
122e=echo
123ll='ls -l'
124## END
125## OK dash STDOUT:
126e='echo'
127ll='ls -l'
128## END
129
130#### alias without args lists all aliases
131alias ex=exit ll='ls -l'
132alias | grep -E 'ex=|ll=' # need to grep because mksh/zsh have builtin aliases
133echo status=$?
134## STDOUT:
135alias ex='exit'
136alias ll='ls -l'
137status=0
138## END
139## OK dash STDOUT:
140ex='exit'
141ll='ls -l'
142status=0
143## END
144## OK mksh/zsh STDOUT:
145ex=exit
146ll='ls -l'
147status=0
148## END
149
150#### unalias without args is a usage error
151unalias
152if test "$?" != 0; then echo usage-error; fi
153## STDOUT:
154usage-error
155## END
156## BUG mksh/dash STDOUT:
157## END
158
159#### alias with trailing space causes alias expansion on second word
160shopt -s expand_aliases # bash requires this
161
162alias hi='echo hello world '
163alias punct='!!!'
164
165hi punct
166
167alias hi='echo hello world' # No trailing space
168
169hi punct
170
171## STDOUT:
172hello world !!!
173hello world punct
174## END
175
176#### Recursive alias expansion of first word
177shopt -s expand_aliases # bash requires this
178alias hi='e_ hello world'
179alias e_='echo __'
180hi # first hi is expanded to echo hello world; then echo is expanded. gah.
181## STDOUT:
182__ hello world
183## END
184
185#### Recursive alias expansion of SECOND word
186shopt -s expand_aliases # bash requires this
187alias one='ONE '
188alias two='TWO '
189alias e_='echo one '
190e_ two hello world
191## STDOUT:
192one TWO hello world
193## END
194
195#### Expansion of alias with variable
196shopt -s expand_aliases # bash requires this
197x=x
198alias echo-x='echo $x' # nothing is evaluated here
199x=y
200echo-x hi
201## STDOUT:
202y hi
203## END
204
205#### Alias must be an unquoted word, no expansions allowed
206shopt -s expand_aliases # bash requires this
207alias echo_alias_='echo'
208cmd=echo_alias_
209echo_alias_ X # this works
210$cmd X # this fails because it's quoted
211echo status=$?
212## STDOUT:
213X
214status=127
215## END
216
217#### first and second word are the same alias, but no trailing space
218shopt -s expand_aliases # bash requires this
219x=x
220alias echo-x='echo $x' # nothing is evaluated here
221echo-x echo-x
222## STDOUT:
223x echo-x
224## END
225
226#### first and second word are the same alias, with trailing space
227shopt -s expand_aliases # bash requires this
228x=x
229alias echo-x='echo $x ' # nothing is evaluated here
230echo-x echo-x
231## STDOUT:
232x echo x
233## END
234
235#### Invalid syntax of alias
236shopt -s expand_aliases # bash requires this
237alias echo_alias_= 'echo --; echo' # bad space here
238echo_alias_ x
239## status: 127
240
241#### Dynamic alias definition
242shopt -s expand_aliases # bash requires this
243x=x
244name='echo_alias_'
245val='=echo'
246alias "$name$val"
247echo_alias_ X
248## stdout: X
249
250#### Alias name with punctuation
251# NOTE: / is not OK in bash, but OK in other shells. Must less restrictive
252# than var names.
253shopt -s expand_aliases # bash requires this
254alias e_+.~x='echo'
255e_+.~x X
256## stdout: X
257
258#### Syntax error after expansion
259shopt -s expand_aliases # bash requires this
260alias e_=';; oops'
261e_ x
262## status: 2
263## OK mksh/zsh status: 1
264
265#### Loop split across alias and arg works
266shopt -s expand_aliases # bash requires this
267alias e_='for i in 1 2 3; do echo $i;'
268e_ done
269## STDOUT:
2701
2712
2723
273## END
274
275#### Loop split across alias in another way
276shopt -s expand_aliases
277alias e_='for i in 1 2 3; do echo '
278e_ $i; done
279## STDOUT:
2801
2812
2823
283## END
284## OK osh stdout-json: ""
285## OK osh status: 2
286
287#### Loop split across both iterative and recursive aliases
288shopt -s expand_aliases # bash requires this
289alias FOR1='for '
290alias FOR2='FOR1 '
291alias eye1='i '
292alias eye2='eye1 '
293alias IN='in '
294alias onetwo='$one "2" ' # NOTE: this does NOT work in any shell except bash.
295one=1
296FOR2 eye2 IN onetwo 3; do echo $i; done
297## STDOUT:
2981
2992
3003
301## END
302## OK osh stdout-json: ""
303## OK osh status: 2
304## BUG zsh stdout-json: ""
305
306#### Alias with a quote in the middle is a syntax error
307shopt -s expand_aliases
308alias e_='echo "'
309var=x
310e_ '${var}"'
311## status: 2
312## OK mksh/zsh status: 1
313
314#### Alias with internal newlines
315shopt -s expand_aliases
316alias e_='echo 1
317echo 2
318echo 3'
319var='echo foo'
320e_ ${var}
321## STDOUT:
3221
3232
3243 echo foo
325## END
326
327#### Alias trailing newline
328shopt -s expand_aliases
329alias e_='echo 1
330echo 2
331echo 3
332'
333var='echo foo'
334e_ ${var}
335## STDOUT:
3361
3372
3383
339foo
340## END
341## OK zsh STDOUT:
3421
3432
3443
345## END
346## OK zsh status: 127
347
348#### Two aliases in pipeline
349shopt -s expand_aliases
350alias SEQ='seq '
351alias THREE='3 '
352alias WC='wc '
353SEQ THREE | WC -l
354## stdout: 3
355
356#### Alias not respected inside $()
357# This could be parsed correctly, but it is only defined in a child process.
358shopt -s expand_aliases
359echo $(alias sayhi='echo hello')
360sayhi
361## status: 127
362
363#### Alias can be defined and used on a single line
364shopt -s expand_aliases
365alias sayhi='echo hello'; sayhi same line
366sayhi other line
367## STDOUT:
368hello other line
369## END
370
371#### Alias is respected inside eval
372shopt -s expand_aliases
373eval "alias sayhi='echo hello'
374sayhi inside"
375sayhi outside
376## STDOUT:
377hello inside
378hello outside
379## END
380## BUG zsh STDOUT:
381hello outside
382## END
383
384#### alias with redirects works
385shopt -s expand_aliases
386alias e_=echo
387>$TMP/alias1.txt e_ 1
388e_ >$TMP/alias2.txt 2
389e_ 3 >$TMP/alias3.txt
390cat $TMP/alias1.txt $TMP/alias2.txt $TMP/alias3.txt
391## STDOUT:
3921
3932
3943
395## END
396
397#### alias with environment bindings works
398shopt -s expand_aliases
399alias p_=printenv.py
400FOO=1 printenv.py FOO
401FOO=2 p_ FOO
402## STDOUT:
4031
4042
405## END
406
407#### alias with line continuation in the middle
408shopt -s expand_aliases
409alias e_='echo '
410alias one='ONE '
411alias two='TWO '
412alias three='THREE' # no trailing space
413e_ one \
414 two one \
415 two three two \
416 one
417## stdout: ONE TWO ONE TWO THREE two one
418
419#### alias for left brace
420shopt -s expand_aliases
421alias LEFT='{'
422LEFT echo one; echo two; }
423## STDOUT:
424one
425two
426## END
427## OK osh stdout-json: ""
428## OK osh status: 2
429
430#### alias for left paren
431shopt -s expand_aliases
432alias LEFT='('
433LEFT echo one; echo two )
434## STDOUT:
435one
436two
437## END
438## OK osh stdout-json: ""
439## OK osh status: 2
440
441#### alias used in subshell and command sub
442# This spec seems to be contradictoary?
443# http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_03_01
444# "When used as specified by this volume of POSIX.1-2017, alias definitions
445# shall not be inherited by separate invocations of the shell or by the utility
446# execution environments invoked by the shell; see Shell Execution
447# Environment."
448shopt -s expand_aliases
449alias echo_='echo [ '
450( echo_ subshell; )
451echo $(echo_ commandsub)
452## STDOUT:
453[ subshell
454[ commandsub
455## END
456
457#### alias used in here doc
458shopt -s expand_aliases
459alias echo_='echo [ '
460cat <<EOF
461$(echo_ ])
462EOF
463## STDOUT:
464[ ]
465## END
466
467#### here doc inside alias
468shopt -s expand_aliases
469alias c='cat <<EOF
470$(echo hi)
471EOF
472'
473c
474## STDOUT:
475hi
476## END
477## BUG bash stdout-json: ""
478## BUG bash status: 127
479
480#### Corner case: alias inside LHS array arithmetic expression
481shopt -s expand_aliases
482alias zero='echo 0'
483a[$(zero)]=ZERO
484a[1]=ONE
485argv.py "${a[@]}"
486## STDOUT:
487['ZERO', 'ONE']
488## END
489## N-I dash stdout-json: ""
490## N-I dash status: 2
491## N-I zsh stdout-json: ""
492## N-I zsh status: 1
493
494#### Alias that is pipeline
495shopt -s expand_aliases
496alias t1='echo hi|wc -c'
497t1
498## STDOUT:
4993
500## END
501
502#### Alias that is && || ;
503shopt -s expand_aliases
504alias t1='echo one && echo two && echo 3 | wc -l;
505echo four'
506t1
507## STDOUT:
508one
509two
5101
511four
512## END
513
514#### Alias and command sub (bug regression)
515cd $TMP
516shopt -s expand_aliases
517echo foo bar > tmp.txt
518alias a=argv.py
519a `cat tmp.txt`
520## stdout: ['foo', 'bar']
521
522#### Alias and arithmetic
523shopt -s expand_aliases
524alias a=argv.py
525a $((1 + 2))
526## stdout: ['3']
527
528#### Alias and PS4
529# dash enters an infinite loop!
530case $SH in
531 dash)
532 exit 1
533 ;;
534esac
535
536set -x
537PS4='+$(echo trace) '
538shopt -s expand_aliases
539alias a=argv.py
540a foo bar
541## stdout: ['foo', 'bar']
542## BUG dash status: 1
543## BUG dash stdout-json: ""
544
545#### alias with keywords
546# from issue #299
547shopt -s expand_aliases
548alias a=
549
550# both of these fail to parse in OSH
551# this is because of our cleaner evaluation model
552
553a (( var = 0 ))
554#a case x in x) true ;; esac
555
556echo done
557## stdout: done
558## OK osh status: 2
559## OK osh stdout-json: ""
560
561
562#### alias with word of multiple lines
563shopt -s expand_aliases
564
565alias ll='ls -l'
566ll '1
567 2
568 3'
569echo status=$?
570
571## STDOUT:
572status=2
573## END