coproc Command in Linux with Examples

coproc command in Linux is a shell command which allows us to create a co-process that is connected to the invoking shell via two pipes. One of the pipes enables us to send the input while the other enables us to read the output without having to resort to named pipes. The co-process is executed asynchronously in a subshell. This command can be used above bash versions 4.0.

Syntax:

coproc command args #first command
coproc name command args #second command

The first command is used in the case of simple commands. Name must not be given to the command because in the case of simple command it is interpreted as the first word of the simple command.  In the case of compound commands, the second command is used. If the name is not provided then COPROC is the ‘name’ by default.  When the coprocess is executed, an array is created named ‘name'(by default COPROC if the name is not supplied in the command) in the context of the executing shell. The first element of this array is the output descriptor while the second element of the array is the input descriptor to the co-process. A bidirectional pipe is established between the executing shell and the co-process. Bash puts the file descriptors for those pipes into the array :

  • name[0] is the file descriptor for the pipe that is connected to the standard output of the co-process in the executing shell.
  • name[1] is the file descriptor for the pipe that is connected to the standard input of the co-process in the executing shell.

These pipes are established before any redirections are done by the command. These file descriptors can be utilized as arguments to shell commands and redirections using standard word expansions. The variable name_PID stores the process ID number. The wait builtin command may be used to wait for the co-process to complete its execution. The coproc command always returns success as it is created as an asynchronous command. The return status of a co-process is the same as the exit status of command. 

Working with coproc command

1. As is can be seen in the below-mentioned example code, no name is given in the coproc command so by default COPROC is the name of the array. COPROC[@] prints the elements of the array which stores the file descriptor that is connected to the output and input respectively. COPROC_PID stores the process ID number. COPROC[0] enables us to read the output of the coprocess



coproc (echo $(whoami))                                   
echo "The coprocess array is ${COPROC[@]}"         
echo "The PID of the coprocess is ${COPROC_PID}"                                 
read -r o <&"${COPROC[0]}"
echo "The user is $o which is the output of the coprocess"

whoami prints the name of the current user which is mishra in my system

2. The below-mentioned code prints geeksforgeeks as the output. The input to the bash is given using gfg[1] which is the file descriptor for the pipe connected to the input.

coproc gfg { bash ; }
echo 'echo geeksforgeeks' >&"${gfg[1]}"
read output <&"${gfg[0]}"
echo $output

3. The file descriptors of the co-process are accessible only to the process from which the co-process was generated. They are not inherited by subshells (For ex: any command which is launched within parenthesis is launched in a new subshell). As it can be seen from the below-mentioned code, Error is shown in the second case as the command within the parenthesis is launched within a new shell and file descriptors of co-process are accessible only to the process from which it was generated. 

coproc gfg ( read -r input; echo "${input}" )
echo "PID:${gfg_PID}"
#first case
echo "geeksforgeeks"  >&"${gfg[1]}"
read -r output1 <&"${gfg[0]}"
echo "The output of coprocess is ${output1}"
#second case                                     
(echo "geeksforgeeks"  >&"${gfg[1]}")    #This will cause an error                     
read -r output2 <&"${gfg[0]}"
echo "The output of coprocess is ${output2}"

In first case no error is produced and the desired statement is printed

4. tr command in the below-mentioned code will replace all instances of the letter “a” in the input with letter b. The file descriptor is closed by the exec statement. Note that closing this way is allowed in bash versions above 4.3. For versions, prior to 4.3, you need to first store the file descriptor in a variable and then use the exec command.

coproc gfg { tr a b; }
echo abbaaabbb >&"${gfg[1]}"
exec {gfg[1]}>&-
cat <&"${gfg[0]}"

Advantage of coproc command over & operator

Running a co-process in the background can also be achieved by using & operator which can be simply appended to the command. Commands like fg, kill, and [jobspec]% can be used to bring the process to the foreground or sending signals to it. But this does not allow us to send input to the background command or read the output of that command. This can be achieved using coproc command which can be interpreted as having the same function as an & operator with a two-way pipe established between the executing shell and the co-process. 

My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.


Article Tags :

Be the First to upvote.


Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.