Se eu tiver um diretório que contenha alguns arquivos cujos nomes tenham espaços, por exemplo,
$ ls -1 dir1
file 1
file 2
file 3
Posso copiar todos eles com êxito para outro diretório como este:
$ find dir1 -mindepth 1 -exec cp -t dir2 {} +
No entanto, a saída de find dir1 -mindepth 1
contém espaços sem escape:
$ find dir1 mindepth 1
dir1/file 1
dir1/file 3
dir1/file 3
Se eu usar em print0
vez de print
, a saída ainda conterá espaços sem escape:
$ find dir1 mindepth 1 -print0
dir1/file 1dir1/file 2dir1/file 3
Para copiar esses arquivos manualmente usando cp
, eu precisaria escapar dos espaços; mas parece que isso é desnecessário quando cp
surgem os argumentos find
, independentemente de eu usar +
ou \;
no final do comando.
Qual o motivo disso?
find..exec
pode lidar com nomes estranhos em seu próprio ..A questão é dividida em duas partes:
find
conseguem programas de chamadas usando-exec
sem funcionar em problemas com espaços incorporados em nomes de arquivos, e-print0
opção?Para o primeiro,
find
está fazendo uma chamada de sistema, na verdade uma de um grupo de chamadas relacionadas, chamadas de "exec" . Ele passa o nome do arquivo como argumento diretamente para esta chamada, que é passada diretamente (após a criação de um novo processo) sem perder informações sobre o nome do arquivo.O
find
recurso POSIX+
é explicado da seguinte forma, na lógica :Que " notavelmente um
-print0
primário" se refere ao GNUfind
exargs
que resolve o problema de uma maneira diferente. Também é suportado pelo FreeBSDfind
exargs
. Se você adicionou uma-0
opção (consulte a página do manual ) àxargs
chamada, esse programa aceita linhas terminadas com caracteres de "byte nulo". Por sua vez,xargs
chama exec -funtions para fazer seu trabalho. A distinção principal entre a-print0
e-0
característica versus a+
característica é que o primeiro passa os nomes de arquivo ao longo de um tubo, enquanto que o último não o faz. Os desenvolvedores encontram usos para quase qualquer recurso; os tubos não são excepção.De volta ao exemplo do OP, que usa uma
-t
opção paracp
: que não é encontrada no POSIX cp . Pelo contrário, é uma extensão (também conhecida como "característica não padronizada") fornecida pelo GNU cp . A-0
extensão dexargs
não melhoraria este exemplo, mas há outros casos em que ele pode ser usado com eficiência - tendo em mente que existe a alternativa portátil+
, que o GNUfind
aceita.fonte
( Isso deve ser um comentário, mas é muito grande. )
Para quem gosta de experimentar as coisas:
Crie um script listando os parâmetros posicionais passados, chame-o
list_positional_parameters.sh
.Execute
find
com ele em algum diretório $ dir:Como esperado, existe apenas um único parâmetro em todas as chamadas, o nome do arquivo, independentemente de haver espaços em seu nome ou não.
fonte
printf
comoprintf '"%s"\n' "$@"
imprimir todos os argumentos posicionais citados, para inspeção visual.