Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > gnu.bash.bug > #15359 > unrolled thread

wait fails to grab exit codes with multiple process substitutions

Started byleo.dalecki@ntymail.com
First post2019-09-14 12:29 +0200
Last post2019-09-14 12:29 +0200
Articles 1 — 1 participant

Back to article view | Back to gnu.bash.bug

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  wait fails to grab exit codes with multiple process substitutions leo.dalecki@ntymail.com - 2019-09-14 12:29 +0200

#15359 — wait fails to grab exit codes with multiple process substitutions

Fromleo.dalecki@ntymail.com
Date2019-09-14 12:29 +0200
Subjectwait fails to grab exit codes with multiple process substitutions
Message-ID<mailman.243.1568494359.2190.bug-bash@gnu.org>
From: leo.dalecki@ntymail.com
To: bug-bash@gnu.org
Subject: wait fails to grab exit codes with multiple process substitutions

Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -g -O2 -fdebug-prefix-map=/build/bash-2bxm7h/bash-5.0=. -fstack-protector-strong -Wformat -Werror=format-security -Wall -Wno-parentheses -Wno-format-security
uname output: Linux debian 4.19.0-5-amd64 #1 SMP Debian 4.19.37-5+deb10u2 (2019-08-08) x86_64 GNU/Linux
Machine Type: x86_64-pc-linux-gnu

Bash Version: 5.0
Patch Level: 3
Release Status: release

Description:
	Hi,

	I was trying to write a script that could run an arbitrary amount of asynchronous commands, and then as soon as one finishes, perform actions
	according to its exit code and output. 

	I attempted to do this by using process substitution and the wait command. But wait's ability to retrieve the exit code of a finished process 
	that is a current shell's children seems inconsistent.

	The script starts ten asynchronous commands by redirecting a process substitution's file descriptor to one of the current shell using exec.
	The script then uses wait with the process IDs of the asynchronous tasks to retrieve their exit codes.

	wait fails on nine of the ten tasks, giving the error "wait: pid X is not a child of this shell". But weirdly enough, it succeeds when retrieving 
	the exit code of the last asynchronous task to be run.

	The exact script I use is included in Repeat-By section, as a way to trigger the bug.

	Thank you and have a nice day.

Repeat-By:
	The following script reproduces the behavior I described in the Description section:

	
	#!/bin/bash
	
	# bg.sh
	
	# Executing commands asynchronously, retrieving their exit codes and outputs upon completion.
	
	asynch_cmds=
	
	echo -e "Asynchronous commands:\nPID	FD"
	
	for i in {1..10}; do
		exec {fd}< <(sleep $(( i * 2 )) && echo $RANDOM && exit $i) # Dummy asynchronous task, standard output's stream is redirected to the current shell
		asynch_cmds+="$!:$fd " # Append the task's PID and FD to the list of running tasks
	
		echo "$!	$fd"
	done
	
	echo -e "\nExit codes and outputs:\nPID	FD	EXIT	OUTPUT"
	
	while [[ ${#asynch_cmds} -gt 0 ]]; do # While the list of running tasks isn't empty
	
		for asynch_cmd in $asynch_cmds; do # For each task in the list
	
			pid=${asynch_cmd%:*} # Task's PID
			fd=${asynch_cmd#*:} # Task's FD
	
			if ! kill -0 $pid 2>/dev/null; then # If the task ended
	
				wait $pid # Retrieving the task's exit code
				echo -n "$pid	$fd	$?	"
	
				cat <&$fd # Retrieving the task's output
	
				asynch_cmds=${asynch_cmds/$asynch_cmd /} # Removing the task from the list
			fi
		done
	done


	By running this script, you will see that wait gives the error I described. And also that the tenth task (with exit code 10) doesn't trigger the wait error.

[toc] | [standalone]


Back to top | Article view | gnu.bash.bug


csiph-web