Eu sei que quando você tem problemas ao canalizar a saída de eg find ..
para xargs
devido a nomes de arquivo 'estranhos', pode ajudar usar um delimitador específico (por exemplo, \0
) para realmente passar nomes de arquivo completos (por exemplo find foldername/ -type f -print0 | xargs -0 ...
, . E 'sempre' ajuda citar strings problemáticas para especificar seus limites.
Mas e se essas strings (nomes de arquivo) contiverem caracteres sensíveis ao bash como '
, "
, `
, (
,.. ? e você quiser usar uma string duas vezes (ou seja, tiver que usar sh -c ..
e precisar injetar essas strings em comandos aninhados (ou seja, $(CMD)
)?
Por exemplo:
# create a file which should not exist but does
mkdir remove_afterwards
touch remove_afterwards/"some [\"strange\"] ('file')"
# this will work
find remove_afterwards/ -type f -print0 | xargs -0 -I{} sh -c 'echo "{}"'
# but this won't due to the nested command
find remove_afterwards/ -type f -print0 | xargs -0 -I{} sh -c 'echo "{}" $(stat -c "%s" "{}")'
stat: cannot statx 'remove_afterwards/some [strange] ('\''file'\'')': No such file or directory
remove_afterwards/some [strange] ('file')
Ainda não descobri como escapar do segundo {}
interior $()
.
Existe uma maneira?
É verdade que um script real com funções tornaria tudo isso mais fácil de escrever e ler, mas estou curioso e ter uma frase tão curta na história vale o esforço de escrever esta pergunta.