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


18

Na documentação , vejo o uso nos dois sentidos:

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

find repo/ -exec test -d {}/.svn -o -d {}/.git -o -d {}/CVS ; \

4
Parece que isso não tem nada a ver com o comando find, e sim com a citação adequada para o comando que está sendo chamado.
Zoredache

1
Experimente com peixe, em vez de bash.
Charles Duffy

Respostas:


24

Para a bashconcha, '{}'e {}são intercambiáveis. Este não é o caso de todas as conchas (como fish).

Colocar o argumento entre aspas simples indica explicitamente que os chavetas devem ser enviadas para find. Dependendo do uso, o shell bash às vezes substitui o conteúdo dos colchetes.

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

$ echo {}
{}

$ echo {1}
{1}

$ echo {1,3}
1 3

$ echo '{1,3}'
{1,3}

4
Não importa com o bash. Importa com peixes.
Charles Duffy #

1
Eu substituir " are interchangeable"com " are interchangeable in some shells, not in all of them. ALWAYS use the single quotes to make sure they get passed as-is to the find command"(bons hábitos começa por ter certeza que você use o caminho correto, mesmo se acontecer de você (sempre) estar em um sistema que permite a uma ambígua?)
Olivier Dulac

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 cadeia incorporada de ser substituída por outra coisa, por exemplo:

  • 'a b' é um parâmetro único de três caracteres, sem as aspas que seriam dois parâmetros de caracteres únicos
  • '$b' é a 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 estiver definido
  • '!!' são pontos de exclamação literais enquanto não estão entre aspas e com algumas conchas interativas, eles se expandem para o último comando colocado na história
  • '*' é um asterisco literário, 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 as conchas tradicionais ( sh(Bourne), ksh, bash, ash, dash, zsh, csh, tcsh) expandir {}para outra coisa, as aspas não são necessários.

No entanto, existe um shell exótico, chamado fish, que se expande {}como uma string vazia, 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 finddocumentação do GNU sugere proteção {}contra interpretação com aspas ou barras invertidas.


9

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

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

Observe que os colchetes estão entre aspas simples para protegê-los da interpretação como pontuação do script de shell.

Eu acho que os autores da página de manual do GNU estão errando por precaução, mas observo que nem todos os exemplos em sua página de manual citam os chavetas. Estes exemplos do GNU oficial encontram documentação também omitem a citação.

Nos exemplos da especificação POSIX / Single UNIX, os colchetes não são citados quando usados ​​com a -execopção

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

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

Finalmente, eu tentei correr find -exec ls -l {} \;em sh, dashe tcsh, mas nenhuma dessas conchas expandiu o {}em qualquer outra coisa. Como outros já apontaram, o fishshell trata {}especialmente, mas não é um shell POSIX (que seus criadores e usuários consideram uma vantagem). Não faz mal citar os aparelhos, mas os datilógrafos preguiçosos que não usam a casca de peixe não devem se sentir culpados por omiti-los.


eles não estão errando, eles estão tentando garantir que as pessoas usem a maneira correta (ou seja, use em '{}'vez de {}) para que seu shell envie {}para o comando find sem interpretá-lo (como mencionado acima por Charles-Duffy, se você usar peixe , ele irá interpretar, {}mas não '{}', então você precisa usá-lo nesse shell (e em vários outros!). Portanto, sempre use '{}'para evitar ser mordido pela ambiguidade de{}
Olivier Dulac

6

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

Rode isto

echo '{}'

e isto.

echo {}

Se eles produzem a mesma saída, a resposta para o seu shell é sim. Como outros observaram, será pelo menos sim na festança e não no peixe. A saída é para o que você deve consultar a página de manual de um determinado comando.


Se você quiser se dar bem, pode até prefixar echouma linha de comando inteira, para ver o comando real , com todos os seus argumentos, que seu shell realmente chamaria. Cuidado, porém, que a lista que compreende o comando mais argumentos é uma verdadeira matriz de seqüências de caracteres, cada uma possivelmente vazia ou com espaço em branco, mas o eco a imprime ambiguamente como uma lista separada por espaço.

Como pode ser verificado com este comando de eco um pouco mais detalhado (mostrando argumentos citados por guillemet),

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

digitando isso 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 em peixes:

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

Como um conselho geral, nunca é demais citar.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.