Sem xargs
$ ( IFS=$'\n'; somefun $(lsx) )
arg='1 is one'
arg='2 are two'
O subshell é usado para que a alteração para IFS
seja local, não global.
Limitação : Isso submete a saída de lsx
à expansão do nome do caminho, o que pode ou não ser um problema.
Com xargs
Para acessar uma função de shell com xargs, precisamos executar um shell. Para ter acesso a somefun
em um shell filho, primeiro precisamos exportá-lo. Assim:
$ export -f somefun
$ lsx | xargs -d'\n' bash -c 'somefun "$@"' SomeFun
arg='1 is one'
arg='2 are two'
O primeiro argumento para bash
é atribuído a $0
e serve como o nome do programa em mensagens de erro. Esta pode ser uma palavra arbitrária. Aqui, usamos SomeFun
.
Exemplos dos problemas de expansão do nome do caminho
$ lsx() { echo '1 is one*'; echo '2 are two*'; }
$ touch '1 is one'{1..3} two{a..c}
$ ( IFS=$'\n'; somefun $(lsx) )
arg='1 is one1'
arg='1 is one2'
arg='1 is one3'
arg='2 are two*'
Como você pode ver, a primeira linha de saída foi expandida em três linhas.
O shell primeiro executa divisão de palavras na saída de $(lsx)
. Como o IFS é definido como um caractere de nova linha, a saída é dividida em linhas. O shell executa então a expansão do nome do caminho. Como existem arquivos que correspondem ao glob 1 is one*
, esse glob é expandido em uma lista desses nomes. Em nosso exemplo, não há arquivos que correspondam ao glob 2 is two*
e, portanto, que glob não seja expandido. (No IFS padrão, 2 is two*
teria sido dividido em três palavras e o terceiro corresponderia aos arquivos twoa
, twob
e twoc
.)
A abordagem xargs
evita a expansão do nome do caminho:
$ export -f somefun
$ lsx | xargs -d'\n' bash -c 'somefun "$@"' SomeFun
arg='1 is one*'
arg='2 are two*'