DEV Community

Discussion on: October 22nd, 2021: What did you learn this week?

Collapse
 
grendel profile image
grendel

xargs can come in handy in a pinch, but it's usually unnecessary and the way it generates arguments can cause some complications. I can't think of a case where xargs would be more appropriate than Command Substitution or a while read loop, e.g.:

open "$(some_commands)" #thus you fully control word-splitting
Enter fullscreen mode Exit fullscreen mode

or

some_commands | \
  while IFS= read -r line; do #unsetting IFS here prevents word-splitting
    some_other_commands "$line"
    even_some_more_commands "$line"
    #vars declared in here are not valid afterwards,
    #since they are declared inside the pipeline subshell
    #and its environment does not hoist
    #This includes $line
  done

#alternatively, using process substitution:
while IFS= read -r line; do
  some_other_commands "$line"
  #variables set here remain valid afterwards
  #since this while-loop is not in a subshell
  #thus the last $line will remain set afterwards
done < <(some_commands)
Enter fullscreen mode Exit fullscreen mode

With process substitution and the mapfile builtin, you can even populate an array and iterate over that:

mapfile -t arr < <(some_commands)
#synonym: readarray -t arr < <(some_commands)

for elem in "${arr[@]}"; do
  some_stuff_with "$elem"
done
# or:
for ((i=0; i<${#arr[@]}; i++)); do
  some_stuff_with "${arr[$i]}"
done
Enter fullscreen mode Exit fullscreen mode