Usando o comando a seguir, alguém poderia explicar qual é exatamente o propósito dos chavetas finais ({}) e do sinal de mais (+)?
E como o comando operaria de maneira diferente se eles fossem excluídos do comando?
find . -type d -exec chmod 775 {} +
Usando o comando a seguir, alguém poderia explicar qual é exatamente o propósito dos chavetas finais ({}) e do sinal de mais (+)?
E como o comando operaria de maneira diferente se eles fossem excluídos do comando?
find . -type d -exec chmod 775 {} +
Respostas:
As chaves serão substituídas pelos resultados do findcomando e chmodserão executadas em cada uma delas. As +marcas findtentar executar o mínimo de comandos como possível (portanto, chmod 775 file1 file2 file3em oposição a chmod 755 file1, chmod 755 file2, chmod 755 file3). Sem eles, o comando apenas dá um erro. Tudo isso é explicado em man find:
-exec command ;
Executar comando ; true se 0 status for retornado. Todos os argumentos a seguir
findsão considerados argumentos para o comando até que um argumento que consiste em ';' seja encontrado. A string '{}' é substituída pelo nome do arquivo atual sendo processado em todos os lugares em que ocorre nos argumentos do comando, não apenas nos argumentos em que está sozinho, como em algumas versões dofind. ...
-exec command {} +
Essa variante da
-execação executa o comando especificado nos arquivos selecionados, mas a linha de comando é criada anexando cada nome de arquivo selecionado no final; o número total de invocações do comando será muito menor que o número de arquivos correspondentes. ...
Além da resposta de Terdon,
-exec …deve ser terminado com um ponto-e-vírgula ( ;) ou um sinal de mais ( +). Ponto e vírgula é um caractere especial no shell (ou, pelo menos, a cada escudo que eu já utilizado), por isso, se é para ser usado como parte do findcomando , ele deve ser precedido ou cotados ( \;, ";"ou ';').Com -exec … ;, a {}cadeia pode aparecer várias vezes no comando, incluindo zero ou duas ou mais, em qualquer posição.
Veja isso
para um exemplo de por que você pode querer fazer -execsem usar {}.
Ter duas ou mais aparências é útil principalmente porque, em (pelo menos) algumas versões do find, {}não precisa ser uma palavra por si só; pode ter outros caracteres no começo ou no fim; por exemplo,
find . -type f -exec mv {} {}.bak ";"
Com -exec … +, a {}cadeia deve aparecer como o último argumento antes do +. Um comando como
find . -name "*.bak" -exec mv {} backup_folder +
resulta na find: missing argument to ‘-exec’mensagem de erro enigmática .
Uma solução alternativa específica para os comandos cpe mvé
find . -name "*.bak" -exec mv -t backup_folder {} +
ou
find . -name "*.bak" -exec mv --target-directory=backup_folder {} +
O {}deve ser uma palavra por si só; não pode ter outros caracteres no começo ou no final. E, em (pelo menos) algumas versões find, você pode não ter mais de uma {}.
Uma nota de sanidade: você pode dizer
encontrar . -name "* .sh" -type f -executable -exec {} args opcionais aqui ";"
para executar cada um dos seus scripts. Mas
encontrar . -name "* .sh" -tipo f -executable -exec {} +
executa um de seus scripts, com os nomes de todos os outros como parâmetros. Isso é semelhante a dizer
./*.sh
como um comando shell, exceto findque não garante que ele classifique seus resultados, portanto você não tem garantia de execução aaa.sh
(seu primeiro *.sharquivo em ordem alfabética ) como seria com a execução ./*.sh.
Um aspecto findque pode não estar perfeitamente claro para iniciantes é que a linha de comando é, efetivamente, uma declaração executável em um idioma misterioso. Por exemplo,
find . -name "*.sh" -type f -executable -print
significa
for each file
if the file’s name matches `*.sh` (i.e., if it ends with `.sh`)
then
if it is a plain file (i.e., not a directory)
then
if it is executable (i.e., the appropriate `---x--x--x` bit is set)
then
print the file’s name
end if
end if
end if
end loop
ou simplesmente,
for each file
if the file’s name matches `*.sh` AND it is a plain file AND it is executable
then
print the file’s name
end if
end loop
Algumas das -palavras - chave são uma ação executável e um teste. Em particular, isso é verdade para -exec … ;; por exemplo,
find . -type f -exec grep -q cat {} ";" -print
traduz para
para cada arquivo
se for um arquivo simples (ou seja, não um diretório)
então
execute o nome do arquivo grep -q cat
se o processo for bem-sucedido (ou seja, sai com o status 0)
então
imprime o nome do arquivo
fim se
fim se
laço final
que imprimirá os nomes de todos os arquivos que contêm a string “ cat”. E, embora isso seja algo que greppossa ser feito sozinho (com a opção -l(minúscula L)), pode ser útil usá-lo findpara encontrar arquivos que contenham uma determinada string E tenham um determinado tamanho E sejam de propriedade de um determinado proprietário E foram modificados em um determinado intervalo de tempo,….
No entanto, isso não funciona -exec … +. Como -exec … +executa um comando para vários arquivos, não faz sentido usá-lo como uma condição lógica dentro de um for each file …loop.
findgeralmente sai com um status de saída 0, a menos que você dê argumentos inválidos ou encontre um diretório que não pode ler. Mesmo se um programa que você executa falhar (sai com um status de saída diferente de zero),
findsai com um status de saída igual a 0.
Exceto se um programa que você executa com -exec … +falha (sai com um status de saída diferente de zero)
findsai com um status de saída diferente de zero.Além de um milhão de versões find(1)
e testes do que findrealmente faz em alguns sistemas, o
The Open Group Base Specifications Edição 7, 2013 Edition
forneceu algumas informações sobre o que finddeve, pode e não deve ser feito.
... -exec mv {} {}.bak ...não é garantido para funcionar como esperado em todas asfindimplementações. Os estados padrão POSIX{}devem parecer sozinhos para serem sempre reconhecidos; caso contrário, o comportamento é livre para manter os caracteres inalterados ou substituí-los pelo nome do caminho. No primeiro caso, o seu comando inteiro vai essencialmente apagar todos os arquivos, mas o último encontrado ...