kd88
kd88

Reputation: 1204

Pipe to executable without exiting/EOF in bash

I have a (read-only) executable "myexec" which I always execute followed by the input "input1" (a string), and then I get on with my business "" and "exit" when I feel like it:

$ myexec
> input1
> do something else for as long as I like
> exit

What I would like to do is automatically execute "myexec" with the input "input1", and then be able to "do something else for as long as I like". From what I can see, my options are:

$ myexec <<< "input1"

or

$ echo "input1" | myexec

or

$ myexec << EOF
input1
EOF

BUT the problem with these methods is that they terminate "myexec" after reading "input1". How can I avoid the EOF/exit/terminate?

Upvotes: 10

Views: 5814

Answers (4)

pynexj
pynexj

Reputation: 20698

You can use to automate that. For example:

#!/usr/bin/expect

spawn /my/exec
expect "> "
send "input1\r"
interact

Upvotes: 5

chepner
chepner

Reputation: 531275

You can use cat for this:

$ { echo "input1"; cat; } | my exec

Upvotes: 6

Davide Berra
Davide Berra

Reputation: 6568

You can create a pipe and listen for inputs with tail -f

mkfifo pipe
tail -f pipe | ./script.sh

Example content of script.sh

#!/bin/bash

while read row
do
    if [ "${row}" = "exit" ]; then
        break
    fi
    echo "ROW READ $row"
done

echo "script exit"
exit 0

Then, with another script, feed the pipe

echo "example content" > ./pipe
echo "bla bla bla" > ./pipe
echo "exit" > ./pipe
echo "" > ./pipe

you'll obtain

[root@mypc ~]# tail -f pipe | ./script
ROW READ example content
ROW READ bla bla bla
script exit
[root@mypc ~]#

Upvotes: 2

andy magoon
andy magoon

Reputation: 2929

It almost sounds like you want a fifo, which is a named pipe stored in your filesystem. Any output you redirect to it will come out the other side into what is listening. Try this:

mkfifo myexec.fifo
myexec < myexec.fifo &
echo input1 > myexec.fifo
echo input2 > myexec.fifo

You can test this by using bash and having it run commands that are sent to the fifo, in the example below:

mkfifo bash.fifo
/bin/bash < bash.fifo &
echo uname > bash.fifo
Darwin

The ampersand detaches the process into the background, so as long as myexec continues to listen it'll continue to execute commands.

If myexec is exiting, you can wrap it in a while loop:

while [ 1 ]; do myexec < myexec.fifo; done

After myexec consumes the contents of what is waiting in the fifo, it will iterate the loop. If the fifo is empty, it will wait.

Upvotes: 0

Related Questions