3

Is there a way to allow a background job in bash to modify variables? for ex:

[bash]# a=1
[bash]# a=2 &
[1] 14533
[bash]# echo $a
1

I'd like the value of a to be 2 not 1

4 Answers4

4

Variables can't be sent back to a parent process from a child, so what you're trying to do is impossible. It's the same reason that cd has to be a shell builtin rather than an executable in its own right. If it were an executable, it would run, change the directory, and then exit, leaving you back in the shell which hasn't had its directory changed.

Carl Norum
  • 219,201
  • 40
  • 422
  • 469
1

A child process can't affect his parent's environment, but if your background process ends after the evaluation you can "pass" the value as an exit code. The parent can catch it with the wait command. Here is an example of a background process returning a variable incremented by one:

etuardu@subranu:~$ a=1
etuardu@subranu:~$ (exit $[ $a + 1 ]) &
[1] 7486
etuardu@subranu:~$ wait $!; a=$?
[1]+  Exit 2                  ( exit $[ $a + 1 ] )
etuardu@subranu:~$ echo $a
2
etuardu
  • 5,066
  • 3
  • 46
  • 58
0

As Carl explained quite well, it is impossible.

An example:

#!/bin/bash

a=1
for i in 1 2 3 4 5 6 7 8 9 10
do
    let a=a+1 ;echo "Child value $a"
done &
sleep 2
echo "Parent value $a"

Output would show child with value 1-10, and then parent with old value of 1.

bbaja42
  • 2,099
  • 18
  • 34
-1
-> a=1
-> a=2; exit &
-> echo $a
2
Rufo El Magufo
  • 686
  • 6
  • 19
  • 2
    That is changing the value in the current shell not in the background, and then launching a subshell to execute the 'exit' command. – glenn jackman Jul 25 '11 at 18:56
  • I don't like my solution but this works for the example of the user. – Rufo El Magufo Jul 25 '11 at 19:10
  • 1
    It doesn't. Nothing is modified in a background job. – glenn jackman Jul 25 '11 at 19:29
  • Not in background, I mean in current shell. Look at the example of the user, he is not checking the value in the background process. He is checking the value in *current* shell. If the user need the value in the current shell my example works (in bash 4.1). If he need check the value in the child process the example of @bbaja42 is the correct. – Rufo El Magufo Jul 25 '11 at 19:40
  • It doesn't actually work for me, the example above was a simple illustration, in my real script, there are 10 background jobs in parallel which do calculations and modify variables. They work in parallel in the background to save time, so transfer of information from background jobs to the shell is unavoidable. –  Aug 03 '11 at 10:07
  • Why don't use temp files? If you combine with tmpfs, it will be fast and you will can forget the bash variables. – Rufo El Magufo Aug 03 '11 at 10:16
  • Temp files is the first solution I originally thought about, however, I didn't want the overhead of creating and deleting files and I was for a more elegant alternative. I didn't know that time about tmpfs, it seems the only solution –  Jan 03 '12 at 18:21