aboutsummaryrefslogtreecommitdiff
path: root/tests/sh.test
blob: 4895ca7b5e1d944defcff906a6a42d84938c4965 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/bin/echo no

# Testing shell corner cases _within_ a shell script is kind of hard.

[ -f testing.sh ] && . testing.sh

# TODO make fake pty wrapper for test infrastructure

#testing "name" "command" "result" "infile" "stdin"

[ -z "$SH" ] && { [ -z "$TEST_HOST" ] && SH="sh" || export SH="bash" ; }
export EVAL="$SH -c"

testing "smoketest" "echo hello" "hello\n" "" ""

# ; | && ||
testing "semicolon" "echo one;echo two" "one\ntwo\n" "" ""
testing "simple pipe" "echo hello | cat" "hello\n" "" ""
testing "&&" "true && echo hello" "hello\n" "" ""
testing "&&2" "false && echo hello" "" "" ""
testing "||" "true || echo hello" "" "" ""
testing "||2" "false || echo hello" "hello\n" "" ""
testing "&& ||" "true && false && potato || echo hello" "hello\n" "" ""

# redirection

testing "" "cat < input" "hello\n" "hello\n" ""
testing "" "echo blah >out; cat out" "blah\n" "" ""
testing "" "touch /not/exist 2>out||grep -o /not/exist out" "/not/exist\n" "" ""
#testing "" 'echo hello | (read i <input; echo $i; read i; echo $i)' \
#  "there\nhello\n" "there\n" ""

testing "tilde expansion" "echo ~" "$HOME\n" "" ""
testing "tilde2" "echo ~/dir" "$HOME/dir\n" "" ""
testing "bracket expansion" \
  "echo {A{a,b}B{c,d}C}" "{AaBcC} {AaBdC} {AbBcC} {AbBdC}\n" "" ""
testing "brackets2" "echo {A{a,b}B{c,d}C,D}" "AaBcC AaBdC AbBcC AbBdC D\n" "" ""
testing "brackets3" 'echo {A"b,c"D}' "{Ab,cD}\n" "" ""
testing "brackets4" 'echo {A"bc",D}' "Abc D\n" "" ""
testing "brackets5" 'echo {A,B,C' "{A,B,C\n" "" ""
testing "brackets6" 'echo {{{{A,B},C}D},E}' "{AD} {BD} {CD} E\n" "" ""
testing "brackets7" 'echo {{{a,b},c,{d,e}},f}' "a b c d e f\n" "" ""
testing "brackets8" 'echo A{a{b,c{B,C}D}d{e,f},g{h,i}j}E' \
  "AabdeE AabdfE AacBDdeE AacBDdfE AacCDdeE AacCDdfE AghjE AgijE\n" "" ""
testing "brackets9" 'echo A{B{C,D}E{N,O},F{G,H}I}J{K,L}M' \
  "ABCENJKM ABCENJLM ABCEOJKM ABCEOJLM ABDENJKM ABDENJLM ABDEOJKM ABDEOJLM AFGIJKM AFGIJLM AFHIJKM AFHIJLM\n" "" ""
for i in /root /var/root /; do [ -e $i ] && EXPECT=$i && break; done
testing "bracket+tilde" "echo {~,~root}/pwd" "$HOME/pwd $EXPECT/pwd\n" "" ""

testing "leading variable assignment" 'abc=def env | grep ^abc=; echo $abc' \
  "abc=def\n\n" "" ""
testing "leading variable assignments" \
  "abc=def ghi=jkl env | egrep '^(abc|ghi)=' | sort; echo \$abc \$ghi" \
  "abc=def\nghi=jkl\n\n" "" ""
#testing "leading assignments don't affect current line" \
#  'VAR=12345 echo ${VAR}a' "a\n" "" ""
#testing "can't have space before first : but yes around arguments" \
#  'BLAH=abcdefghi; echo ${BLAH: 1 : 3 }' "bcd\n" "" ""

testing "curly brackets and pipe" \
  '{ echo one; echo two ; } | tee blah.txt; wc blah.txt' \
  "one\ntwo\n2 2 8 blah.txt\n" "" ""

# texpect "name" "command" E/O/I"string"

# Prompt changes for root/normal user
[ $(id -u) -eq 0 ] && P='# ' || P='$ '
# run sufficiently isolated shell child process to get predictable results
SH="env -i PATH=${PATH@Q} PS1='\\$ ' $SH --noediting --noprofile --norc -is"

txpect "prompt and exit" "$SH" "E$P" "Iexit\n" X0
txpect "prompt and echo" "$SH" "E$P" "Iecho hello\n" "Ohello"$'\n' "E$P" X0
txpect "redirect err" "$SH" "E$P" "Iecho > /dev/full\n" "E" "E$P" X0
txpect "wait for <(exit)" "$SH" "E$P" "Icat <(echo hello 1>&2)\n" $'Ehello\n' \
  "E$P" X0



# $@ $* $# $? $- $$ $! $0
# always exported: PWD SHLVL _
#  ./bash -c 'echo $_' prints $BASH, but PATH search shows path? Hmmm...
# ro: UID PPID EUID $
# IFS LINENO
# PATH HOME SHELL USER LOGNAME SHLVL HOSTNAME HOSTTYPE MACHTYPE OSTYPE OLDPWD
# PS0 PS1='$ ' PS2='> ' PS3 PS4 BASH BASH_VERSION
# ENV - if [ -n "$ENV" ]; then . "$ENV"; fi # BASH_ENV - synonym for ENV
# FUNCNEST - maximum function nesting level (abort when above)
# REPLY - set by input with no args
# OPTARG OPTIND - set by getopts builtin
# OPTERR

# maybe not: EXECIGNORE, FIGNORE, GLOBIGNORE

#BASHPID - synonym for $$ HERE
#BASH_SUBSHELL - SHLVL synonym
#BASH_EXECUTION_STRING - -c argument
#
#automatically set:
#OPTARG - set by getopts builtin
#OPTIND - set by getopts builtin
#
#PROMPT_COMMAND PROMPT_DIRTRIM PS0 PS1 PS2 PS3 PS4
#
#unsettable (assignments ignored before then)
#LINENO SECONDS RANDOM
#GROUPS - id -g
#HISTCMD - history number
#
#TMOUT - used by read