Reputation: 7370
I want to create a bash script that repeatedly pipes output between two processes, until the output contains some special characters.
Consider these two Python scripts:
script1.py
from sys import stdin
for line in stdin.readline():
if line.isdigit():
print int(line) + 3
script2.py
from sys import stdin
for line in stdin.readline():
if line.isdigit():
print int(line) - 1
and the following execution
$ echo 0|python script1.py|python script2.py|python script1.py|python script2.py
4
Can a Bash script be created, that executes the two scripts and passes the output from one as input to the other, until the output of script1 reaches some certain number?
(I don't want to modify the Python scripts, I'm not actually using them, they were just created in order to demonstrate what I want to achieve).
Upvotes: 1
Views: 131
Reputation: 75488
A safer approach that could prevent fork bomb:
function piper {
read
if [[ $REPLY == 4 ]]; then
echo 4
elif [[ $REPLY =~ ^[[:digit:]]+$ && $REPLY -lt 4 ]]; then
echo "$REPLY" | python script1.py | python script2.py | piper
fi
}
echo 0 | piper
Upvotes: 2
Reputation: 46823
Assuming that your python script script2.py
only outputs one number on one line, and you want to execute python script1.py | python script2.py
until the output number is 4
, here's a recursive way. It uses recursion so you might hit a stackoverflow if there are too many calls:
#!/bin/bash
apply_until4() {
local l
read l < <(python script1.py | python script2.py)
if [[ $l = 4 ]]; then
echo "$l"
return
fi
echo "$l" | apply_until4
}
echo "0" | apply_until4
or (with the same logic but slightly different implementation—not pure Bash anymore because of the cat
, though this could be changed):
#!/bin/bash
apply_until4() {
local l next=apply_until4
read l < <(python script1.py | python script2.py)
[[ $l = 4 ]] && next=cat
echo "$l" | $next
}
echo "0" | apply_until4
Another possibility without recursion:
#!/bin/bash
apply_until4() {
local l
read l
until [[ $l = 4 ]]; do
read l < <(echo "$l" | python script1.py | python script2.py)
done
echo "$l"
}
echo "0" | apply_until4
python script1.py | python script2.py
and if the output is not 4
, feed it to the combo again.The
read l < <(python script.py | python script2.py)
statement can be changed to
l=$(python script.py | python script2.py)
and, similarly, the
read l < <(echo "$l" | python script1.py | python script2.py)
statement can be changed to
l=$(echo "$l" | python script1.py | python script2.py)
with the difference that the read
will discard all leading and trailing spaces, if any.
Upvotes: 1