1 ## compare_shells: bash-4.4 mksh
2 ## oils_failures_allowed: 1
3
4 # note: some of these pass with AT&T ksh
5
6 # Extended assignment language, e.g. typeset, declare, arrays, etc.
7 # Things that dash doesn't support.
8
9 #### local -a
10 # nixpkgs setup.sh uses this (issue #26)
11 f() {
12 local -a array=(x y z)
13 argv.py "${array[@]}"
14 }
15 f
16 ## stdout: ['x', 'y', 'z']
17 ## N-I mksh stdout-json: ""
18 ## N-I mksh status: 1
19
20 #### declare -a
21 # nixpkgs setup.sh uses this (issue #26)
22 declare -a array=(x y z)
23 argv.py "${array[@]}"
24 ## stdout: ['x', 'y', 'z']
25 ## N-I mksh stdout-json: ""
26 ## N-I mksh status: 1
27
28 #### declare -f exit code indicates function existence
29 func2=x # var names are NOT found
30 declare -f myfunc func2
31 echo $?
32
33 myfunc() { echo myfunc; }
34 declare -f myfunc func2 > /dev/null
35 echo $?
36
37 func2() { echo func2; }
38 declare -f myfunc func2 > /dev/null
39 echo $?
40 ## STDOUT:
41 1
42 1
43 0
44 ## END
45 ## N-I mksh STDOUT:
46 127
47 127
48 127
49 ## END
50
51 #### declare -F prints function names
52 add () { expr 4 + 4; }
53 div () { expr 6 / 2; }
54 ek () { echo hello; }
55 __ec () { echo hi; }
56 _ab () { expr 10 % 3; }
57
58 declare -F
59 ## STDOUT:
60 declare -f __ec
61 declare -f _ab
62 declare -f add
63 declare -f div
64 declare -f ek
65 ## END
66 ## N-I mksh stdout-json: ""
67 ## N-I mksh status: 127
68
69 #### declare -F with shopt -s extdebug prints more info
70 case $SH in mksh) exit ;; esac
71
72 source $REPO_ROOT/spec/testdata/bash-source-2.sh
73
74 shopt -s extdebug
75
76 add () { expr 4 + 4; }
77
78 declare -F
79 echo
80
81 declare -F add
82 # in bash-source-2
83 declare -F g | sed "s;$REPO_ROOT;ROOT;g"
84
85 ## STDOUT:
86 declare -f add
87 declare -f g
88
89 add 7 main
90 g 3 ROOT/spec/testdata/bash-source-2.sh
91 ## END
92 ## N-I mksh STDOUT:
93 ## END
94
95 #### declare -F with shopt -s extdebug and main file
96 case $SH in mksh) exit ;; esac
97
98 $SH $REPO_ROOT/spec/testdata/extdebug.sh | sed "s;$REPO_ROOT;ROOT;g"
99
100 ## STDOUT:
101 declare -f add
102 declare -f g
103
104 add 5 ROOT/spec/testdata/extdebug.sh
105 g 3 ROOT/spec/testdata/bash-source-2.sh
106 ## END
107 ## N-I mksh STDOUT:
108 ## END
109
110 #### declare -p var (exit status)
111 var1() { echo func; } # function names are NOT found.
112 declare -p var1 var2 >/dev/null
113 echo $?
114
115 var1=x
116 declare -p var1 var2 >/dev/null
117 echo $?
118
119 var2=y
120 declare -p var1 var2 >/dev/null
121 echo $?
122 ## STDOUT:
123 1
124 1
125 0
126 ## N-I mksh STDOUT:
127 127
128 127
129 127
130 ## END
131
132 #### declare
133 test_var1=111
134 readonly test_var2=222
135 export test_var3=333
136 declare -n test_var4=test_var1
137 f1() {
138 local test_var5=555
139 {
140 echo '[declare]'
141 declare
142 echo '[readonly]'
143 readonly
144 echo '[export]'
145 export
146 echo '[local]'
147 local
148 } | grep -E '^\[|^\b.*test_var.\b'
149 }
150 f1
151 ## STDOUT:
152 [declare]
153 test_var1=111
154 test_var2=222
155 test_var3=333
156 test_var4=test_var1
157 test_var5=555
158 [readonly]
159 declare -r test_var2=222
160 [export]
161 declare -x test_var3=333
162 [local]
163 test_var5=555
164 ## END
165 ## OK bash STDOUT:
166 [declare]
167 test_var1=111
168 test_var2=222
169 test_var3=333
170 test_var4=test_var1
171 test_var5=555
172 [readonly]
173 declare -r test_var2="222"
174 [export]
175 declare -x test_var3="333"
176 [local]
177 test_var5=555
178 ## END
179 ## N-I mksh STDOUT:
180 [declare]
181 [readonly]
182 test_var2
183 [export]
184 test_var3
185 [local]
186 typeset test_var1
187 typeset -r test_var2
188 typeset -x test_var3
189 typeset test_var5
190 ## END
191
192 #### declare -p
193 # BUG: bash doesn't output flags with "local -p", which seems to contradict
194 # with manual.
195 test_var1=111
196 readonly test_var2=222
197 export test_var3=333
198 declare -n test_var4=test_var1
199 f1() {
200 local test_var5=555
201 {
202 echo '[declare]'
203 declare -p
204 echo '[readonly]'
205 readonly -p
206 echo '[export]'
207 export -p
208 echo '[local]'
209 local -p
210 } | grep -E '^\[|^\b.*test_var.\b'
211 }
212 f1
213 ## STDOUT:
214 [declare]
215 declare -- test_var1=111
216 declare -r test_var2=222
217 declare -x test_var3=333
218 declare -n test_var4=test_var1
219 declare -- test_var5=555
220 [readonly]
221 declare -r test_var2=222
222 [export]
223 declare -x test_var3=333
224 [local]
225 declare -- test_var5=555
226 ## END
227 ## BUG bash STDOUT:
228 [declare]
229 declare -- test_var1="111"
230 declare -r test_var2="222"
231 declare -x test_var3="333"
232 declare -n test_var4="test_var1"
233 declare -- test_var5="555"
234 [readonly]
235 declare -r test_var2="222"
236 [export]
237 declare -x test_var3="333"
238 [local]
239 test_var5=555
240 ## END
241 ## N-I mksh STDOUT:
242 [declare]
243 [readonly]
244 readonly test_var2=222
245 [export]
246 export test_var3=333
247 [local]
248 typeset test_var1=111
249 typeset -r test_var2=222
250 typeset -x test_var3=333
251 typeset test_var5=555
252 ## END
253
254 #### declare -p doesn't print binary data, but can be loaded into bash
255
256 # bash prints binary data!
257 case $SH in bash*|mksh) exit ;; esac
258
259 unquoted='foo'
260 sq='foo bar'
261 bash1=$'\x1f' # ASCII control char
262 bash2=$'\xfe\xff' # Invalid UTF-8
263
264 s1=$unquoted
265 s2=$sq
266 s3=$bash1
267 s4=$bash2
268
269 declare -a a=("$unquoted" "$sq" "$bash1" "$bash2")
270 declare -A A=(["$unquoted"]="$sq" ["$bash1"]="$bash2")
271
272 #echo lengths ${#s1} ${#s2} ${#s3} ${#s4} ${#a[@]} ${#A[@]}
273
274 declare -p s1 s2 s3 s4 a A | tee tmp.bash
275
276 echo ---
277
278 bash -c 'source tmp.bash; echo "$s1 $s2"; echo -n "$s3" "$s4" | od -A n -t x1'
279 echo bash=$?
280
281 ## STDOUT:
282 declare -- s1=foo
283 declare -- s2='foo bar'
284 declare -- s3=$'\u001f'
285 declare -- s4=$'\xfe\xff'
286 declare -a a=(foo 'foo bar' $'\u001f' $'\xfe\xff')
287 declare -A A=([$'\u001f']=$'\xfe\xff' ['foo']='foo bar')
288 ---
289 foo foo bar
290 1f 20 fe ff
291 bash=0
292 ## END
293
294 ## N-I bash/mksh STDOUT:
295 ## END
296
297
298
299 #### declare -p var
300 # BUG? bash doesn't output anything for 'local/readonly -p var', which seems to
301 # contradict with manual. Besides, 'export -p var' is not described in
302 # manual
303 test_var1=111
304 readonly test_var2=222
305 export test_var3=333
306 declare -n test_var4=test_var1
307 f1() {
308 local test_var5=555
309 {
310 echo '[declare]'
311 declare -p test_var{0..5}
312 echo '[readonly]'
313 readonly -p test_var{0..5}
314 echo '[export]'
315 export -p test_var{0..5}
316 echo '[local]'
317 local -p test_var{0..5}
318 } | grep -E '^\[|^\b.*test_var.\b'
319 }
320 f1
321 ## STDOUT:
322 [declare]
323 declare -- test_var1=111
324 declare -r test_var2=222
325 declare -x test_var3=333
326 declare -n test_var4=test_var1
327 declare -- test_var5=555
328 [readonly]
329 declare -r test_var2=222
330 [export]
331 declare -x test_var3=333
332 [local]
333 declare -- test_var5=555
334 ## END
335 ## BUG bash STDOUT:
336 [declare]
337 declare -- test_var1="111"
338 declare -r test_var2="222"
339 declare -x test_var3="333"
340 declare -n test_var4="test_var1"
341 declare -- test_var5="555"
342 [readonly]
343 [export]
344 [local]
345 ## END
346 ## N-I mksh STDOUT:
347 [declare]
348 [readonly]
349 ## END
350
351 #### declare -p arr
352 test_arr1=()
353 declare -a test_arr2=()
354 declare -A test_arr3=()
355 test_arr4=(1 2 3)
356 declare -a test_arr5=(1 2 3)
357 declare -A test_arr6=(['a']=1 ['b']=2 ['c']=3)
358 test_arr7=()
359 test_arr7[3]=foo
360 declare -p test_arr{1..7}
361 ## STDOUT:
362 declare -a test_arr1=()
363 declare -a test_arr2=()
364 declare -A test_arr3=()
365 declare -a test_arr4=(1 2 3)
366 declare -a test_arr5=(1 2 3)
367 declare -A test_arr6=(['a']=1 ['b']=2 ['c']=3)
368 declare -a test_arr7=([3]=foo)
369 ## END
370 ## OK bash STDOUT:
371 declare -a test_arr1=()
372 declare -a test_arr2=()
373 declare -A test_arr3=()
374 declare -a test_arr4=([0]="1" [1]="2" [2]="3")
375 declare -a test_arr5=([0]="1" [1]="2" [2]="3")
376 declare -A test_arr6=([a]="1" [b]="2" [c]="3" )
377 declare -a test_arr7=([3]="foo")
378 ## END
379 ## N-I mksh stdout-json: ""
380 ## N-I mksh status: 1
381
382 #### declare -p foo=bar doesn't make sense
383 case $SH in (mksh) exit 0; esac
384
385 declare -p foo=bar
386 echo status=$?
387
388 a=b
389 declare -p a foo=bar > tmp.txt
390 echo status=$?
391 sed 's/"//g' tmp.txt # don't care about quotes
392 ## STDOUT:
393 status=1
394 status=1
395 declare -- a=b
396 ## END
397 ## N-I mksh stdout-json: ""
398
399 #### declare -pnrx
400 test_var1=111
401 readonly test_var2=222
402 export test_var3=333
403 declare -n test_var4=test_var1
404 f1() {
405 local test_var5=555
406 {
407 echo '[declare -pn]'
408 declare -pn
409 echo '[declare -pr]'
410 declare -pr
411 echo '[declare -px]'
412 declare -px
413 } | grep -E '^\[|^\b.*test_var.\b'
414 }
415 f1
416 ## STDOUT:
417 [declare -pn]
418 declare -n test_var4=test_var1
419 [declare -pr]
420 declare -r test_var2=222
421 [declare -px]
422 declare -x test_var3=333
423 ## END
424 ## OK bash STDOUT:
425 [declare -pn]
426 declare -n test_var4="test_var1"
427 [declare -pr]
428 declare -r test_var2="222"
429 [declare -px]
430 declare -x test_var3="333"
431 ## END
432 ## N-I mksh STDOUT:
433 [declare -pn]
434 [declare -pr]
435 [declare -px]
436 ## END
437
438 #### declare -paA
439 declare -a test_var6=()
440 declare -A test_var7=()
441 f1() {
442 {
443 echo '[declare -pa]'
444 declare -pa
445 echo '[declare -pA]'
446 declare -pA
447 } | grep -E '^\[|^\b.*test_var.\b'
448 }
449 f1
450 ## STDOUT:
451 [declare -pa]
452 declare -a test_var6=()
453 [declare -pA]
454 declare -A test_var7=()
455 ## END
456 ## OK bash STDOUT:
457 [declare -pa]
458 declare -a test_var6=()
459 [declare -pA]
460 declare -A test_var7=()
461 ## END
462 ## N-I mksh stdout-json: ""
463 ## N-I mksh status: 1
464
465 #### declare -pnrx var
466 # Note: Bash ignores other flags (-nrx) when variable names are supplied while
467 # OSH uses other flags to select variables. Bash's behavior is documented.
468 test_var1=111
469 readonly test_var2=222
470 export test_var3=333
471 declare -n test_var4=test_var1
472 f1() {
473 local test_var5=555
474 {
475 echo '[declare -pn]'
476 declare -pn test_var{0..5}
477 echo '[declare -pr]'
478 declare -pr test_var{0..5}
479 echo '[declare -px]'
480 declare -px test_var{0..5}
481 } | grep -E '^\[|^\b.*test_var.\b'
482 }
483 f1
484 ## STDOUT:
485 [declare -pn]
486 declare -n test_var4=test_var1
487 [declare -pr]
488 declare -r test_var2=222
489 [declare -px]
490 declare -x test_var3=333
491 ## END
492 ## N-I bash STDOUT:
493 [declare -pn]
494 declare -- test_var1="111"
495 declare -r test_var2="222"
496 declare -x test_var3="333"
497 declare -n test_var4="test_var1"
498 declare -- test_var5="555"
499 [declare -pr]
500 declare -- test_var1="111"
501 declare -r test_var2="222"
502 declare -x test_var3="333"
503 declare -n test_var4="test_var1"
504 declare -- test_var5="555"
505 [declare -px]
506 declare -- test_var1="111"
507 declare -r test_var2="222"
508 declare -x test_var3="333"
509 declare -n test_var4="test_var1"
510 declare -- test_var5="555"
511 ## END
512 ## N-I mksh STDOUT:
513 [declare -pn]
514 [declare -pr]
515 [declare -px]
516 ## END
517
518 #### declare -pg
519 test_var1=global
520 f1() {
521 local test_var1=local
522 {
523 declare -pg
524 } | grep -E '^\[|^\b[^"]*test_var.\b'
525 }
526 f1
527 ## STDOUT:
528 declare -- test_var1=global
529 ## END
530 ## N-I bash STDOUT:
531 declare -- test_var1="local"
532 ## END
533 ## N-I mksh stdout-json: ""
534 ## N-I mksh status: 1
535
536 #### declare -pg var
537 test_var1=global
538 f1() {
539 local test_var1=local
540 {
541 declare -pg test_var1
542 } | grep -E '^\[|^\b.*test_var.\b'
543 }
544 f1
545 ## STDOUT:
546 declare -- test_var1=global
547 ## END
548 ## N-I bash STDOUT:
549 declare -- test_var1="local"
550 ## END
551 ## N-I mksh stdout-json: ""
552 ## N-I mksh status: 1
553
554 #### ble.sh: eval -- "$(declare -p var arr)"
555 # This illustrates an example usage of "eval & declare" for exporting
556 # multiple variables from $().
557 eval -- "$(
558 printf '%s\n' a{1..10} | {
559 sum=0 i=0 arr=()
560 while read line; do
561 ((sum+=${#line},i++))
562 arr[$((i/3))]=$line
563 done
564 declare -p sum arr
565 })"
566 echo sum=$sum
567 for ((i=0;i<${#arr[@]};i++)); do
568 echo "arr[$i]=${arr[i]}"
569 done
570 ## STDOUT:
571 sum=21
572 arr[0]=a2
573 arr[1]=a5
574 arr[2]=a8
575 arr[3]=a10
576 ## END
577 ## N-I mksh stdout-json: ""
578 ## N-I mksh status: 1
579
580 #### declare -p and value.Undef
581
582 # This is a regression for a crash
583 # But actually there is also an incompatibility -- we don't print anything
584
585 declare x
586 declare -p x
587
588 function f { local x; declare -p x; }
589 x=1
590 f
591
592 ## STDOUT:
593 declare -- x
594 declare -- x
595 ## END
596
597 ## N-I mksh status: 127
598 ## N-I mksh STDOUT:
599 ## END
600
601 #### eval -- "$(declare -p arr)" (restore arrays w/ unset elements)
602 arr=(1 2 3)
603 eval -- "$(arr=(); arr[3]= arr[4]=foo; declare -p arr)"
604 for i in {0..4}; do
605 echo "arr[$i]: ${arr[$i]+set ... [}${arr[$i]-unset}${arr[$i]+]}"
606 done
607 ## STDOUT:
608 arr[0]: unset
609 arr[1]: unset
610 arr[2]: unset
611 arr[3]: set ... []
612 arr[4]: set ... [foo]
613 ## END
614 ## N-I mksh stdout-json: ""
615 ## N-I mksh status: 1
616
617 #### declare -p UNDEF (and typeset) -- prints something to stderr
618
619 x=42
620 readonly x
621 export x
622
623 declare -p x undef1 undef2 2> de
624
625 typeset -p x undef1 undef2 2> ty
626
627 # readonly -p and export -p don't accept args! They only print all
628 #
629 # These do not accept args
630 # readonly -p x undef1 undef2 2> re
631 # export -p x undef1 undef2 2> ex
632
633 f() {
634 # it behaves weird with x
635 #local -p undef1 undef2 2>lo
636 local -p a b b>lo
637 #local -p x undef1 undef2 2> lo
638 }
639 # local behaves differently in bash 4.4 and bash 5, not specifying now
640 # f
641 # files='de ty lo'
642
643 files='de ty'
644
645 wc -l $files
646 #cat $files
647
648 ## STDOUT:
649 declare -rx x="42"
650 declare -rx x="42"
651 2 de
652 2 ty
653 4 total
654 ## END
655
656 ## OK osh STDOUT:
657 declare -rx x=42
658 declare -rx x=42
659 2 de
660 2 ty
661 4 total
662 ## END
663
664 ## N-I mksh STDOUT:
665 typeset -x -r x=42
666 1 de
667 0 ty
668 1 total
669 ## END
670
671
672 #### typeset -f
673 # mksh implement typeset but not declare
674 typeset -f myfunc func2
675 echo $?
676
677 myfunc() { echo myfunc; }
678 # This prints the source code.
679 typeset -f myfunc func2 > /dev/null
680 echo $?
681
682 func2() { echo func2; }
683 typeset -f myfunc func2 > /dev/null
684 echo $?
685 ## STDOUT:
686 1
687 1
688 0
689 ## END
690
691 #### typeset -p
692 var1() { echo func; } # function names are NOT found.
693 typeset -p var1 var2 >/dev/null
694 echo $?
695
696 var1=x
697 typeset -p var1 var2 >/dev/null
698 echo $?
699
700 var2=y
701 typeset -p var1 var2 >/dev/null
702 echo $?
703 ## STDOUT:
704 1
705 1
706 0
707 ## BUG mksh STDOUT:
708 # mksh doesn't respect exit codes
709 0
710 0
711 0
712 ## END
713
714 #### typeset -r makes a string readonly
715 typeset -r s1='12'
716 typeset -r s2='34'
717
718 s1='c'
719 echo status=$?
720 s2='d'
721 echo status=$?
722
723 s1+='e'
724 echo status=$?
725 s2+='f'
726 echo status=$?
727
728 unset s1
729 echo status=$?
730 unset s2
731 echo status=$?
732
733 ## status: 1
734 ## stdout-json: ""
735 ## OK mksh status: 2
736 ## OK bash status: 0
737 ## OK bash STDOUT:
738 status=1
739 status=1
740 status=1
741 status=1
742 status=1
743 status=1
744 ## END
745
746 #### typeset -ar makes it readonly
747 typeset -a -r array1=(1 2)
748 typeset -ar array2=(3 4)
749
750 array1=('c')
751 echo status=$?
752 array2=('d')
753 echo status=$?
754
755 array1+=('e')
756 echo status=$?
757 array2+=('f')
758 echo status=$?
759
760 unset array1
761 echo status=$?
762 unset array2
763 echo status=$?
764
765 ## status: 1
766 ## stdout-json: ""
767 ## OK bash status: 0
768 ## OK bash STDOUT:
769 status=1
770 status=1
771 status=1
772 status=1
773 status=1
774 status=1
775 ## END
776 ## N-I mksh status: 1
777 ## N-I mksh stdout-json: ""
778
779 #### typeset -x makes it exported
780 typeset -rx PYTHONPATH=lib/
781 printenv.py PYTHONPATH
782 ## STDOUT:
783 lib/
784 ## END
785
786 #### Multiple assignments / array assignments on a line
787 a=1 b[0+0]=2 c=3
788 echo $a ${b[@]} $c
789 ## stdout: 1 2 3
790
791 #### Env bindings shouldn't contain array assignments
792 a=1 b[0]=2 c=3 printenv.py a b c
793 ## status: 2
794 ## stdout-json: ""
795 ## OK bash STDOUT:
796 1
797 None
798 3
799 ## END
800 ## OK bash status: 0
801 ## BUG mksh STDOUT:
802 1
803 2
804 3
805 ## END
806 ## BUG mksh status: 0
807
808 #### syntax error in array assignment
809 a=x b[0+]=y c=z
810 echo $a $b $c
811 ## status: 2
812 ## stdout-json: ""
813 ## BUG bash stdout: x
814 ## BUG bash status: 0
815 ## OK mksh stdout-json: ""
816 ## OK mksh status: 1
817
818 #### declare -g (bash-specific; bash-completion uses it)
819 f() {
820 declare -g G=42
821 declare L=99
822
823 declare -Ag dict
824 dict["foo"]=bar
825
826 declare -A localdict
827 localdict["spam"]=Eggs
828
829 # For bash-completion
830 eval 'declare -Ag ev'
831 ev["ev1"]=ev2
832 }
833 f
834 argv.py "$G" "$L"
835 argv.py "${dict["foo"]}" "${localdict["spam"]}"
836 argv.py "${ev["ev1"]}"
837 ## STDOUT:
838 ['42', '']
839 ['bar', '']
840 ['ev2']
841 ## END
842 ## N-I mksh STDOUT:
843 ['', '']
844 ## END
845 ## N-I mksh status: 1
846
847 #### myvar=typeset (another form of dynamic assignment)
848 myvar=typeset
849 x='a b'
850 $myvar x=$x
851 echo $x
852 ## STDOUT:
853 a
854 ## END
855 ## OK osh STDOUT:
856 a b
857 ## END
858
859 #### dynamic array parsing is not allowed
860 code='x=(1 2 3)'
861 typeset -a "$code" # note: -a flag is required
862 echo status=$?
863 argv.py "$x"
864 ## STDOUT:
865 status=2
866 ['']
867 ## END
868 ## OK mksh STDOUT:
869 status=0
870 ['(1 2 3)']
871 ## END
872 # bash allows it
873 ## OK bash STDOUT:
874 status=0
875 ['1']
876 ## END
877
878 #### dynamic flag in array in assign builtin
879 typeset b
880 b=(unused1 unused2) # this works in mksh
881
882 a=(x 'foo=F' 'bar=B')
883 typeset -"${a[@]}"
884 echo foo=$foo
885 echo bar=$bar
886 printenv.py foo
887 printenv.py bar
888
889 # syntax error in mksh! But works in bash and zsh.
890 #typeset -"${a[@]}" b=(spam eggs)
891 #echo "length of b = ${#b[@]}"
892 #echo "b[0]=${b[0]}"
893 #echo "b[1]=${b[1]}"
894
895 ## STDOUT:
896 foo=F
897 bar=B
898 F
899 B
900 ## END
901
902 #### typeset +x
903 export e=E
904 printenv.py e
905 typeset +x e=E2
906 printenv.py e # no longer exported
907 ## STDOUT:
908 E
909 None
910 ## END
911
912 #### typeset +r removes read-only attribute (TODO: documented in bash to do nothing)
913 readonly r=r1
914 echo r=$r
915
916 # clear the readonly flag. Why is this accepted in bash, but doesn't do
917 # anything?
918 typeset +r r=r2
919 echo r=$r
920
921 r=r3
922 echo r=$r
923
924 ## status: 0
925 ## STDOUT:
926 r=r1
927 r=r2
928 r=r3
929 ## END
930
931 # mksh doesn't allow you to unset
932 ## OK mksh status: 2
933 ## OK mksh STDOUT:
934 r=r1
935 ## END
936
937 # bash doesn't allow you to unset
938 ## OK bash status: 0
939 ## OK bash STDOUT:
940 r=r1
941 r=r1
942 r=r1
943 ## END
944
945
946 #### function name with /
947 ble/foo() { echo hi; }
948 declare -F ble/foo
949 echo status=$?
950 ## STDOUT:
951 ble/foo
952 status=0
953 ## END
954 ## N-I mksh stdout: status=127
955 ## N-I zsh stdout-json: ""
956 ## N-I zsh status: 1
957 ## N-I ash stdout-json: ""
958 ## N-I ash status: 2
959
960 #### invalid var name
961 typeset foo/bar
962 ## status: 1
963
964 #### unset and shell funcs
965 foo() {
966 echo bar
967 }
968
969 foo
970
971 declare -F
972 unset foo
973 declare -F
974
975 foo
976
977 ## status: 127
978 ## STDOUT:
979 bar
980 declare -f foo
981 ## END
982 ## N-I mksh status: 0
983 ## N-I mksh STDOUT:
984 bar
985 bar
986 ## END