Home > Blockchain >  Passing arrays as command line arguments with xargs
Passing arrays as command line arguments with xargs

Time:09-21

I have the following two scripts:

#script1.sh:
#!/bin/bash
this_chunk=(1 2 3 4)
printf "%s\n" "${this_chunk[@]}" | ./script2.sh


#script2.sh:
#!/bin/bash
while read -r arr 
do
    echo "--$arr"
done

When I execute script1.sh, the output is as expected:

--1
--2
--3
--4

which shows that I was able to pipe the elements of the array this_chunk as arguments to script2.sh. However, if I change the line calling script2.sh to

printf "%s\n" "${this_chunk[@]}" | xargs ./script2.sh

there is no output. My question is, how to pass the array this_chunk using xargs, rather than simple piping? The reason is that I will have to deal with large arrays and thus long argument lists which will be a problem with piping.

Edit: Based on the answers and comments, this is the correct way to do it:

#script1.sh
#!/bin/bash
this_chunk=(1 2 3 4)
printf "%s\0" "${this_chunk[@]}" | xargs -0 ./script2.sh


#script2.sh
#!/bin/bash
for i in "${@}"; do
    echo $i
done

CodePudding user response:

how to pass the array this_chunk using xargs

Note that xargs by default interprets ' " and \ sequences. To disable the interpretation, either preprocess the data, or better use GNU xargs with -d '\n' option. -d option is not part of POSIX xargs.

printf "%s\n" "${this_chunk[@]}" | xargs -d '\n' ./script2.sh

That said, with GNU xargs prefer zero terminated streams, to preserve newlines:

printf "%s\0" "${this_chunk[@]}" | xargs -0 ./script2.sh

Your script ./script2.sh ignores command line arguments, and your xargs spawns the process with standard input closed. Because the input is closed, read -r arr fails, so your scripts does not print anything, as expected. (Note that in POSIX xargs, when the spawned process tries to read from stdin, the result is unspecified.)

  • Related