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 # Bash only implements it behind the posix option
9 #test -n "$BASH_VERSION" && set -o posix
10 case $SH in
11 *dash|*zsh|*osh)
12 ;;
13 *)
14 set -o posix
15 ;;
16 esac
17 foo=bar :
18 echo -$foo-
19 ## STDOUT:
20 -bar-
21 ## END
22 ## BUG zsh STDOUT:
23 --
24 ## END
25
26 #### true is not special
27 foo=bar true
28 echo $foo
29 ## stdout:
30
31 #### Shift is special and the whole script exits if it returns non-zero
32 test -n "$BASH_VERSION" && set -o posix
33 set -- a b
34 shift 3
35 echo status=$?
36 ## stdout-json: ""
37 ## status: 1
38 ## OK dash status: 2
39 ## BUG bash/zsh status: 0
40 ## BUG bash/zsh STDOUT:
41 status=1
42 ## END
43
44 #### set is special and fails, even if using || true
45 shopt -s invalid_ || true
46 echo ok
47 set -o invalid_ || true
48 echo should not get here
49 ## STDOUT:
50 ok
51 ## END
52 ## status: 1
53 ## OK dash status: 2
54 ## BUG bash status: 0
55 ## BUG bash STDOUT:
56 ok
57 should not get here
58 ## END
59
60 #### Special builtins can't be redefined as functions
61 # bash manual says they are 'found before' functions.
62 test -n "$BASH_VERSION" && set -o posix
63 export() {
64 echo 'export func'
65 }
66 export hi
67 echo status=$?
68 ## status: 2
69 ## BUG mksh/zsh status: 0
70 ## BUG mksh/zsh stdout: status=0
71
72 #### Non-special builtins CAN be redefined as functions
73 test -n "$BASH_VERSION" && set -o posix
74 true() {
75 echo 'true func'
76 }
77 true hi
78 echo status=$?
79 ## STDOUT:
80 true func
81 status=0
82 ## END