Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

xargs not working with built in shell functions

I am trying to speed up the processing of a database. I migrated towards xargs. But I'm seriously stuck. Piping a list of arguments to xargs does not work if the command invoked by xargs isn't a built in. I can't figure out why. Here is my code:

#!/bin/bash

list='foo
bar'

test(){
    echo "$1" 
}

echo "$list" | tr '\012' '\000' | xargs -0 -n1 -I '{}' 'test' {}

So there is no output at all. And test function never gets executed. But if I replace "test" in the "xargs" command with "echo" or "printf" it works fine.

like image 472
Sgt.Doakes Avatar asked Dec 01 '22 17:12

Sgt.Doakes


1 Answers

You can't pass a shell function to xargs directly, but you can invoke a shell.

printf 'foo\0bar\0' |
xargs -r -0 sh -c 'for f; do echo "$f"; done' _

The stuff inside sh -c '...' can be arbitrarily complex; if you really wanted to, you could declare and then use your function. But since it's simple and nonrecursive, I just inlined the functionality.

The dummy underscore parameter is because the first argument after sh -c 'script' is used to populate $0.

Because your question seems to be about optimization, I imagine you don't want to spawn a separate shell for every item passed to xargs -- if you did, nothing would get faster. So I put in the for loop and took out the -I etc arguments to xargs.

like image 175
tripleee Avatar answered Dec 04 '22 04:12

tripleee