[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bash process substitution process not awaited before next statement star
From: |
alexis |
Subject: |
bash process substitution process not awaited before next statement started? |
Date: |
Wed, 23 Nov 2011 08:41:56 +0100 (CET) |
Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64'
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-pc-linux-gnu'
-DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL
-DHAVE_CONFIG_H -I. -I../bash -I../bash/include -I../bash/lib -g -O2 -Wall
uname output: Linux torchio 2.6.32-5-amd64 #1 SMP Fri Sep 9 20:23:16 UTC 2011
x86_64 GNU/Linux
Machine Type: x86_64-pc-linux-gnu
Bash Version: 4.1
Patch Level: 5
Release Status: release
Description:
It looks as if bash is not waiting for a process-substition process
which is reading stdin to complete before bash moves on to executing
the next statement.
Repeat-By:
#!/bin/bash
LOCK_DIR=/tmp/$$
spew_and_slurp_with_lock()
{
local I
for ((I=0; I<1000; I++)); do
echo "some junk"
done > >(mkdir $LOCK_DIR; cat > /dev/null; rmdir $LOCK_DIR)
}
main()
{
local J
rm -fr $LOCK_DIR
for ((J=0; J<1000; J++)); do
spew_and_slurp_with_lock
done
}
main
Expected output: nothing
Actual output: rmdir errors ('cos dir already deleted) and mkdir
errors ('cos dir already exists)
A bit more info ...
The actual process in my real script's process substitution list was
sqlite3, which was randomly complaining that the database was locked;
for the purposes of demonstrating the problem mkdir+cat+rmdir is a
reasonable simulation of sqlite3 (both sqlite3 and mkdir+cat+rmdir
slurp stdin and use locking).
(I use a main() function here simply to allow be to below unambiguously
references bits of code above.)
The expected output was nothing. The actual output was:
mkdir: cannot create directory `/tmp/2076': File exists
rmdir: failed to remove `/tmp/2076': No such file or directory
mkdir: cannot create directory `/tmp/2076': File exists
rmdir: failed to remove `/tmp/2076': No such file or directory
...
The number of failing mkdir/rmdir pairs is not consistent:
fiori$ ./demo 2>&1 | wc -l
468
fiori$ ./demo 2>&1 | wc -l
470
fiori$ ./demo 2>&1 | wc -l
458
fiori$
I.e. somewhere between 20-25%. But that's just due to timing.
It seems to me that the process-substituted list has not finished
before bash moves on to executing the next commmand (in this case:
looping back round in main() to call spew_and_slurp_with_lock()
again). I.e. the N+1'th loop's mkdir is running before the N'th
loop's rmdir, and that results in the 'File exists' message.
The bash man page does not mention that the sustitute process runs
asynchronously, and, indeed, an added call to 'wait' immediately after
the 'for' loop in spew_and_slurp_with_lock() reaps nothing.
A second odd behaviour, which might just be another symptom of
an un-waited-for child process is that when the script finishes
the following things happen in the following order: I get a prompt,
an rmdir complains. Like this:
...
mkdir: cannot create directory `/tmp/12961': File exists
rmdir: failed to remove `/tmp/12961': No such file or directory
mkdir: cannot create directory `/tmp/12961': File exists
fiori$ rmdir: failed to remove `/tmp/12961': No such file or directory
Thanks!
Alexis
- bash process substitution process not awaited before next statement started?,
alexis <=