Calling shell functions with xargs

bash, sh, xargs

Solution

Exporting the function should do it (untested):

export -f echo_var
seq -f "n%04g" 1 100 | xargs -n 1 -P 10 -I {} bash -c 'echo_var "$@"' _ {}

You can use the builtin `printf` instead of the external `seq`:

printf "n%04g\n" {1..100} | xargs -n 1 -P 10 -I {} bash -c 'echo_var "$@"' _ {}

Also, using `return 0` and `exit 0` like that masks any error value that might be produced by the command preceding it. Also, if there's no error, it's the default and thus somewhat redundant.

@phobic mentions that the Bash command could be simplified to

bash -c 'echo_var "{}"'

moving the `{}` directly inside it. But it's vulnerable to command injection as pointed out by @Sasha.

Here is an example why you should not use the embedded format:

$ echo '$(date)' | xargs -I {} bash -c 'echo_var "{}"'
Sun Aug 18 11:56:45 CDT 2019

Another example of why not:

echo '\"; date\"' | xargs -I {} bash -c 'echo_var "{}"'

This is what is output using the safe format:

$ echo '$(date)' | xargs -I {} bash -c 'echo_var "$@"' _ {}
$(date)

This is comparable to using parameterized SQL queries to avoid injection.

I'm using `date` in a command substitution or in escaped quotes here instead of the `rm` command used in Sasha's comment since it's non-destructive.

Problem

I am trying to use xargs to call a more complex function in parallel. ``` #!/bin/bash echo_var(){ echo $1 return 0 } seq -f "n%04g" 1 100 |xargs -n 1 -P 10 -i echo_var {} exit 0 ``` This returns the error ``` xargs: echo_var: No such file or directory ``` Any ideas on how I can use xargs to accomplish this, or any other solution(s) would be welcome.

Original source