1 #
2 # POSIX rule about special builtins pointed at:
3 #
4 # https://www.reddit.com/r/oilshell/comments/5ykpi3/oildev_is_alive/
5
6 #### : is special and prefix assignments persist after special builtins
7 case $SH in
8 dash|zsh|*osh)
9 ;;
10 *)
11 # for bash
12 set -o posix
13 ;;
14 esac
15 foo=bar :
16 echo foo=$foo
17 ## STDOUT:
18 foo=bar
19 ## END
20 ## BUG zsh STDOUT:
21 foo=
22 ## END
23
24 #### readonly is special and prefix assignments persist
25
26 # Bash only implements it behind the posix option
27 case $SH in
28 dash|zsh|*osh)
29 ;;
30 *)
31 # for bash
32 set -o posix
33 ;;
34 esac
35 foo=bar readonly spam=eggs
36 echo foo=$foo
37 echo spam=$spam
38
39 # should NOT be exported
40 printenv.py foo
41 printenv.py spam
42 ## STDOUT:
43 foo=bar
44 spam=eggs
45 None
46 None
47 ## END
48 ## BUG bash STDOUT:
49 foo=bar
50 spam=eggs
51 bar
52 None
53 ## END
54
55 #### true is not special
56 foo=bar true
57 echo $foo
58 ## stdout:
59
60 #### Shift is special and the whole script exits if it returns non-zero
61 test -n "$BASH_VERSION" && set -o posix
62 set -- a b
63 shift 3
64 echo status=$?
65 ## stdout-json: ""
66 ## status: 1
67 ## OK dash status: 2
68 ## BUG bash/zsh status: 0
69 ## BUG bash/zsh STDOUT:
70 status=1
71 ## END
72
73 #### set is special and fails, even if using || true
74 shopt -s invalid_ || true
75 echo ok
76 set -o invalid_ || true
77 echo should not get here
78 ## STDOUT:
79 ok
80 ## END
81 ## status: 1
82 ## OK dash status: 2
83 ## BUG bash status: 0
84 ## BUG bash STDOUT:
85 ok
86 should not get here
87 ## END
88
89 #### Special builtins can't be redefined as functions
90 # bash manual says they are 'found before' functions.
91 test -n "$BASH_VERSION" && set -o posix
92 export() {
93 echo 'export func'
94 }
95 export hi
96 echo status=$?
97 ## status: 2
98 ## BUG mksh/zsh status: 0
99 ## BUG mksh/zsh stdout: status=0
100
101 #### Non-special builtins CAN be redefined as functions
102 test -n "$BASH_VERSION" && set -o posix
103 true() {
104 echo 'true func'
105 }
106 true hi
107 echo status=$?
108 ## STDOUT:
109 true func
110 status=0
111 ## END