Bash – Why do bash variables disappear when I use xargs

bashpipeshellxargs

I have a simple bash script and want to count how often a command gets called. Here is a minimal example, the counter is called c and should be 4 at the end:

#!/bin/bash

c=0;
for a in X Y; do
  for b in 1 2; do
    c="$(( ${c} + 1 ))"
    echo "${a}${b}"
  done #| xargs -L 1 -P 20 echo
  echo "count $c"
done
echo "--"
echo "final $c"

Works great without xargs (final=4), but when I uncomment the pipe to xargs it counts nothing (final=0). Why?

Expected output: |  This happens with xargs:
X1               |  X1
X2               |  X2
count 2          |  count 0
Y1               |  Y1
Y2               |  Y2
count 4          |  count 0
--               |  --
final 4          |  final 0

Best Answer

The pipe means that your for loop is happening in a subshell, which doesn't pass $c back to the rest of your program. You'll need to rewrite without the pipe. This StackOverflow question is pretty similar. The <( ) syntax might be your friend here.

Related Question