I have the following test script.

#!/bin/bash

function foo {
  printf "Test line break: $1\nafter line break\n\n"
}

for VARIABLE in {1..30}
do
  foo $VARIABLE &
done
wait

Now I executed the script several times, and some times the output looks like that:

Test line break: 15
Test line break: 14
after line break: 14
after line break: 15


Test line break: 16
after line break: 16

instead of the expected:

Test line break: 15
after line break: 15

Test line break: 14
after line break: 14

Test line break: 16
after line break: 16

how can I prevent that printf "interrupts" another printf, but still running it in the background?

For me it seems, that the problem is the "\n" inside printf.

  • If you're going to use printf remember that its first string is actually a format string and so understands % as a format character. You would be better with printf "%s" ""Test line break: $1\nafter line break\n\n" or even printf "Test line break: %s\nafter line break\n\n" "$1" – roaima Sep 7 '15 at 19:19
up vote 5 down vote accepted

In fact you need a mutex :

Each sub-shell will access concurrently to the same /dev/stdout of the parent shell, so you can not ensure the order even inside the same function. To ensure it you need a lock which enforce the mutual exclusion i.e. : all other processes won't start to write in /dev/stdout until the lock is released.

#!/bin/bash

function foo {
lockdir=/tmp/myscript.lock
 mkdir "$lockdir" 2>/dev/null
while [ $? -ne 0 ]; do mkdir "$lockdir" 2>/dev/null; done
printf "Test line break: $1\nafter line break: $1\n\n"
rm -rf $lockdir
}

for VARIABLE in {1..30}
do
  foo $VARIABLE &
done
wait

This will give this as a result :

$ bash plop1 2>/dev/null
Test line break: 5
after line break: 5

Test line break: 3
after line break: 3

Test line break: 11
after line break: 11

Test line break: 23
after line break: 23

Test line break: 14
after line break: 14

Test line break: 17
after line break: 17

Test line break: 24
after line break: 24

Test line break: 21
after line break: 21

Test line break: 27
after line break: 27

Test line break: 6
after line break: 6

Test line break: 2
after line break: 2

Test line break: 9
after line break: 9

Test line break: 26
after line break: 26

Test line break: 29
after line break: 29

Test line break: 20
after line break: 20

Test line break: 1
after line break: 1

Test line break: 12
after line break: 12

Test line break: 4
after line break: 4

Test line break: 13
after line break: 13

Test line break: 10
after line break: 10

Test line break: 15
after line break: 15

Test line break: 28
after line break: 28

Test line break: 25
after line break: 25

Test line break: 19
after line break: 19

Test line break: 18
after line break: 18

Test line break: 8
after line break: 8

Test line break: 7
after line break: 7

Test line break: 16
after line break: 16

Test line break: 22
after line break: 22

Test line break: 30
after line break: 30
  • 2
    you can also have a look at this excellent wiki : wiki.bash-hackers.org/howto/mutex – netmonk Sep 7 '15 at 13:03
  • thank you! But is it possible without having to type 2>/dev/null? – sam Sep 7 '15 at 13:24
  • yes, you just have to add it inside the function ! i just edited the script – netmonk Sep 7 '15 at 13:25
  • very cool, thanks – sam Sep 7 '15 at 13:28

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.