1

I am trying to assign values to variables using GNU Parallel:

$ parallel --dry-run --xapply a{1}={2} ::: a b c ::: 5 6 7
aa=5
ab=6
ac=7

But the execution seems not to be working OK:

$ parallel --xapply a{1}={2} ::: a b c ::: 5 6 7
$ echo $aa

$ echo $ab

$ echo $ac

Empty values in all cases.

What is going on, and how could I assign a value to a variable by using GNU Parallel?

Further data:

  • I know there are ways to make GNU Parallel inherit the variables from its parent process, but in this case what I want is the reverse.
Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
  • 1
    IF this was possible, how would you deal with two parallel processes setting the same variable? E.g. parallel a={} ::: 1 2 3 – Ole Tange Feb 26 '18 at 12:02
  • I mean, they'd walk all over each other, but race conditions are par for the course. If it were possible, I would expect something like parallel {1}={2} ::: a b c :::+ 1 2 3 (I'm brand new to this, sorry if the syntax isn't right) to do something more useful. Other decisions, like allowing ungrouped output without line buffering, make me think that the philosophy is to give you control, and it's up to you to prevent races, correct them after the fact, or somehow make use of the result. Just my first impression. – John P Jan 08 '19 at 02:51

2 Answers2

2

You can’t set variable in the shell from outside the shell (including from a process started by the shell); see e.g. Is it possible to pass environment variables from child to parent in user space?

I doubt there would be much point in using parallel for this anyway, it’s not as if setting a variable takes a long time...

Stephen Kitt
  • 434,908
2

As Stephen Kitt writes, it is impossible to pass values from child to parent - that is you cannot do it without cheating.

Luckily for you newer versions of GNU Parallel includes a cheat called parset. parset is a shell function that you need to activate first.

$ . `which env_parallel.bash` # Replace bash with zsh, ksh, ash, dash, sh as needed
$ parset a,b,c echo ::: 5 6 7
$ echo $a
5

If the shell supports arrays:

$ parset arr echo ::: 5 6 7
$ echo ${arr[1]}
5 (in zsh) 6 (otherwise)

As Stephen Kitt indicates this is much slower than simply assigning the numerical value. But I take it that your example is just an MCVE, so the real situation will be much more complex and thus may warrant running in parallel.

Ole Tange
  • 35,514