Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Launch process from Bash script in the background, then bring it to foreground

The following is a simplified version of some code I have:

#!/bin/bash

myfile=file.txt
interactive_command > $myfile &
pid=$!

# Use tail to wait for the file to be populated
while read -r line; do
  first_output_line=$line
  break # we only need the first line
done < <(tail -f $file)
rm $file

# do stuff with $first_output_line and $pid
# ...
# bring `interactive_command` to foreground?

I want to bring interactive_command to the foreground after its first line of output has been stored to a variable, so that a user can interact with it via calling this script.

However, it seems that using fg %1 does not work in the context of a script, and I cannot use fg with the PID. Is there a way that I can do this?

(Also, is there a more elegant way of capturing the first line of output, without writing to a temp file?)

like image 836
David Bailey Avatar asked Oct 16 '22 15:10

David Bailey


1 Answers

Job control using fg and bg are only available on interactive shells (i.e. when typing commands in a terminal). Usually the shell scripts run in non-interactive shells (same reason why aliases don't work in shell scripts by default)

Since you already have the PID stored in a variable, foregrounding the process is same as waiting on it (See Job Control Builtins). For example you could just do

wait "$pid"

Also what you have is a basic version of coproc bash built-in which allows you get the standard output messages captured from background commands. It exposes two file descriptors stored in an array, using which one can read outputs from stdout or feed inputs to its stdin

coproc fdPair interactive_command 

The syntax is usually coproc <array-name> <cmd-to-bckgd>. The array is populated with the file descriptor id's by the built-in. If no variable is used explicitly, it is populated under COPROC variable. So your requirement can be written as

coproc fdPair interactive_command 
IFS= read -r -u "${fdPair[0]}" firstLine
printf '%s\n' "$firstLine"
like image 95
Inian Avatar answered Nov 15 '22 09:11

Inian