Cenário:
$ process(){ echo "[$1] [$2] [$3]" ; } ; export -f process
$ process "x" "" "a.txt"
[x] [] [a.txt]
Aqui vemos que o segundo argumento é uma string vazia (esperado).
$ find -name "*.txt" -print | SHELL=$(type -p bash) parallel process "x" ""
[x] [./a.txt] []
[x] [./b.txt] []
[x] [./c.txt] []
Aqui vemos que o segundo argumento é a saída de find (inesperado).
Resultado esperado:
[x] [] [./a.txt]
[x] [] [./b.txt]
[x] [] [./c.txt]
Como consertar?
Nota: se o segundo argumento for alterado de ""
para "y"
, então a saída de find estará presente como o terceiro argumento (esperado):
$ find -name "*.txt" -print | SHELL=$(type -p bash) parallel process "x" "y"
[x] [y] [./a.txt]
[x] [y] [./b.txt]
[x] [y] [./c.txt]
Por que a saída de find não está presente como terceiro argumento com ""
?
UPD: Parece que a solução é \"\"
:
$ find -name "*.txt" -print | SHELL=$(type -p bash) parallel process "x" \"\"
[x] [] [./a.txt]
[x] [] [./b.txt]
[x] [] [./c.txt]
No entanto, não tenho certeza se esta é a solução geral correta. Aqui está o contra-exemplo:
$ VAR="" ; find -name "*.txt" -print | SHELL=$(type -p bash) parallel process "x" "$VAR"
[x] [./a.txt] []
[x] [./b.txt] []
[x] [./c.txt] []
Portanto, o paralelo executa o comando por meio de um shell, em vez de executá-lo diretamente. Bem, tem que ser assim, caso contrário a função shell que você está usando não funcionaria.
Isso também significa que os argumentos com espaços em branco serão divididos:
E realmente não importa se você cita os argumentos individuais ou o comando inteiro:
E você pode fazer coisas assim:
Para passar valores arbitrários, você precisa cotá-los para o shell. No Bash, você poderia usar a
${var@Q}
expansão para variáveis:E o paralelo parece ter uma opção para fazer exatamente isso:
É claro que isso também irá descartar redirecionamentos e coisas assim:
Claro, ele irá citar espaços em branco, então se você tentar passar os argumentos do comando como uma única string, ele falhará.
Observe que quando você faz isso
a variável ainda contém apenas a string vazia, que é passada para paralelo como argumento. Para torná-lo igual a
parallel process "x" \"\"
, você precisaria ter aspas na variável, ou sejaVAR=\"\"
, ouVAR='""'
ou equivalente. Ou use algo parecidoparallel process "x" "'$VAR'"
. E lembre-se de que você não pode colocar coisas cegamente entre aspas se a própria variável também puder conter aspas. Isso irá falhar: