OILS / spec / alias.test.sh View on Github | oilshell.org

552 lines, 288 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#### listing given aliases
96alias e=echo ll='ls -l'
97alias e ll
98## STDOUT:
99alias e='echo'
100alias ll='ls -l'
101## END
102## OK mksh/zsh STDOUT:
103e=echo
104ll='ls -l'
105## END
106## OK dash STDOUT:
107e='echo'
108ll='ls -l'
109## END
110
111#### alias without args lists all aliases
112alias ex=exit ll='ls -l'
113alias | grep -E 'ex=|ll=' # need to grep because mksh/zsh have builtin aliases
114echo status=$?
115## STDOUT:
116alias ex='exit'
117alias ll='ls -l'
118status=0
119## END
120## OK dash STDOUT:
121ex='exit'
122ll='ls -l'
123status=0
124## END
125## OK mksh/zsh STDOUT:
126ex=exit
127ll='ls -l'
128status=0
129## END
130
131#### unalias without args is a usage error
132unalias
133echo status=$?
134## stdout: status=2
135## BUG mksh/dash stdout: status=0
136## BUG zsh stdout: status=1
137
138#### alias with trailing space causes alias expansion on second word
139shopt -s expand_aliases # bash requires this
140
141alias hi='echo hello world '
142alias punct='!!!'
143
144hi punct
145
146alias hi='echo hello world' # No trailing space
147
148hi punct
149
150## STDOUT:
151hello world !!!
152hello world punct
153## END
154
155#### Recursive alias expansion of first word
156shopt -s expand_aliases # bash requires this
157alias hi='e_ hello world'
158alias e_='echo __'
159hi # first hi is expanded to echo hello world; then echo is expanded. gah.
160## STDOUT:
161__ hello world
162## END
163
164#### Recursive alias expansion of SECOND word
165shopt -s expand_aliases # bash requires this
166alias one='ONE '
167alias two='TWO '
168alias e_='echo one '
169e_ two hello world
170## STDOUT:
171one TWO hello world
172## END
173
174#### Expansion of alias with variable
175shopt -s expand_aliases # bash requires this
176x=x
177alias echo-x='echo $x' # nothing is evaluated here
178x=y
179echo-x hi
180## STDOUT:
181y hi
182## END
183
184#### Alias must be an unquoted word, no expansions allowed
185shopt -s expand_aliases # bash requires this
186alias echo_alias_='echo'
187cmd=echo_alias_
188echo_alias_ X # this works
189$cmd X # this fails because it's quoted
190echo status=$?
191## STDOUT:
192X
193status=127
194## END
195
196#### first and second word are the same alias, but no trailing space
197shopt -s expand_aliases # bash requires this
198x=x
199alias echo-x='echo $x' # nothing is evaluated here
200echo-x echo-x
201## STDOUT:
202x echo-x
203## END
204
205#### first and second word are the same alias, with trailing space
206shopt -s expand_aliases # bash requires this
207x=x
208alias echo-x='echo $x ' # nothing is evaluated here
209echo-x echo-x
210## STDOUT:
211x echo x
212## END
213
214#### Invalid syntax of alias
215shopt -s expand_aliases # bash requires this
216alias echo_alias_= 'echo --; echo' # bad space here
217echo_alias_ x
218## status: 127
219
220#### Dynamic alias definition
221shopt -s expand_aliases # bash requires this
222x=x
223name='echo_alias_'
224val='=echo'
225alias "$name$val"
226echo_alias_ X
227## stdout: X
228
229#### Alias name with punctuation
230# NOTE: / is not OK in bash, but OK in other shells. Must less restrictive
231# than var names.
232shopt -s expand_aliases # bash requires this
233alias e_+.~x='echo'
234e_+.~x X
235## stdout: X
236
237#### Syntax error after expansion
238shopt -s expand_aliases # bash requires this
239alias e_=';; oops'
240e_ x
241## status: 2
242## OK mksh/zsh status: 1
243
244#### Loop split across alias and arg works
245shopt -s expand_aliases # bash requires this
246alias e_='for i in 1 2 3; do echo $i;'
247e_ done
248## STDOUT:
2491
2502
2513
252## END
253
254#### Loop split across alias in another way
255shopt -s expand_aliases
256alias e_='for i in 1 2 3; do echo '
257e_ $i; done
258## STDOUT:
2591
2602
2613
262## END
263## OK osh stdout-json: ""
264## OK osh status: 2
265
266#### Loop split across both iterative and recursive aliases
267shopt -s expand_aliases # bash requires this
268alias FOR1='for '
269alias FOR2='FOR1 '
270alias eye1='i '
271alias eye2='eye1 '
272alias IN='in '
273alias onetwo='$one "2" ' # NOTE: this does NOT work in any shell except bash.
274one=1
275FOR2 eye2 IN onetwo 3; do echo $i; done
276## STDOUT:
2771
2782
2793
280## END
281## OK osh stdout-json: ""
282## OK osh status: 2
283## BUG zsh stdout-json: ""
284
285#### Alias with a quote in the middle is a syntax error
286shopt -s expand_aliases
287alias e_='echo "'
288var=x
289e_ '${var}"'
290## status: 2
291## OK mksh/zsh status: 1
292
293#### Alias with internal newlines
294shopt -s expand_aliases
295alias e_='echo 1
296echo 2
297echo 3'
298var='echo foo'
299e_ ${var}
300## STDOUT:
3011
3022
3033 echo foo
304## END
305
306#### Alias trailing newline
307shopt -s expand_aliases
308alias e_='echo 1
309echo 2
310echo 3
311'
312var='echo foo'
313e_ ${var}
314## STDOUT:
3151
3162
3173
318foo
319## END
320## OK zsh STDOUT:
3211
3222
3233
324## END
325## OK zsh status: 127
326
327#### Two aliases in pipeline
328shopt -s expand_aliases
329alias SEQ='seq '
330alias THREE='3 '
331alias WC='wc '
332SEQ THREE | WC -l
333## stdout: 3
334
335#### Alias not respected inside $()
336# This could be parsed correctly, but it is only defined in a child process.
337shopt -s expand_aliases
338echo $(alias sayhi='echo hello')
339sayhi
340## status: 127
341
342#### Alias can be defined and used on a single line
343shopt -s expand_aliases
344alias sayhi='echo hello'; sayhi same line
345sayhi other line
346## STDOUT:
347hello other line
348## END
349
350#### Alias is respected inside eval
351shopt -s expand_aliases
352eval "alias sayhi='echo hello'
353sayhi inside"
354sayhi outside
355## STDOUT:
356hello inside
357hello outside
358## END
359## BUG zsh STDOUT:
360hello outside
361## END
362
363#### alias with redirects works
364shopt -s expand_aliases
365alias e_=echo
366>$TMP/alias1.txt e_ 1
367e_ >$TMP/alias2.txt 2
368e_ 3 >$TMP/alias3.txt
369cat $TMP/alias1.txt $TMP/alias2.txt $TMP/alias3.txt
370## STDOUT:
3711
3722
3733
374## END
375
376#### alias with environment bindings works
377shopt -s expand_aliases
378alias p_=printenv.py
379FOO=1 printenv.py FOO
380FOO=2 p_ FOO
381## STDOUT:
3821
3832
384## END
385
386#### alias with line continuation in the middle
387shopt -s expand_aliases
388alias e_='echo '
389alias one='ONE '
390alias two='TWO '
391alias three='THREE' # no trailing space
392e_ one \
393 two one \
394 two three two \
395 one
396## stdout: ONE TWO ONE TWO THREE two one
397
398#### alias for left brace
399shopt -s expand_aliases
400alias LEFT='{'
401LEFT echo one; echo two; }
402## STDOUT:
403one
404two
405## END
406## OK osh stdout-json: ""
407## OK osh status: 2
408
409#### alias for left paren
410shopt -s expand_aliases
411alias LEFT='('
412LEFT echo one; echo two )
413## STDOUT:
414one
415two
416## END
417## OK osh stdout-json: ""
418## OK osh status: 2
419
420#### alias used in subshell and command sub
421# This spec seems to be contradictoary?
422# http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_03_01
423# "When used as specified by this volume of POSIX.1-2017, alias definitions
424# shall not be inherited by separate invocations of the shell or by the utility
425# execution environments invoked by the shell; see Shell Execution
426# Environment."
427shopt -s expand_aliases
428alias echo_='echo [ '
429( echo_ subshell; )
430echo $(echo_ commandsub)
431## STDOUT:
432[ subshell
433[ commandsub
434## END
435
436#### alias used in here doc
437shopt -s expand_aliases
438alias echo_='echo [ '
439cat <<EOF
440$(echo_ ])
441EOF
442## STDOUT:
443[ ]
444## END
445
446#### here doc inside alias
447shopt -s expand_aliases
448alias c='cat <<EOF
449$(echo hi)
450EOF
451'
452c
453## STDOUT:
454hi
455## END
456## BUG bash stdout-json: ""
457## BUG bash status: 127
458
459#### Corner case: alias inside LHS array arithmetic expression
460shopt -s expand_aliases
461alias zero='echo 0'
462a[$(zero)]=ZERO
463a[1]=ONE
464argv.py "${a[@]}"
465## STDOUT:
466['ZERO', 'ONE']
467## END
468## N-I dash stdout-json: ""
469## N-I dash status: 2
470## N-I zsh stdout-json: ""
471## N-I zsh status: 1
472
473#### Alias that is pipeline
474shopt -s expand_aliases
475alias t1='echo hi|wc -c'
476t1
477## STDOUT:
4783
479## END
480
481#### Alias that is && || ;
482shopt -s expand_aliases
483alias t1='echo one && echo two && echo 3 | wc -l;
484echo four'
485t1
486## STDOUT:
487one
488two
4891
490four
491## END
492
493#### Alias and command sub (bug regression)
494cd $TMP
495shopt -s expand_aliases
496echo foo bar > tmp.txt
497alias a=argv.py
498a `cat tmp.txt`
499## stdout: ['foo', 'bar']
500
501#### Alias and arithmetic
502shopt -s expand_aliases
503alias a=argv.py
504a $((1 + 2))
505## stdout: ['3']
506
507#### Alias and PS4
508# dash enters an infinite loop!
509case $SH in
510 dash)
511 exit 1
512 ;;
513esac
514
515set -x
516PS4='+$(echo trace) '
517shopt -s expand_aliases
518alias a=argv.py
519a foo bar
520## stdout: ['foo', 'bar']
521## BUG dash status: 1
522## BUG dash stdout-json: ""
523
524#### alias with keywords
525# from issue #299
526shopt -s expand_aliases
527alias a=
528
529# both of these fail to parse in OSH
530# this is because of our cleaner evaluation model
531
532a (( var = 0 ))
533#a case x in x) true;; esac
534
535echo done
536## stdout: done
537## OK osh status: 2
538## OK osh stdout-json: ""
539
540
541#### alias with word of multiple lines
542shopt -s expand_aliases
543
544alias ll='ls -l'
545ll '1
546 2
547 3'
548echo status=$?
549
550## STDOUT:
551status=2
552## END