1 #!/usr/bin/env bash
2 #
3 # Tests for pipelines.
4 # NOTE: Grammatically, ! is part of the pipeline:
5 #
6 # pipeline : pipe_sequence
7 # | Bang pipe_sequence
8
9 #### Brace group in pipeline
10 { echo one; echo two; } | tac
11 ## stdout-json: "two\none\n"
12
13 #### For loop starts pipeline
14 for w in one two; do
15 echo $w
16 done | tac
17 ## stdout-json: "two\none\n"
18
19 #### While Loop ends pipeline
20 seq 3 | while read i
21 do
22 echo ".$i"
23 done
24 ## stdout-json: ".1\n.2\n.3\n"
25
26 #### Redirect in Pipeline
27 echo hi 1>&2 | wc -l
28 ## stdout: 0
29 ## BUG zsh stdout: 1
30
31 #### Pipeline comments
32 echo abcd | # input
33 # blank line
34 tr a-z A-Z # transform
35 ## stdout: ABCD
36
37 #### Exit code is last status
38 echo a | egrep '[0-9]+'
39 ## status: 1
40
41 #### PIPESTATUS
42 return3() {
43 return 3
44 }
45 { sleep 0.03; exit 1; } | { sleep 0.02; exit 2; } | { sleep 0.01; return3; }
46 echo ${PIPESTATUS[@]}
47 ## stdout: 1 2 3
48 ## N-I dash status: 2
49 ## N-I dash stdout-json: ""
50 ## N-I zsh status: 0
51 ## N-I zsh stdout-json: "\n"
52
53 #### PIPESTATUS with shopt -s lastpipe
54 shopt -s lastpipe
55 return3() {
56 return 3
57 }
58 { sleep 0.03; exit 1; } | { sleep 0.02; exit 2; } | { sleep 0.01; return3; }
59 echo ${PIPESTATUS[@]}
60 ## stdout: 1 2 3
61 ## N-I dash status: 2
62 ## N-I dash stdout-json: ""
63 ## N-I zsh status: 0
64 ## N-I zsh stdout-json: "\n"
65
66 #### |&
67 stdout_stderr.py |& cat
68 ## STDOUT:
69 STDERR
70 STDOUT
71 ## END
72 ## status: 0
73 ## N-I dash/mksh stdout-json: ""
74 ## N-I dash status: 2
75 ## N-I osh stdout-json: ""
76 ## N-I osh status: 1
77
78 #### ! turns non-zero into zero
79 ! $SH -c 'exit 42'; echo $?
80 ## stdout: 0
81 ## status: 0
82
83 #### ! turns zero into 1
84 ! $SH -c 'exit 0'; echo $?
85 ## stdout: 1
86 ## status: 0
87
88 #### ! in if
89 if ! echo hi; then
90 echo TRUE
91 else
92 echo FALSE
93 fi
94 ## stdout-json: "hi\nFALSE\n"
95 ## status: 0
96
97 #### ! with ||
98 ! echo hi || echo FAILED
99 ## stdout-json: "hi\nFAILED\n"
100 ## status: 0
101
102 #### ! with { }
103 ! { echo 1; echo 2; } || echo FAILED
104 ## stdout-json: "1\n2\nFAILED\n"
105 ## status: 0
106
107 #### ! with ( )
108 ! ( echo 1; echo 2 ) || echo FAILED
109 ## stdout-json: "1\n2\nFAILED\n"
110 ## status: 0
111
112 #### ! is not a command
113 v='!'
114 $v echo hi
115 ## status: 127
116
117 #### Evaluation of argv[0] in pipeline occurs in child
118 ${cmd=echo} hi | wc -l
119 echo "cmd=$cmd"
120 ## STDOUT:
121 1
122 cmd=
123 ## END
124 ## BUG zsh STDOUT:
125 1
126 cmd=echo
127 ## END
128
129 #### bash/dash/mksh run the last command is run in its own process
130 echo hi | read line
131 echo "line=$line"
132 ## stdout: line=hi
133 ## OK bash/dash/mksh stdout: line=
134
135 #### shopt -s lastpipe (always on in OSH)
136 shopt -s lastpipe
137 echo hi | read line
138 echo "line=$line"
139 ## stdout: line=hi
140 ## N-I dash/mksh stdout: line=
141
142 #### shopt -s lastpipe (always on in OSH)
143 shopt -s lastpipe
144 i=0
145 seq 3 | while read line; do
146 (( i++ ))
147 done
148 echo i=$i
149 ## stdout: i=3
150 ## N-I dash/mksh stdout: i=0
151
152
153 #### SIGPIPE causes pipeline to die (regression for issue #295)
154 cat /dev/urandom | sleep 0.1
155 echo ${PIPESTATUS[@]}
156
157 # hm bash gives '1 0' which seems wrong
158
159 ## STDOUT:
160 141 0
161 ## END
162 ## BUG bash STDOUT:
163 1 0
164 ## END
165 ## N-I zsh stdout:
166 ## N-I dash status: 2
167 ## N-I dash stdout-json: ""