Diferença entre '{}' e {} no comando find?

17

Na documentação , vejo o uso das duas formas:

find . -type f -exec file '{}' \;

find repo/ -exec test -d {}/.svn -o -d {}/.git -o -d {}/CVS ; \
    
por tarabyte 03.11.2015 / 20:53

4 respostas

24

Para o bash shell, '{}' e {} são intercambiáveis. Este não é o caso de todos os shells (como fish ).

Colocar o argumento entre aspas simples indica explicitamente que as chaves devem ser enviadas para find . Dependendo do uso, o shell bash às vezes substitui o conteúdo das chaves.

Como visto abaixo, bash não substitui colchetes vazios, e eles são passados para o comando. Para o comando find , não importa.

$ echo {}
{}

$ echo {1}
{1}

$ echo {1,3}
1 3

$ echo '{1,3}'
{1,3}
    
por 03.11.2015 / 21:10
9

Com quase todos os intérpretes de shell disponíveis, não há absolutamente nenhuma diferença entre '{}' e {} .

As aspas simples são normalmente usadas para proteger a string incorporada de ser substituída por outra coisa, por exemplo:

  • 'a b' é um único parâmetro de três caracteres, sem as aspas que seriam dois parâmetros de caractere único
  • '$b' é literalmente o cifrão seguido pela letra b, sem a citação que seria o que a variável b contém e possivelmente nada se não fosse definida
  • '!!' são pontos de exclamação litteral enquanto não são citados e com alguns shells interativos, eles se expandem até o último comando colocado no histórico
  • '*' é um asterisco litteral, sem aspas, seria substituído pela lista de nomes de arquivos não ocultos no diretório atual.

Como nem o padrão POSIX nem os shells convencionais ( sh (Bourne), ksh , bash , ash , dash , zsh , csh , tcsh ) expanda {} para outra coisa, as aspas não são necessárias.

No entanto, há um shell exótico chamado fish , que expande {} como um espaço em branco string, por exemplo:

> ps -p %self
  PID TTY          TIME CMD
 5247 pts/1    00:00:00 fish
> echo a {} b '{}'
a  b {}

Essa é provavelmente a razão pela qual a documentação do GNU find sugere proteger {} da interpretação com aspas ou contrabarras.

    
por 04.11.2015 / 07:52
9

Para a maioria dos usuários (especialmente aqueles que usam POSIX shells), não há diferença.

De acordo com a seção Exemplo da página man do GNU find :

Notice that the braces are enclosed in single quote marks to protect them from interpretation as shell script punctuation.

Eu acho que o (s) autor (es) da página man do GNU estão errando no lado da cautela, mas eu notei que nem todos os exemplos em sua página man citam as chaves. Estes exemplos da documentação oficial do GNU encontram também omitem a citação.

Nos exemplos da especificação POSIX / Single UNIX , as chaves são não citado quando usado com a opção -exec .

Com um shell POSIX, a expansão de parâmetros ocorre apenas quando há parâmetros especiais dentro das chaves - mas não com chaves vazias .

O shell Bash inclui expansão de chave como um (não portátil) recurso, mas tais padrões são apenas expandidos quando uma vírgula ou pontos são incluídos dentro das chaves . O Bash também usa chaves para o agrupamento de comandos , mas isso não ocorre a menos que realmente seja um grupo de comandos dentro da chave.

Por fim, tentei executar find -exec ls -l {} \; em sh , dash e tcsh , mas nenhum desses shells expandiu o {} para mais nada. Como outros apontaram, o shell fish trata {} especialmente, mas este não é um shell POSIX (que seus criadores e usuários consideram uma vantagem). Não faz mal citar as chaves, mas os dactilógrafos preguiçosos que não usam a casca de peixe não devem se sentir culpados por omiti-los.

    
por 03.11.2015 / 21:10
5

Isso depende da sintaxe do seu shell. Em caso de dúvida, faça eco!

Execute isto

echo '{}'

e isso.

echo {}

Se eles produzem o mesmo resultado, a resposta para o seu shell é sim. Como outros já observaram, será pelo menos sim em bash e não em peixe. A saída, é o que você deve consultar a página de um determinado comando.

Se você quiser ser útil, você pode até prefixar echo para uma linha de comando inteira, para ver o comando real , com todos os seus argumentos, que seu shell realmente invocaria. Porém, esteja ciente de que a lista que compreende o comando mais argumentos é um verdadeiro array de strings, cada um possivelmente vazio ou com espaço em branco, mas o echo imprime ambiguamente como uma lista separada por espaços.

Como pode ser verificado com este comando echo ligeiramente mais detalhado (mostrando argumentos entre aspas),

#!/bin/sh
for a in "$@"; do
    printf '«%s» ' "$a"
done
echo ''

digitando isto na linha de comando,

find 'My Documents and Settings' -type f -exec file {} \;

significa isso para bash:

«find» «My Documents and Settings» «-type» «f» «-exec» «file» «{}» «;»

e isso no peixe:

«find» «My Documents and Settings» «-type» «f» «-exec» «file» «» «;»

Como um conselho geral, nunca é demais citar.

    
por 05.11.2015 / 00:55