j0kR
j0kR

Reputation: 15

wrong output because of backgrounded processes

If I run the script with ./test.sh 100 I do not get the output 100 because I am using a thread. What do I have to do to get the expected output? (I must not change test.sh though.)

test.sh

#!/bin/bash
FILE="number.txt"
echo "0" > $FILE
for (( x=1; x<=$1; x++)); do
    exec "./increment.sh" $FILE &
done
wait
cat $FILE

increment.sh

#!/bin/bash
value=(< "$1")
let value++
echo $value > "$1"

EDIT

Well I tried this:

#!/bin/bash
flock $1 --shared 2>/dev/null
value=(< "$1")
let value++
echo $value > "$1"

Now i get something like 98 99 all the time if I use ./test.sh 100 I is not working very well and I do not know how to fix it.

Upvotes: 1

Views: 88

Answers (1)

pilcrow
pilcrow

Reputation: 58544

If test.sh really cannot be improved, then each instance of increment.sh must serialize it's own access to $FILE.

Filesystem locking is the obvious solution for this under UNIX. However, there is no shell builtin to accomplish this. Instead, you must rely on an external utility program like flock, setlock, or chpst -l|-L. For example:

#!/bin/bash
(
  flock 100          # Lock *exclusively* (not shared)
  value=(< "$1")
  let value++
  echo $value > "$1"
) 100>>"$1"          # A note of caution

A note of caution: using the file you'll be modifying as a lockfile gets tricky quickly — it's easy to truncate in shell when you didn't mean to, and the mixing of access modes above might offend some people — but the above avoids gross mistakes.

Upvotes: 2

Related Questions