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