DEV Community

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

Collapse
 
vonheikemen profile image
Heiker • Edited

I used xargs this week.

It looks like the open command can't take data from the standard input, so I ended up using something like this.

some_command | xargs -r -I{} open {}
Enter fullscreen mode Exit fullscreen mode

For those who don't know, xargs (with the right arguments) can act like the map method on javascript arrays. So you can imagine the above doing something like this:

some_command().map(arg => open(arg))
Enter fullscreen mode Exit fullscreen mode
Collapse
 
jeremyf profile image
Jeremy Friesen

xargs is some great shell magic. And your JS translation helps me better think about it.

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
Collapse
 
nickytonline profile image
Nick Taylor

Nice!

Nice