1

ATM my current thoughts are, to do it like this:

a_NODE=$(node -v) &
a_NPM=v$(npm -v) &
a_YARN=v$(yarn -v) &
a_CURL=v$(curl --version | head -n 1 | awk '{ print $2 }') &
wait
echo "Node:             $a_NODE"
echo "NPM:              $a_NPM"
echo "YARN:             $a_YARN"
echo "curl:             $a_CURL"

But this actually skips all the variable definitions and prints empty version strings. AFAIK the wait command should make the script wait untill all of the varbiables are set and just then go over to printing - but it doesn't.

6
  • 1
    Background commands run in a subshell, so the assignments don't affect the original shell. Commented Jun 30, 2022 at 17:13
  • when you put a process in the background you are actually spawning a new standalone process; and while the current process may be referred to as the parent process there is no interaction between the two processes which means when the background process exits, any assignments made in that process disappear with the process; to feed the results of the child processes back to the parent process you'll need to implement some sort of interprocess communications (eg, files, pipes, sockets, etc) Commented Jun 30, 2022 at 17:14
  • You could have each command write to temporary files. Then assign the variables from the files after they're all done. Commented Jun 30, 2022 at 17:14
  • @ufopilot He does if he wants to run the commands concurrently. Commented Jun 30, 2022 at 17:14
  • It says it right there in the title: "in parallel" Commented Jun 30, 2022 at 17:16

2 Answers 2

5

Background commands run in subshells, so the variable assignments aren't in the original shell process.

Redirect the outputs to files, and read those files in the main shell.

node -v > /tmp/node.$$ &
npm -v > /tmp/npm.$$ &
yarn -v > /tmp/yarn.$$ &
curl --version | head -n 1 | awk '{ print $2 }' > /tmp/curl.$$ &
wait
a_NODE=$(</tmp/node.$$)
a_NPM=$(</tmp/npm.$$)
a_YARN=$(</tmp/yarn.$$)
a_CURL=$(</tmp/curl.$$)
rm -f /tmp/{node,npm,yarn,curl}.$$
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, that worked :) Just a sidequestion: can I store the output in variables and not in files?
No, that's the whole problem.
1

@Barmar's answer is probably the correct for this particular question. If you have more than just 4 jobs you want to run in parallel, a better solution is to use parset:

$ parset myarr -j 8 'echo Job {#}; echo arguments {}' ::: a b c ::: X Y Z ::: 1 2 3
$ echo ${myarr[5]}
Job 6 arguments a Y 3

parset will basically do what @Barmar does, but will also clean up tmp-files if the command crashes.

https://www.gnu.org/software/parallel/parset.html

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.