9

I need to write a bash program that runs commands echoed to a named pipe it reads, but I cannot get it work only when a command is sent. It keeps repeating the last command until a new one is written.

That is:

  1. Execute ./read_pipe.sh
  2. It waits until a command is echoed to pipe and reads it.
  3. It executes the command once. <- What doesn't work. It keeps executing it forever.
  4. Repeat from step 2.

My read_pipe.sh

#!/bin/bash
pipe="mypipe"
if [ ! -p $pipe ]; then
  echo 'Creating pipe'
  mkfifo $pipe
fi

while true
do
  if read line <$pipe; then
    COMMAND=$(cat $pipe)
    echo "Running $COMMAND ..."
    # sh -c $COMMAND
  fi
done

If I cat "echo 'Hello World'" > mypipe the output is this forever:

Running "echo 'Hello World'" ...
Running "echo 'Hello World'" ...
Running "echo 'Hello World'" ...
Running "echo 'Hello World'" ...
...

How can I run the command once and wait for another echoed command?

7

One way to do it:

#! /usr/bin/env bash
pipe=/path/to/pipe
[ -p "$pipe" ] || mkfifo -m 0600 "$pipe" || exit 1
while :; do
    while read -r cmd; do
        if [ "$cmd" ]; then
            printf 'Running %s ...\n' "$cmd"
            # sh -c "$cmd" sh
        fi
    done <"$pipe"
done

It's probably a really bad idea to uncomment the sh line though.

8
  • I tried your solution, but It doesn't work properly. It executes the command once, but then your program exits. The intended way is keep executing the script, and when a new command is echoed to pipe, execute it. Jun 6 '17 at 8:05
  • Ok, I added a loop around it. Jun 6 '17 at 8:10
  • That's exactly what I've done. It executes the command sent to pipe forever until a new one is sent. I want it to be executed only once, and then wait for another command. Jun 6 '17 at 8:11
  • 1
    This is not what I'm seeing here. shrug Jun 6 '17 at 8:29
  • 1
    Sorry @SatoKatsura I've just found the solution: rm -f pipe && mkfifo pipe. Now it works correctly. For some reason it was a simple text file. -.-' Jun 6 '17 at 8:58
7

In your case, you can do simply:

tail -f $pipe | sh & 

no need for loops.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.