0

I would like to write a script that starts a process in a screen, letting it continue to run, but extracts a certain part of the output for use in the main process of the script.

My first idea was to use a named pipe to communicate between the two processes. However, using an actual named pipe just causes the script to hang forever -- the screen boots up and runs fine, and I can access it later, but the terminal process just hangs without returning:

pipe=/tmp/fwdpipe$$
trap "rm -f $pipe" exit

mkfifo $pipe

server=$(cat $pipe) &

screen -dmS jupyter
screen -S jupyter -X stuff "cat foo" > $pipe\015"

wait
echo $server

(The background-and-wait pattern is an experiment; the problem persists if I move the server= line to the end.)

If I use a normal file instead, the cat complains that the file doesn't exist. Either way, I can't seem to achieve that original goal of communicating from within a screen.

  • I figured out part of my problem: the cat complaining that the file doesn't exist is because the screen seems to be running much slower than expected, and also running in parallel in a way I didn't expect. (I expected each screen line to wait for its own internal output before returning.) Simply adding sleep 4 fixed that problem. I'd still like to use the pipe if possible, though. – linkhyrule5 Sep 20 at 21:43
0

You should start the screen command before reading from the fifo. This example will list the current directory in screen and the nonexistent path error will be redirected to the fifo.

#!/bin/bash  
  
[[ -p screen.fifo ]] \  
|| mkfifo -m 660 screen.fifo  
  
exec 3<>screen.fifo

session=test  

screen -ls $session >&- || screen -dmS $session  
screen  -S $session \  
        -X stuff 'ls \$PWD nonexistent 2> screen.fifo\n' &  
  
while IFS= read -r -u 3; do  
echo REPLY: $REPLY  
done

You can also use tee to write to both screen and the fifo:

#!/bin/bash

[[ -p screen.fifo ]] \
    || mkfifo -m 660 screen.fifo

session=test

screen -ls $session >&- || screen -dmS $session
screen  -S $session \
        -X stuff "printf '%s\\\n%s\\\n' hello world | tee screen.fifo\n"

text="$(cat < screen.fifo)"
echo "$text"
| improve this answer | |

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.