aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--shell/ash_test/ash-heredoc/heredoc_huge.right3
-rwxr-xr-xshell/ash_test/ash-heredoc/heredoc_huge.tests9
-rw-r--r--shell/ash_test/ash-misc/and-or.right18
-rwxr-xr-xshell/ash_test/ash-misc/and-or.tests34
-rw-r--r--shell/ash_test/ash-misc/assignment1.right9
-rwxr-xr-xshell/ash_test/ash-misc/assignment1.tests42
-rw-r--r--shell/ash_test/ash-misc/assignment3.right2
-rwxr-xr-xshell/ash_test/ash-misc/assignment3.tests5
-rw-r--r--shell/ash_test/ash-misc/assignment4.right1
-rwxr-xr-xshell/ash_test/ash-misc/assignment4.tests3
-rw-r--r--shell/ash_test/ash-misc/break1.right2
-rwxr-xr-xshell/ash_test/ash-misc/break1.tests2
-rw-r--r--shell/ash_test/ash-misc/break2.right3
-rwxr-xr-xshell/ash_test/ash-misc/break2.tests6
-rw-r--r--shell/ash_test/ash-misc/break3.right2
-rwxr-xr-xshell/ash_test/ash-misc/break3.tests2
-rw-r--r--shell/ash_test/ash-misc/break4.right6
-rwxr-xr-xshell/ash_test/ash-misc/break4.tests12
-rw-r--r--shell/ash_test/ash-misc/break5.right13
-rwxr-xr-xshell/ash_test/ash-misc/break5.tests4
-rw-r--r--shell/ash_test/ash-misc/builtin1.right2
-rwxr-xr-xshell/ash_test/ash-misc/builtin1.tests6
-rw-r--r--shell/ash_test/ash-misc/case1.right22
-rwxr-xr-xshell/ash_test/ash-misc/case1.tests40
-rw-r--r--shell/ash_test/ash-misc/colon.right2
-rwxr-xr-xshell/ash_test/ash-misc/colon.tests5
-rw-r--r--shell/ash_test/ash-misc/compound.right14
-rwxr-xr-xshell/ash_test/ash-misc/compound.tests21
-rw-r--r--shell/ash_test/ash-misc/continue1.right8
-rwxr-xr-xshell/ash_test/ash-misc/continue1.tests4
-rw-r--r--shell/ash_test/ash-misc/continue2.right1
-rwxr-xr-xshell/ash_test/ash-misc/continue2.tests3
-rw-r--r--shell/ash_test/ash-misc/continue3.right2
-rwxr-xr-xshell/ash_test/ash-misc/continue3.tests3
-rw-r--r--shell/ash_test/ash-misc/empty_for.right1
-rwxr-xr-xshell/ash_test/ash-misc/empty_for.tests3
-rw-r--r--shell/ash_test/ash-misc/empty_for2.right4
-rwxr-xr-xshell/ash_test/ash-misc/empty_for2.tests6
-rw-r--r--shell/ash_test/ash-misc/exit1.right1
-rwxr-xr-xshell/ash_test/ash-misc/exit1.tests4
-rw-r--r--shell/ash_test/ash-misc/for_with_bslashes.right8
-rwxr-xr-xshell/ash_test/ash-misc/for_with_bslashes.tests10
-rw-r--r--shell/ash_test/ash-misc/for_with_keywords.right4
-rwxr-xr-xshell/ash_test/ash-misc/for_with_keywords.tests2
-rw-r--r--shell/ash_test/ash-misc/if_false_exitcode.right1
-rwxr-xr-xshell/ash_test/ash-misc/if_false_exitcode.tests2
-rw-r--r--shell/ash_test/ash-misc/nommu1.right7
-rwxr-xr-xshell/ash_test/ash-misc/nommu1.tests12
-rw-r--r--shell/ash_test/ash-misc/nommu2.right5
-rwxr-xr-xshell/ash_test/ash-misc/nommu2.tests5
-rw-r--r--shell/ash_test/ash-misc/nommu3.right2
-rwxr-xr-xshell/ash_test/ash-misc/nommu3.tests15
-rw-r--r--shell/ash_test/ash-misc/opts1.right2
-rwxr-xr-xshell/ash_test/ash-misc/opts1.tests5
-rw-r--r--shell/ash_test/ash-misc/pid.right1
-rwxr-xr-xshell/ash_test/ash-misc/pid.tests1
-rw-r--r--shell/ash_test/ash-misc/pipefail.right40
-rwxr-xr-xshell/ash_test/ash-misc/pipefail.tests45
-rw-r--r--shell/ash_test/ash-misc/read.right4
-rwxr-xr-xshell/ash_test/ash-misc/read.tests4
-rw-r--r--shell/ash_test/ash-misc/return1.right1
-rwxr-xr-xshell/ash_test/ash-misc/return1.tests4
-rw-r--r--shell/ash_test/ash-misc/shift.right6
-rwxr-xr-xshell/ash_test/ash-misc/shift.tests14
-rw-r--r--shell/ash_test/ash-misc/sigint1.right1
-rwxr-xr-xshell/ash_test/ash-misc/sigint1.tests41
-rw-r--r--shell/ash_test/ash-misc/unicode1.right3
-rwxr-xr-xshell/ash_test/ash-misc/unicode1.tests13
-rw-r--r--shell/ash_test/ash-misc/until1.right3
-rwxr-xr-xshell/ash_test/ash-misc/until1.tests11
-rw-r--r--shell/ash_test/ash-misc/while1.right1
-rwxr-xr-xshell/ash_test/ash-misc/while1.tests2
-rw-r--r--shell/ash_test/ash-misc/while2.right2
-rwxr-xr-xshell/ash_test/ash-misc/while2.tests2
-rw-r--r--shell/ash_test/ash-misc/while4.right1
-rwxr-xr-xshell/ash_test/ash-misc/while4.tests6
-rw-r--r--shell/ash_test/ash-misc/while_in_subshell.right1
-rwxr-xr-xshell/ash_test/ash-misc/while_in_subshell.tests2
-rw-r--r--shell/ash_test/ash-signals/save-ret.right2
-rwxr-xr-xshell/ash_test/ash-signals/save-ret.tests4
-rw-r--r--shell/ash_test/ash-vars/empty.right3
-rwxr-xr-xshell/ash_test/ash-vars/empty.tests5
-rw-r--r--shell/ash_test/ash-vars/glob_and_vars.right1
-rwxr-xr-xshell/ash_test/ash-vars/glob_and_vars.tests2
-rw-r--r--shell/ash_test/ash-vars/param_expand_len.right9
-rwxr-xr-xshell/ash_test/ash-vars/param_expand_len.tests17
-rw-r--r--shell/ash_test/ash-vars/param_glob.right4
-rwxr-xr-xshell/ash_test/ash-vars/param_glob.tests9
-rw-r--r--shell/ash_test/ash-vars/param_subshell.right7
-rwxr-xr-xshell/ash_test/ash-vars/param_subshell.tests15
-rw-r--r--shell/ash_test/ash-vars/star.right6
-rwxr-xr-xshell/ash_test/ash-vars/star.tests8
-rw-r--r--shell/ash_test/ash-vars/var_expand_in_assign.right5
-rwxr-xr-xshell/ash_test/ash-vars/var_expand_in_assign.tests15
-rw-r--r--shell/ash_test/ash-vars/var_expand_in_redir.right3
-rwxr-xr-xshell/ash_test/ash-vars/var_expand_in_redir.tests13
-rw-r--r--shell/ash_test/ash-vars/var_expand_on_ifs.right9
-rwxr-xr-xshell/ash_test/ash-vars/var_expand_on_ifs.tests11
-rw-r--r--shell/ash_test/ash-vars/var_in_pipes.right6
-rwxr-xr-xshell/ash_test/ash-vars/var_in_pipes.tests7
-rw-r--r--shell/ash_test/ash-vars/var_leaks.right1
-rwxr-xr-xshell/ash_test/ash-vars/var_leaks.tests14
-rw-r--r--shell/hush_test/hush-misc/assignment2.right (renamed from shell/hush_test/hush-misc/assignment2.rigth)0
103 files changed, 795 insertions, 0 deletions
diff --git a/shell/ash_test/ash-heredoc/heredoc_huge.right b/shell/ash_test/ash-heredoc/heredoc_huge.right
new file mode 100644
index 000000000..11740f674
--- /dev/null
+++ b/shell/ash_test/ash-heredoc/heredoc_huge.right
@@ -0,0 +1,3 @@
+546ed3f5c81c780d3ab86ada14824237 -
+546ed3f5c81c780d3ab86ada14824237 -
+End
diff --git a/shell/ash_test/ash-heredoc/heredoc_huge.tests b/shell/ash_test/ash-heredoc/heredoc_huge.tests
new file mode 100755
index 000000000..c2ec2817b
--- /dev/null
+++ b/shell/ash_test/ash-heredoc/heredoc_huge.tests
@@ -0,0 +1,9 @@
+# This creates 120k heredoc
+echo 'cat <<HERE | md5sum' >"$0.tmp"
+yes "123456789 123456789 123456789 123456789" | head -3000 >>"$0.tmp"
+echo 'HERE' >>"$0.tmp"
+
+yes "123456789 123456789 123456789 123456789" | head -3000 | md5sum
+. "$0.tmp"
+rm "$0.tmp"
+echo End
diff --git a/shell/ash_test/ash-misc/and-or.right b/shell/ash_test/ash-misc/and-or.right
new file mode 100644
index 000000000..f9fa5fbf8
--- /dev/null
+++ b/shell/ash_test/ash-misc/and-or.right
@@ -0,0 +1,18 @@
+a1
+a4
+b1
+b3
+b4
+b6
+c4
+c5
+c7
+c8
+ff1
+ff3
+ft2
+ft3
+tf2
+tf3
+tt2
+tt4
diff --git a/shell/ash_test/ash-misc/and-or.tests b/shell/ash_test/ash-misc/and-or.tests
new file mode 100755
index 000000000..485458abe
--- /dev/null
+++ b/shell/ash_test/ash-misc/and-or.tests
@@ -0,0 +1,34 @@
+false || echo a1
+false && echo a2
+true || echo a3
+true && echo a4
+
+false || echo b1 || echo b2
+false || echo b3 && echo b4
+false && echo b5 || echo b6
+false && echo b7 && echo b8
+
+true || echo c1 || echo c2
+true || echo c3 && echo c4
+true && echo c5 || echo c6
+true && echo c7 && echo c8
+
+false || false || echo ff1
+false || false && echo ff2
+false && false || echo ff3
+false && false && echo ff4
+
+false || true || echo ft1
+false || true && echo ft2
+false && true || echo ft3
+false && true && echo ft4
+
+true || false || echo tf1
+true || false && echo tf2
+true && false || echo tf3
+true && false && echo tf4
+
+true || true || echo tt1
+true || true && echo tt2
+true && true || echo tt3
+true && true && echo tt4
diff --git a/shell/ash_test/ash-misc/assignment1.right b/shell/ash_test/ash-misc/assignment1.right
new file mode 100644
index 000000000..d0a13d3d8
--- /dev/null
+++ b/shell/ash_test/ash-misc/assignment1.right
@@ -0,0 +1,9 @@
+if1:0
+while1:0
+until1:0
+if2:0
+while2:0
+until2:0
+if3:0
+while3:0
+until3:0
diff --git a/shell/ash_test/ash-misc/assignment1.tests b/shell/ash_test/ash-misc/assignment1.tests
new file mode 100755
index 000000000..033b35250
--- /dev/null
+++ b/shell/ash_test/ash-misc/assignment1.tests
@@ -0,0 +1,42 @@
+# Assignments after some keywords should still work
+
+if a=1 true; then a=1 true; elif a=1 true; then a=1 true; else a=1 true; fi
+echo if1:$?
+while a=1 true; do a=1 true; break; done
+echo while1:$?
+until a=1 false; do a=1 true; break; done
+echo until1:$?
+
+if a=1 true
+ then a=1 true
+ elif a=1 true
+ then a=1 true
+ else a=1 true
+ fi
+echo if2:$?
+while a=1 true
+ do a=1 true
+ break
+ done
+echo while2:$?
+until a=1 false
+ do a=1 true
+ break
+ done
+echo until2:$?
+
+if
+ a=1 true; then
+ a=1 true; elif
+ a=1 true; then
+ a=1 true; else
+ a=1 true; fi
+echo if3:$?
+while
+ a=1 true; do
+ a=1 true; break; done
+echo while3:$?
+until
+ a=1 false; do
+ a=1 true; break; done
+echo until3:$?
diff --git a/shell/ash_test/ash-misc/assignment3.right b/shell/ash_test/ash-misc/assignment3.right
new file mode 100644
index 000000000..0f02d7cbc
--- /dev/null
+++ b/shell/ash_test/ash-misc/assignment3.right
@@ -0,0 +1,2 @@
+Done:0
+abc=123
diff --git a/shell/ash_test/ash-misc/assignment3.tests b/shell/ash_test/ash-misc/assignment3.tests
new file mode 100755
index 000000000..790129be1
--- /dev/null
+++ b/shell/ash_test/ash-misc/assignment3.tests
@@ -0,0 +1,5 @@
+# This must be interpreted as assignments
+a=1 b\
+=2 c=3
+echo Done:$?
+echo abc=$a$b$c
diff --git a/shell/ash_test/ash-misc/assignment4.right b/shell/ash_test/ash-misc/assignment4.right
new file mode 100644
index 000000000..31c896f62
--- /dev/null
+++ b/shell/ash_test/ash-misc/assignment4.right
@@ -0,0 +1 @@
+Done:0
diff --git a/shell/ash_test/ash-misc/assignment4.tests b/shell/ash_test/ash-misc/assignment4.tests
new file mode 100755
index 000000000..6f46d0a33
--- /dev/null
+++ b/shell/ash_test/ash-misc/assignment4.tests
@@ -0,0 +1,3 @@
+# There was a bug where we misinterpreted assignments after 'do':
+for i in 1; do eval b=; done
+echo Done:$?
diff --git a/shell/ash_test/ash-misc/break1.right b/shell/ash_test/ash-misc/break1.right
new file mode 100644
index 000000000..04a4b1757
--- /dev/null
+++ b/shell/ash_test/ash-misc/break1.right
@@ -0,0 +1,2 @@
+A
+OK:0
diff --git a/shell/ash_test/ash-misc/break1.tests b/shell/ash_test/ash-misc/break1.tests
new file mode 100755
index 000000000..3a6b060d9
--- /dev/null
+++ b/shell/ash_test/ash-misc/break1.tests
@@ -0,0 +1,2 @@
+while true; do echo A; break; echo B; done
+echo OK:$?
diff --git a/shell/ash_test/ash-misc/break2.right b/shell/ash_test/ash-misc/break2.right
new file mode 100644
index 000000000..8a15cb95f
--- /dev/null
+++ b/shell/ash_test/ash-misc/break2.right
@@ -0,0 +1,3 @@
+A
+AA
+OK:0
diff --git a/shell/ash_test/ash-misc/break2.tests b/shell/ash_test/ash-misc/break2.tests
new file mode 100755
index 000000000..7da9faf34
--- /dev/null
+++ b/shell/ash_test/ash-misc/break2.tests
@@ -0,0 +1,6 @@
+while true; do
+ echo A
+ while true; do echo AA; break 2; echo BB; done
+ echo B
+done
+echo OK:$?
diff --git a/shell/ash_test/ash-misc/break3.right b/shell/ash_test/ash-misc/break3.right
new file mode 100644
index 000000000..04a4b1757
--- /dev/null
+++ b/shell/ash_test/ash-misc/break3.right
@@ -0,0 +1,2 @@
+A
+OK:0
diff --git a/shell/ash_test/ash-misc/break3.tests b/shell/ash_test/ash-misc/break3.tests
new file mode 100755
index 000000000..d138dcac5
--- /dev/null
+++ b/shell/ash_test/ash-misc/break3.tests
@@ -0,0 +1,2 @@
+v=break; while true; do echo A; $v; echo B; break; echo C; done
+echo OK:$?
diff --git a/shell/ash_test/ash-misc/break4.right b/shell/ash_test/ash-misc/break4.right
new file mode 100644
index 000000000..6f41c141d
--- /dev/null
+++ b/shell/ash_test/ash-misc/break4.right
@@ -0,0 +1,6 @@
+A
+AA
+TRUE
+A
+AA
+OK:0
diff --git a/shell/ash_test/ash-misc/break4.tests b/shell/ash_test/ash-misc/break4.tests
new file mode 100755
index 000000000..67da2889c
--- /dev/null
+++ b/shell/ash_test/ash-misc/break4.tests
@@ -0,0 +1,12 @@
+cond=true
+while $cond; do
+ echo A
+ if test "$cond" = true; then
+ cond='echo TRUE'
+ else
+ cond=false
+ fi
+ while true; do echo AA; continue 2; echo BB; done
+ echo B
+done
+echo OK:$?
diff --git a/shell/ash_test/ash-misc/break5.right b/shell/ash_test/ash-misc/break5.right
new file mode 100644
index 000000000..0b9df2a4f
--- /dev/null
+++ b/shell/ash_test/ash-misc/break5.right
@@ -0,0 +1,13 @@
+A
+B
+0
+A:a
+B
+D
+A:b
+B
+D
+A:c
+B
+D
+0
diff --git a/shell/ash_test/ash-misc/break5.tests b/shell/ash_test/ash-misc/break5.tests
new file mode 100755
index 000000000..273e040ec
--- /dev/null
+++ b/shell/ash_test/ash-misc/break5.tests
@@ -0,0 +1,4 @@
+while true; do echo A; { echo B; break; echo C; }; echo D; done
+echo $?
+for v in a b c; do echo A:$v; (echo B; break; echo C); echo D; done
+echo $?
diff --git a/shell/ash_test/ash-misc/builtin1.right b/shell/ash_test/ash-misc/builtin1.right
new file mode 100644
index 000000000..2e55ecb09
--- /dev/null
+++ b/shell/ash_test/ash-misc/builtin1.right
@@ -0,0 +1,2 @@
+VARIABLE=export
+OK:0
diff --git a/shell/ash_test/ash-misc/builtin1.tests b/shell/ash_test/ash-misc/builtin1.tests
new file mode 100755
index 000000000..1a2941faa
--- /dev/null
+++ b/shell/ash_test/ash-misc/builtin1.tests
@@ -0,0 +1,6 @@
+# builtins, unlike keywords like "while", can be constructed
+# with substitutions
+VARIABLE=export
+$VARIABLE VARIABLE
+env | grep ^VARIABLE
+echo OK:$?
diff --git a/shell/ash_test/ash-misc/case1.right b/shell/ash_test/ash-misc/case1.right
new file mode 100644
index 000000000..4afb2f51c
--- /dev/null
+++ b/shell/ash_test/ash-misc/case1.right
@@ -0,0 +1,22 @@
+OK_1
+OK_1
+OK_21
+OK_22
+OK_23
+OK_31
+OK_32
+OK_41
+OK_42
+OK_43
+OK_44
+OK_51
+OK_52
+OK_53
+OK_sub1
+OK_sub2
+OK_sub3
+OK_sub4
+OK_sub5
+OK_sub6
+OK_esac1
+Done
diff --git a/shell/ash_test/ash-misc/case1.tests b/shell/ash_test/ash-misc/case1.tests
new file mode 100755
index 000000000..d72b57f53
--- /dev/null
+++ b/shell/ash_test/ash-misc/case1.tests
@@ -0,0 +1,40 @@
+case w in a) echo SKIP;; w) echo OK_1;; w) echo WRONG;; esac
+
+case w in
+ a) echo SKIP;;
+ w)echo OK_1 ;;
+ w)
+ echo WRONG
+ ;;
+esac
+
+t=w
+case $t in a) echo SKIP;; w) echo OK_21;; w) echo WRONG;; esac;
+case "$t" in a) echo SKIP;; w) echo OK_22;; w) echo WRONG;; esac;
+case w in a) echo SKIP;; $t) echo OK_23;; "$t") echo WRONG;; esac;
+
+case '' in a) echo SKIP;; w) echo WRONG;; *) echo OK_31;; esac;
+case '' in a) echo SKIP;; '') echo OK_32;; *) echo WRONG;; esac;
+
+case `echo w` in a) echo SKIP;; w) echo OK_41;; w) echo WRONG;; esac;
+case "`echo w`" in a) echo SKIP;; w) echo OK_42;; w) echo WRONG;; esac;
+case `echo w w` in a) echo SKIP;; w) echo WRONG;; 'w w') echo OK_43;; esac;
+case `echo w w` in a) echo SKIP;; w) echo WRONG;; w*) echo OK_44;; esac;
+
+case w in `echo w`) echo OK_51;; `echo WRONG >&2`w) echo WRONG;; esac;
+case w in `echo OK_52 >&2`) echo SKIP;; `echo`w) echo OK_53;; esac;
+
+# parsing cases in subshells can easily get messy
+ case m in m) echo OK_sub1;; esac
+ case m in (m) echo OK_sub2;; esac
+(case m in m) echo OK_sub3;; esac)
+(case m in (m) echo OK_sub4;; esac)
+(
+ case m in m) echo OK_sub5;; esac
+)
+(
+ case m in (m) echo OK_sub6;; esac
+)
+(case esac in "esac") echo OK_esac1;; esac)
+
+echo Done
diff --git a/shell/ash_test/ash-misc/colon.right b/shell/ash_test/ash-misc/colon.right
new file mode 100644
index 000000000..2a87d0293
--- /dev/null
+++ b/shell/ash_test/ash-misc/colon.right
@@ -0,0 +1,2 @@
+0
+OK: 0
diff --git a/shell/ash_test/ash-misc/colon.tests b/shell/ash_test/ash-misc/colon.tests
new file mode 100755
index 000000000..cb8ab5306
--- /dev/null
+++ b/shell/ash_test/ash-misc/colon.tests
@@ -0,0 +1,5 @@
+false
+:
+echo $?
+(while :; do exit; done)
+echo OK: $?
diff --git a/shell/ash_test/ash-misc/compound.right b/shell/ash_test/ash-misc/compound.right
new file mode 100644
index 000000000..757d42fe4
--- /dev/null
+++ b/shell/ash_test/ash-misc/compound.right
@@ -0,0 +1,14 @@
+new group
+0
+1
+2
+3
+4
+5
+6
+new group
+new group
+0
+1
+2
+3
diff --git a/shell/ash_test/ash-misc/compound.tests b/shell/ash_test/ash-misc/compound.tests
new file mode 100755
index 000000000..a5e85c3d5
--- /dev/null
+++ b/shell/ash_test/ash-misc/compound.tests
@@ -0,0 +1,21 @@
+echo new group
+echo 0; { :; }
+echo 1; { : ;}
+echo 2; ({ :; })
+echo 3; ({ : ;})
+echo 4; ( : )
+echo 5; ( :; )
+echo 6; ( : ;)
+# not sure if POSIX requires these, but bash accepts them ...
+#echo 7; {( : )}
+#echo 8; {( :; )}
+#echo 9; {( : ;)}
+
+echo new group
+#echo 0; {(:);}
+
+echo new group
+echo 0; (:)
+echo 1; (:;)
+echo 2; (:);
+echo 3; (:;);
diff --git a/shell/ash_test/ash-misc/continue1.right b/shell/ash_test/ash-misc/continue1.right
new file mode 100644
index 000000000..c4a5565bc
--- /dev/null
+++ b/shell/ash_test/ash-misc/continue1.right
@@ -0,0 +1,8 @@
+A:a
+A:b
+A:c
+OK1
+A:a
+A:b
+A:c
+OK2
diff --git a/shell/ash_test/ash-misc/continue1.tests b/shell/ash_test/ash-misc/continue1.tests
new file mode 100755
index 000000000..72d356660
--- /dev/null
+++ b/shell/ash_test/ash-misc/continue1.tests
@@ -0,0 +1,4 @@
+for v in a b c; do echo A:$v; continue 666; done
+echo OK1
+for v in a b c; do echo A:$v; continue 666; done
+echo OK2
diff --git a/shell/ash_test/ash-misc/continue2.right b/shell/ash_test/ash-misc/continue2.right
new file mode 100644
index 000000000..49d3ebd3a
--- /dev/null
+++ b/shell/ash_test/ash-misc/continue2.right
@@ -0,0 +1 @@
+Ok:1
diff --git a/shell/ash_test/ash-misc/continue2.tests b/shell/ash_test/ash-misc/continue2.tests
new file mode 100755
index 000000000..c2df07195
--- /dev/null
+++ b/shell/ash_test/ash-misc/continue2.tests
@@ -0,0 +1,3 @@
+e=''
+(while test $e && exit 1; true; do e=1; continue; done)
+echo Ok:$?
diff --git a/shell/ash_test/ash-misc/continue3.right b/shell/ash_test/ash-misc/continue3.right
new file mode 100644
index 000000000..aa47d0d46
--- /dev/null
+++ b/shell/ash_test/ash-misc/continue3.right
@@ -0,0 +1,2 @@
+0
+0
diff --git a/shell/ash_test/ash-misc/continue3.tests b/shell/ash_test/ash-misc/continue3.tests
new file mode 100755
index 000000000..0aff867cd
--- /dev/null
+++ b/shell/ash_test/ash-misc/continue3.tests
@@ -0,0 +1,3 @@
+# Test that "continue" does affect exitcode (sets to 0)
+e=''
+while echo $?; test $e && exit; true; do e=1; false; continue; done
diff --git a/shell/ash_test/ash-misc/empty_for.right b/shell/ash_test/ash-misc/empty_for.right
new file mode 100644
index 000000000..290d39b7e
--- /dev/null
+++ b/shell/ash_test/ash-misc/empty_for.right
@@ -0,0 +1 @@
+OK: 0
diff --git a/shell/ash_test/ash-misc/empty_for.tests b/shell/ash_test/ash-misc/empty_for.tests
new file mode 100755
index 000000000..0cb52e849
--- /dev/null
+++ b/shell/ash_test/ash-misc/empty_for.tests
@@ -0,0 +1,3 @@
+false
+for a in; do echo "HELLO"; done
+echo OK: $?
diff --git a/shell/ash_test/ash-misc/empty_for2.right b/shell/ash_test/ash-misc/empty_for2.right
new file mode 100644
index 000000000..1acee9eb8
--- /dev/null
+++ b/shell/ash_test/ash-misc/empty_for2.right
@@ -0,0 +1,4 @@
+PARAM:abc
+PARAM:d e
+PARAM:123
+OK: 0
diff --git a/shell/ash_test/ash-misc/empty_for2.tests b/shell/ash_test/ash-misc/empty_for2.tests
new file mode 100755
index 000000000..2b12ec2c1
--- /dev/null
+++ b/shell/ash_test/ash-misc/empty_for2.tests
@@ -0,0 +1,6 @@
+if test $# = 0; then
+ exec "$THIS_SH" $0 abc "d e" 123
+fi
+false
+for v; do echo "PARAM:$v"; done
+echo OK: $?
diff --git a/shell/ash_test/ash-misc/exit1.right b/shell/ash_test/ash-misc/exit1.right
new file mode 100644
index 000000000..dd2cfc279
--- /dev/null
+++ b/shell/ash_test/ash-misc/exit1.right
@@ -0,0 +1 @@
+Once
diff --git a/shell/ash_test/ash-misc/exit1.tests b/shell/ash_test/ash-misc/exit1.tests
new file mode 100755
index 000000000..41e0d092d
--- /dev/null
+++ b/shell/ash_test/ash-misc/exit1.tests
@@ -0,0 +1,4 @@
+trap "echo Not shown" EXIT
+(exit) # must be silent
+trap "echo Once; exit" EXIT
+{ exit; }
diff --git a/shell/ash_test/ash-misc/for_with_bslashes.right b/shell/ash_test/ash-misc/for_with_bslashes.right
new file mode 100644
index 000000000..02d96692c
--- /dev/null
+++ b/shell/ash_test/ash-misc/for_with_bslashes.right
@@ -0,0 +1,8 @@
+a
+b\c
+b\\c
+b"c
+b'c
+b$c
+b`true`c
+Zero:0
diff --git a/shell/ash_test/ash-misc/for_with_bslashes.tests b/shell/ash_test/ash-misc/for_with_bslashes.tests
new file mode 100755
index 000000000..363f3d85b
--- /dev/null
+++ b/shell/ash_test/ash-misc/for_with_bslashes.tests
@@ -0,0 +1,10 @@
+# UNFIXED BUG.
+# commented-out words contain ^C character.
+# It's a SPECIAL_VAR_SYMBOL, for now hush does not escape it.
+# When it is fixed, update this test.
+
+for a in 'a' 'b\c' 'b\\c' 'b"c' "b'c" 'b$c' 'b`true`c' ### 'b#c'
+do
+ echo $a
+done
+echo Zero:$?
diff --git a/shell/ash_test/ash-misc/for_with_keywords.right b/shell/ash_test/ash-misc/for_with_keywords.right
new file mode 100644
index 000000000..eb04e9af9
--- /dev/null
+++ b/shell/ash_test/ash-misc/for_with_keywords.right
@@ -0,0 +1,4 @@
+do
+done
+then
+OK: 0
diff --git a/shell/ash_test/ash-misc/for_with_keywords.tests b/shell/ash_test/ash-misc/for_with_keywords.tests
new file mode 100755
index 000000000..a8b8e4264
--- /dev/null
+++ b/shell/ash_test/ash-misc/for_with_keywords.tests
@@ -0,0 +1,2 @@
+for if in do done then; do echo $if; done
+echo OK: $?
diff --git a/shell/ash_test/ash-misc/if_false_exitcode.right b/shell/ash_test/ash-misc/if_false_exitcode.right
new file mode 100644
index 000000000..7b24a35ff
--- /dev/null
+++ b/shell/ash_test/ash-misc/if_false_exitcode.right
@@ -0,0 +1 @@
+Ok:0
diff --git a/shell/ash_test/ash-misc/if_false_exitcode.tests b/shell/ash_test/ash-misc/if_false_exitcode.tests
new file mode 100755
index 000000000..01b36b100
--- /dev/null
+++ b/shell/ash_test/ash-misc/if_false_exitcode.tests
@@ -0,0 +1,2 @@
+if false; then echo Bad; fi
+echo Ok:$?
diff --git a/shell/ash_test/ash-misc/nommu1.right b/shell/ash_test/ash-misc/nommu1.right
new file mode 100644
index 000000000..d206a854b
--- /dev/null
+++ b/shell/ash_test/ash-misc/nommu1.right
@@ -0,0 +1,7 @@
+Ok
+Ok
+Ok
+Ok
+Ok
+Ok
+Done
diff --git a/shell/ash_test/ash-misc/nommu1.tests b/shell/ash_test/ash-misc/nommu1.tests
new file mode 100755
index 000000000..e14ada5f9
--- /dev/null
+++ b/shell/ash_test/ash-misc/nommu1.tests
@@ -0,0 +1,12 @@
+(echo \
+Ok)
+( (echo \
+Ok) )
+( ( (echo \
+Ok) ) )
+
+(echo \Ok)
+( (echo \Ok) )
+( ( (echo \Ok) ) )
+
+echo Done
diff --git a/shell/ash_test/ash-misc/nommu2.right b/shell/ash_test/ash-misc/nommu2.right
new file mode 100644
index 000000000..fb8ba8b5c
--- /dev/null
+++ b/shell/ash_test/ash-misc/nommu2.right
@@ -0,0 +1,5 @@
+Ok
+Ok
+Ok
+Ok
+Done
diff --git a/shell/ash_test/ash-misc/nommu2.tests b/shell/ash_test/ash-misc/nommu2.tests
new file mode 100755
index 000000000..61ed5ce5b
--- /dev/null
+++ b/shell/ash_test/ash-misc/nommu2.tests
@@ -0,0 +1,5 @@
+echo Not shown | if true; then echo $(echo Ok); fi
+echo Not shown | if true; then echo `echo Ok`; fi
+echo Not shown | ( if true; then echo $(echo Ok); fi )
+echo Not shown | ( if true; then echo `echo Ok`; fi )
+echo Done
diff --git a/shell/ash_test/ash-misc/nommu3.right b/shell/ash_test/ash-misc/nommu3.right
new file mode 100644
index 000000000..da1534bef
--- /dev/null
+++ b/shell/ash_test/ash-misc/nommu3.right
@@ -0,0 +1,2 @@
+Ok
+0
diff --git a/shell/ash_test/ash-misc/nommu3.tests b/shell/ash_test/ash-misc/nommu3.tests
new file mode 100755
index 000000000..ac82a6a11
--- /dev/null
+++ b/shell/ash_test/ash-misc/nommu3.tests
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+func()
+{
+ while read p; do echo "$p"; done
+}
+
+pipe_to_func()
+{
+ # We had a NOMMU bug which caused "echo Ok |" part to be lost
+ echo Ok | func
+}
+
+pipe_to_func | cat
+echo $?
diff --git a/shell/ash_test/ash-misc/opts1.right b/shell/ash_test/ash-misc/opts1.right
new file mode 100644
index 000000000..4da75737d
--- /dev/null
+++ b/shell/ash_test/ash-misc/opts1.right
@@ -0,0 +1,2 @@
+Param1: >-10qwertyuiop<
+Done
diff --git a/shell/ash_test/ash-misc/opts1.tests b/shell/ash_test/ash-misc/opts1.tests
new file mode 100755
index 000000000..45a23d66b
--- /dev/null
+++ b/shell/ash_test/ash-misc/opts1.tests
@@ -0,0 +1,5 @@
+if test $# = 0; then
+ exec "$THIS_SH" $0 -10qwertyuiop
+fi
+echo "Param1: >$1<"
+echo Done
diff --git a/shell/ash_test/ash-misc/pid.right b/shell/ash_test/ash-misc/pid.right
new file mode 100644
index 000000000..573541ac9
--- /dev/null
+++ b/shell/ash_test/ash-misc/pid.right
@@ -0,0 +1 @@
+0
diff --git a/shell/ash_test/ash-misc/pid.tests b/shell/ash_test/ash-misc/pid.tests
new file mode 100755
index 000000000..eaeaa717b
--- /dev/null
+++ b/shell/ash_test/ash-misc/pid.tests
@@ -0,0 +1 @@
+test `(echo $$)` = `echo $$`; echo $?
diff --git a/shell/ash_test/ash-misc/pipefail.right b/shell/ash_test/ash-misc/pipefail.right
new file mode 100644
index 000000000..5845d8939
--- /dev/null
+++ b/shell/ash_test/ash-misc/pipefail.right
@@ -0,0 +1,40 @@
+Default:
+true | true:
+0
+1
+true | false:
+1
+0
+false | true:
+0
+1
+exit 2 | exit 3 | exit 4:
+4
+0
+Pipefail on:
+true | true:
+0
+1
+true | false:
+1
+0
+false | true:
+1
+0
+exit 2 | exit 3 | exit 4:
+4
+0
+Pipefail off:
+true | true:
+0
+1
+true | false:
+1
+0
+false | true:
+0
+1
+exit 2 | exit 3 | exit 4:
+4
+0
+Done
diff --git a/shell/ash_test/ash-misc/pipefail.tests b/shell/ash_test/ash-misc/pipefail.tests
new file mode 100755
index 000000000..9df841861
--- /dev/null
+++ b/shell/ash_test/ash-misc/pipefail.tests
@@ -0,0 +1,45 @@
+echo Default:
+echo "true | true:"
+ true | true; echo $?
+! true | true; echo $?
+echo "true | false:"
+ true | false; echo $?
+! true | false; echo $?
+echo "false | true:"
+ false | true; echo $?
+! false | true; echo $?
+echo "exit 2 | exit 3 | exit 4:"
+ exit 2 | exit 3 | exit 4; echo $?
+! exit 2 | exit 3 | exit 4; echo $?
+
+echo Pipefail on:
+set -o pipefail
+echo "true | true:"
+ true | true; echo $?
+! true | true; echo $?
+echo "true | false:"
+ true | false; echo $?
+! true | false; echo $?
+echo "false | true:"
+ false | true; echo $?
+! false | true; echo $?
+echo "exit 2 | exit 3 | exit 4:"
+ exit 2 | exit 3 | exit 4; echo $?
+! exit 2 | exit 3 | exit 4; echo $?
+
+echo Pipefail off:
+set +o pipefail
+echo "true | true:"
+ true | true; echo $?
+! true | true; echo $?
+echo "true | false:"
+ true | false; echo $?
+! true | false; echo $?
+echo "false | true:"
+ false | true; echo $?
+! false | true; echo $?
+echo "exit 2 | exit 3 | exit 4:"
+ exit 2 | exit 3 | exit 4; echo $?
+! exit 2 | exit 3 | exit 4; echo $?
+
+echo Done
diff --git a/shell/ash_test/ash-misc/read.right b/shell/ash_test/ash-misc/read.right
new file mode 100644
index 000000000..0e50e2a23
--- /dev/null
+++ b/shell/ash_test/ash-misc/read.right
@@ -0,0 +1,4 @@
+read
+cat
+echo "REPLY=$REPLY"
+REPLY=exec <read.tests
diff --git a/shell/ash_test/ash-misc/read.tests b/shell/ash_test/ash-misc/read.tests
new file mode 100755
index 000000000..ff1acbde1
--- /dev/null
+++ b/shell/ash_test/ash-misc/read.tests
@@ -0,0 +1,4 @@
+exec <read.tests
+read
+cat
+echo "REPLY=$REPLY"
diff --git a/shell/ash_test/ash-misc/return1.right b/shell/ash_test/ash-misc/return1.right
new file mode 100644
index 000000000..7b24a35ff
--- /dev/null
+++ b/shell/ash_test/ash-misc/return1.right
@@ -0,0 +1 @@
+Ok:0
diff --git a/shell/ash_test/ash-misc/return1.tests b/shell/ash_test/ash-misc/return1.tests
new file mode 100755
index 000000000..eeb92ef3f
--- /dev/null
+++ b/shell/ash_test/ash-misc/return1.tests
@@ -0,0 +1,4 @@
+echo "true && return; echo Should not be printed" >return_sourced
+. ./return_sourced
+rm return_sourced
+echo Ok:$?
diff --git a/shell/ash_test/ash-misc/shift.right b/shell/ash_test/ash-misc/shift.right
new file mode 100644
index 000000000..d281e358c
--- /dev/null
+++ b/shell/ash_test/ash-misc/shift.right
@@ -0,0 +1,6 @@
+./shift.tests abc d e
+./shift.tests d e 123
+./shift.tests d e 123
+./shift.tests
+./shift.tests
+./shift.tests
diff --git a/shell/ash_test/ash-misc/shift.tests b/shell/ash_test/ash-misc/shift.tests
new file mode 100755
index 000000000..53ef249f2
--- /dev/null
+++ b/shell/ash_test/ash-misc/shift.tests
@@ -0,0 +1,14 @@
+if test $# = 0; then
+ exec "$THIS_SH" $0 abc "d e" 123
+fi
+echo $0 $1 $2
+shift
+echo $0 $1 $2
+shift 999
+echo $0 $1 $2
+shift 2
+echo $0 $1 $2
+shift 2
+echo $0 $1 $2
+shift
+echo $0 $1 $2
diff --git a/shell/ash_test/ash-misc/sigint1.right b/shell/ash_test/ash-misc/sigint1.right
new file mode 100644
index 000000000..a9094b056
--- /dev/null
+++ b/shell/ash_test/ash-misc/sigint1.right
@@ -0,0 +1 @@
+Sending SIGINT to main shell PID
diff --git a/shell/ash_test/ash-misc/sigint1.tests b/shell/ash_test/ash-misc/sigint1.tests
new file mode 100755
index 000000000..3d483d32a
--- /dev/null
+++ b/shell/ash_test/ash-misc/sigint1.tests
@@ -0,0 +1,41 @@
+# What should happen if non-interactive shell gets SIGINT?
+
+(sleep 1; echo Sending SIGINT to main shell PID; exec kill -INT $$) &
+
+# We create a child which exits with 0 even on SIGINT
+# (The complex command is necessary only if SIGINT is generated by ^C,
+# in this testcase even bare "sleep 2" would do because
+# in the testcase we don't send SIGINT *to the child*...)
+$THIS_SH -c 'trap "exit 0" SIGINT; sleep 2'
+
+# In one second, we (main shell) get SIGINT here.
+# The question is whether we should, or should not, exit.
+
+# bash will not stop here. It will execute next command(s).
+
+# The rationale for this is described here:
+# http://www.cons.org/cracauer/sigint.html
+#
+# Basically, bash will not exit on SIGINT immediately if it waits
+# for a child. It will wait for the child to exit.
+# If child exits NOT by dying on SIGINT, then bash will not exit.
+#
+# The idea is that the following script:
+# | emacs file.txt
+# | more cmds
+# User may use ^C to interrupt editor's ops like search. But then
+# emacs exits normally. User expects that script doesn't stop.
+#
+# This is a nice idea, but detecting "did process really exit
+# with SIGINT?" is racy. Consider:
+# | bash -c 'while true; do /bin/true; done'
+# When ^C is pressed while bash waits for /bin/true to exit,
+# it may happen that /bin/true exits with exitcode 0 before
+# ^C is delivered to it as SIGINT. bash will see SIGINT, then
+# it will see that child exited with 0, and bash will NOT EXIT.
+
+# Therefore we do not implement bash behavior.
+# I'd say that emacs need to put itself into a separate pgrp
+# to isolate shell from getting stray SIGINTs from ^C.
+
+echo Next command after SIGINT was executed
diff --git a/shell/ash_test/ash-misc/unicode1.right b/shell/ash_test/ash-misc/unicode1.right
new file mode 100644
index 000000000..d3bbbf697
--- /dev/null
+++ b/shell/ash_test/ash-misc/unicode1.right
@@ -0,0 +1,3 @@
+1
+1
+Ok
diff --git a/shell/ash_test/ash-misc/unicode1.tests b/shell/ash_test/ash-misc/unicode1.tests
new file mode 100755
index 000000000..8788ba910
--- /dev/null
+++ b/shell/ash_test/ash-misc/unicode1.tests
@@ -0,0 +1,13 @@
+LANG=en_US.UTF-8
+
+# A combining character U+300
+a=`printf "\xcc\x80"`
+# Should print 1
+echo ${#a}
+
+# A Japanese katakana charachter U+30a3
+a=`printf "\xe3\x82\xa3"`
+# Should print 1
+echo ${#a}
+
+echo Ok
diff --git a/shell/ash_test/ash-misc/until1.right b/shell/ash_test/ash-misc/until1.right
new file mode 100644
index 000000000..be2daad95
--- /dev/null
+++ b/shell/ash_test/ash-misc/until1.right
@@ -0,0 +1,3 @@
+1
+1
+Ok:0
diff --git a/shell/ash_test/ash-misc/until1.tests b/shell/ash_test/ash-misc/until1.tests
new file mode 100755
index 000000000..10ab28381
--- /dev/null
+++ b/shell/ash_test/ash-misc/until1.tests
@@ -0,0 +1,11 @@
+x=1
+until test "$x" = 4; do echo $x; x=4; done
+
+# We had a bug in multi-line form
+x=1
+until test "$x" = 4; do
+ echo $x
+ x=4
+done
+
+echo Ok:$?
diff --git a/shell/ash_test/ash-misc/while1.right b/shell/ash_test/ash-misc/while1.right
new file mode 100644
index 000000000..7c4d7beb0
--- /dev/null
+++ b/shell/ash_test/ash-misc/while1.right
@@ -0,0 +1 @@
+OK:0
diff --git a/shell/ash_test/ash-misc/while1.tests b/shell/ash_test/ash-misc/while1.tests
new file mode 100755
index 000000000..11e201e6a
--- /dev/null
+++ b/shell/ash_test/ash-misc/while1.tests
@@ -0,0 +1,2 @@
+while false; do echo NOT SHOWN; done
+echo OK:$?
diff --git a/shell/ash_test/ash-misc/while2.right b/shell/ash_test/ash-misc/while2.right
new file mode 100644
index 000000000..07207cc84
--- /dev/null
+++ b/shell/ash_test/ash-misc/while2.right
@@ -0,0 +1,2 @@
+Hello
+OK:0
diff --git a/shell/ash_test/ash-misc/while2.tests b/shell/ash_test/ash-misc/while2.tests
new file mode 100755
index 000000000..2247adc74
--- /dev/null
+++ b/shell/ash_test/ash-misc/while2.tests
@@ -0,0 +1,2 @@
+while echo Hello; false; do echo NOT SHOWN; done
+echo OK:$?
diff --git a/shell/ash_test/ash-misc/while4.right b/shell/ash_test/ash-misc/while4.right
new file mode 100644
index 000000000..7b24a35ff
--- /dev/null
+++ b/shell/ash_test/ash-misc/while4.right
@@ -0,0 +1 @@
+Ok:0
diff --git a/shell/ash_test/ash-misc/while4.tests b/shell/ash_test/ash-misc/while4.tests
new file mode 100755
index 000000000..ba80e603a
--- /dev/null
+++ b/shell/ash_test/ash-misc/while4.tests
@@ -0,0 +1,6 @@
+false
+while false && echo Not reached; do
+ echo BUG
+ break
+done
+echo Ok:$?
diff --git a/shell/ash_test/ash-misc/while_in_subshell.right b/shell/ash_test/ash-misc/while_in_subshell.right
new file mode 100644
index 000000000..290d39b7e
--- /dev/null
+++ b/shell/ash_test/ash-misc/while_in_subshell.right
@@ -0,0 +1 @@
+OK: 0
diff --git a/shell/ash_test/ash-misc/while_in_subshell.tests b/shell/ash_test/ash-misc/while_in_subshell.tests
new file mode 100755
index 000000000..def8e092b
--- /dev/null
+++ b/shell/ash_test/ash-misc/while_in_subshell.tests
@@ -0,0 +1,2 @@
+(while true; do exit; done)
+echo OK: $?
diff --git a/shell/ash_test/ash-signals/save-ret.right b/shell/ash_test/ash-signals/save-ret.right
new file mode 100644
index 000000000..a3e12ce5e
--- /dev/null
+++ b/shell/ash_test/ash-signals/save-ret.right
@@ -0,0 +1,2 @@
+YEAH
+0
diff --git a/shell/ash_test/ash-signals/save-ret.tests b/shell/ash_test/ash-signals/save-ret.tests
new file mode 100755
index 000000000..0786b6d96
--- /dev/null
+++ b/shell/ash_test/ash-signals/save-ret.tests
@@ -0,0 +1,4 @@
+# make sure we do not corrupt $? across traps
+trap "echo YEAH; false" USR1
+kill -USR1 $$
+echo $?
diff --git a/shell/ash_test/ash-vars/empty.right b/shell/ash_test/ash-vars/empty.right
new file mode 100644
index 000000000..2cb3c70f2
--- /dev/null
+++ b/shell/ash_test/ash-vars/empty.right
@@ -0,0 +1,3 @@
+a b c d e f 1 2 3 4 5 6 7 8 9 0 A B C D E F
+a b c d e f 1 2 3 4 5 6 7 8 9 0 A B C D E F
+a b c d e f 1 2 3 4 5 6 7 8 9 0 A B C D E F
diff --git a/shell/ash_test/ash-vars/empty.tests b/shell/ash_test/ash-vars/empty.tests
new file mode 100755
index 000000000..a9c247e31
--- /dev/null
+++ b/shell/ash_test/ash-vars/empty.tests
@@ -0,0 +1,5 @@
+e=
+
+echo a b c d e f 1 2 3 4 5 6 7 8 9 0 A B C D E F
+echo a $e b $e c $e d $e e $e f $e 1 $e 2 $e 3 $e 4 $e 5 $e 6 $e 7 $e 8 $e 9 $e 0 $e A $e B $e C $e D $e E $e F
+echo $e a $e b $e c $e d $e e $e f $e 1 $e 2 $e 3 $e 4 $e 5 $e 6 $e 7 $e 8 $e 9 $e 0 $e A $e B $e C $e D $e E $e F
diff --git a/shell/ash_test/ash-vars/glob_and_vars.right b/shell/ash_test/ash-vars/glob_and_vars.right
new file mode 100644
index 000000000..3ac7ec5ff
--- /dev/null
+++ b/shell/ash_test/ash-vars/glob_and_vars.right
@@ -0,0 +1 @@
+./glob_and_vars.right ./glob_and_vars.tests
diff --git a/shell/ash_test/ash-vars/glob_and_vars.tests b/shell/ash_test/ash-vars/glob_and_vars.tests
new file mode 100755
index 000000000..482cf9d8a
--- /dev/null
+++ b/shell/ash_test/ash-vars/glob_and_vars.tests
@@ -0,0 +1,2 @@
+v=.
+echo $v/glob_and_vars.[tr]*
diff --git a/shell/ash_test/ash-vars/param_expand_len.right b/shell/ash_test/ash-vars/param_expand_len.right
new file mode 100644
index 000000000..96e8cb59b
--- /dev/null
+++ b/shell/ash_test/ash-vars/param_expand_len.right
@@ -0,0 +1,9 @@
+0
+0
+1
+Make sure len parsing doesnt break arg count
+0 0
+4 4
+Testing len op
+4 3 2 1 0 0
+0 3 0
diff --git a/shell/ash_test/ash-vars/param_expand_len.tests b/shell/ash_test/ash-vars/param_expand_len.tests
new file mode 100755
index 000000000..fe20a45e9
--- /dev/null
+++ b/shell/ash_test/ash-vars/param_expand_len.tests
@@ -0,0 +1,17 @@
+"$THIS_SH" -c 'echo $#'
+"$THIS_SH" -c 'echo $#' arg0
+"$THIS_SH" -c 'echo $#' arg0 arg1
+
+echo Make sure len parsing doesnt break arg count
+set --
+echo $# ${#}
+set -- aaaa bbb cc d
+echo $# ${#}
+
+echo Testing len op
+echo ${#1} ${#2} ${#3} ${#4} ${#5} ${#6}
+
+unset e
+f=abc
+g=
+echo ${#e} ${#f} ${#g}
diff --git a/shell/ash_test/ash-vars/param_glob.right b/shell/ash_test/ash-vars/param_glob.right
new file mode 100644
index 000000000..bdee8fe0f
--- /dev/null
+++ b/shell/ash_test/ash-vars/param_glob.right
@@ -0,0 +1,4 @@
+param_glob.tests
+param_glob.tests
+param_glob.t*
+param_glob.t*
diff --git a/shell/ash_test/ash-vars/param_glob.tests b/shell/ash_test/ash-vars/param_glob.tests
new file mode 100755
index 000000000..4d74fee02
--- /dev/null
+++ b/shell/ash_test/ash-vars/param_glob.tests
@@ -0,0 +1,9 @@
+if test $# = 0; then
+ exec "$THIS_SH" "$0" 'param_glob.t*'
+ echo NOT SHOWN
+ exit
+fi
+echo $*
+echo $@
+echo "$*"
+echo "$@"
diff --git a/shell/ash_test/ash-vars/param_subshell.right b/shell/ash_test/ash-vars/param_subshell.right
new file mode 100644
index 000000000..f3c3767de
--- /dev/null
+++ b/shell/ash_test/ash-vars/param_subshell.right
@@ -0,0 +1,7 @@
+1=1
+2=2
+3=3
+4=4
+5=5
+6=6
+7=7
diff --git a/shell/ash_test/ash-vars/param_subshell.tests b/shell/ash_test/ash-vars/param_subshell.tests
new file mode 100755
index 000000000..27fdc5b9b
--- /dev/null
+++ b/shell/ash_test/ash-vars/param_subshell.tests
@@ -0,0 +1,15 @@
+if test $# = 0; then
+ "$THIS_SH" "$0" 1 2 3 4 5 6 7 8 9
+ exit
+fi
+echo 1=$1
+{ echo 2=$2; }
+{ echo 3=$3; } &
+# cant use usleep as it isnt standard in $PATH --
+# we fail when testing busybox compiled solely as "hush"
+wait
+( echo 4=$4 )
+( echo 5=$5 ) &
+wait
+true | echo 6=$6 | cat
+true | { echo 7=$7; } | cat
diff --git a/shell/ash_test/ash-vars/star.right b/shell/ash_test/ash-vars/star.right
new file mode 100644
index 000000000..0ecc55bc2
--- /dev/null
+++ b/shell/ash_test/ash-vars/star.right
@@ -0,0 +1,6 @@
+.1.
+.abc.
+.d.
+.e.
+.f.
+.1 abc d e f.
diff --git a/shell/ash_test/ash-vars/star.tests b/shell/ash_test/ash-vars/star.tests
new file mode 100755
index 000000000..5554c4090
--- /dev/null
+++ b/shell/ash_test/ash-vars/star.tests
@@ -0,0 +1,8 @@
+if test $# = 0; then
+ exec "$THIS_SH" star.tests 1 abc 'd e f'
+fi
+# 'd e f' should be split into 3 separate args:
+for a in $*; do echo ".$a."; done
+
+# must produce .1 abc d e f.
+for a in "$*"; do echo ".$a."; done
diff --git a/shell/ash_test/ash-vars/var_expand_in_assign.right b/shell/ash_test/ash-vars/var_expand_in_assign.right
new file mode 100644
index 000000000..352210d7e
--- /dev/null
+++ b/shell/ash_test/ash-vars/var_expand_in_assign.right
@@ -0,0 +1,5 @@
+. .
+.abc d e.
+.abc d e.
+.abc d e.
+.abc d e.
diff --git a/shell/ash_test/ash-vars/var_expand_in_assign.tests b/shell/ash_test/ash-vars/var_expand_in_assign.tests
new file mode 100755
index 000000000..18cdc74c0
--- /dev/null
+++ b/shell/ash_test/ash-vars/var_expand_in_assign.tests
@@ -0,0 +1,15 @@
+if test $# = 0; then
+ exec "$THIS_SH" "$0" abc "d e"
+fi
+
+space=' '
+echo .$space.
+
+a=$*
+echo .$a.
+a=$@
+echo .$a.
+a="$*"
+echo .$a.
+a="$@"
+echo .$a.
diff --git a/shell/ash_test/ash-vars/var_expand_in_redir.right b/shell/ash_test/ash-vars/var_expand_in_redir.right
new file mode 100644
index 000000000..423299c97
--- /dev/null
+++ b/shell/ash_test/ash-vars/var_expand_in_redir.right
@@ -0,0 +1,3 @@
+TEST1
+TEST2
+TEST3
diff --git a/shell/ash_test/ash-vars/var_expand_in_redir.tests b/shell/ash_test/ash-vars/var_expand_in_redir.tests
new file mode 100755
index 000000000..bda6bdd7f
--- /dev/null
+++ b/shell/ash_test/ash-vars/var_expand_in_redir.tests
@@ -0,0 +1,13 @@
+if test $# = 0; then
+ exec "$THIS_SH" "$0" abc "d e"
+fi
+
+echo TEST1 >"$1.out"
+echo TEST2 >"$2.out"
+# bash says: "$@.out": ambiguous redirect
+# ash handles it as if it is '$*' - we do the same
+echo TEST3 >"$@.out"
+
+cat abc.out "d e.out" "abc d e.out"
+
+rm abc.out "d e.out" "abc d e.out"
diff --git a/shell/ash_test/ash-vars/var_expand_on_ifs.right b/shell/ash_test/ash-vars/var_expand_on_ifs.right
new file mode 100644
index 000000000..2ed2069f7
--- /dev/null
+++ b/shell/ash_test/ash-vars/var_expand_on_ifs.right
@@ -0,0 +1,9 @@
+1 a b c
+2 a + b c
+3 a b c
+4 a b c
+5 a b c
+6 a b + c
+7 a b c
+8 a b c
+9 a b c
diff --git a/shell/ash_test/ash-vars/var_expand_on_ifs.tests b/shell/ash_test/ash-vars/var_expand_on_ifs.tests
new file mode 100755
index 000000000..a12ff8ec8
--- /dev/null
+++ b/shell/ash_test/ash-vars/var_expand_on_ifs.tests
@@ -0,0 +1,11 @@
+b=' b '
+e=''
+echo 1 a $b c
+echo 2 a +$b c
+echo 3 a $e$b c
+echo 4 a "$e"$b c
+echo 5 a ""$b c
+echo 6 a $b+ c
+echo 7 a $b$e c
+echo 8 a $b"$e" c
+echo 9 a $b"" c
diff --git a/shell/ash_test/ash-vars/var_in_pipes.right b/shell/ash_test/ash-vars/var_in_pipes.right
new file mode 100644
index 000000000..faf65bed4
--- /dev/null
+++ b/shell/ash_test/ash-vars/var_in_pipes.right
@@ -0,0 +1,6 @@
+b=1
+b=2
+b=3
+b=4
+b=5
+b=6
diff --git a/shell/ash_test/ash-vars/var_in_pipes.tests b/shell/ash_test/ash-vars/var_in_pipes.tests
new file mode 100755
index 000000000..3f8cd2729
--- /dev/null
+++ b/shell/ash_test/ash-vars/var_in_pipes.tests
@@ -0,0 +1,7 @@
+b=1 env | grep ^b=
+true | b=2 env | grep ^b=
+a=1 true | b=3 env | grep ^b=
+
+(b=4 env) | grep ^b=
+(true | b=5 env) | grep ^b=
+(a=1 true | b=6 env) | grep ^b=
diff --git a/shell/ash_test/ash-vars/var_leaks.right b/shell/ash_test/ash-vars/var_leaks.right
new file mode 100644
index 000000000..d86bac9de
--- /dev/null
+++ b/shell/ash_test/ash-vars/var_leaks.right
@@ -0,0 +1 @@
+OK
diff --git a/shell/ash_test/ash-vars/var_leaks.tests b/shell/ash_test/ash-vars/var_leaks.tests
new file mode 100755
index 000000000..27c8c6504
--- /dev/null
+++ b/shell/ash_test/ash-vars/var_leaks.tests
@@ -0,0 +1,14 @@
+# external program
+a=b /bin/true
+env | grep ^a=
+
+# builtin
+a=b true
+env | grep ^a=
+
+# exec with redirection only
+# in bash, this leaks!
+a=b exec 1>&1
+env | grep ^a=
+
+echo OK
diff --git a/shell/hush_test/hush-misc/assignment2.rigth b/shell/hush_test/hush-misc/assignment2.right
index 591552cde..591552cde 100644
--- a/shell/hush_test/hush-misc/assignment2.rigth
+++ b/shell/hush_test/hush-misc/assignment2.right