Um -exec
comando deve ser finalizado com a ;
(portanto, você geralmente precisa digitar \;
ou ';'
evitar a interpretação pelo shell) ou a +
. A diferença é que ;
, com , o comando é chamado uma vez por arquivo, com +
, é chamado apenas o menor número de vezes possível (geralmente uma vez, mas existe um comprimento máximo para uma linha de comando, portanto pode ser dividido) com todos os nomes de arquivos . Veja este exemplo:
$ cat /tmp/echoargs
#!/bin/sh
echo $1 - $2 - $3
$ find /tmp/foo -exec /tmp/echoargs {} \;
/tmp/foo - -
/tmp/foo/one - -
/tmp/foo/two - -
$ find /tmp/foo -exec /tmp/echoargs {} +
/tmp/foo - /tmp/foo/one - /tmp/foo/two
Seu comando possui dois erros:
Primeiro, você usa {};
, mas ;
deve ser um parâmetro próprio.
Segundo, o comando termina no &&
. Você especificou "executar localização e, se isso tiver sido bem-sucedido, remova o arquivo chamado {};
.". Se você deseja usar itens de shell no -exec
comando, é necessário executá-lo explicitamente em um shell, como -exec sh -c 'ffmpeg ... && rm'
.
No entanto, você não deve adicionar o {} dentro do comando bash, ele produzirá problemas quando houver caracteres especiais. Em vez disso, você pode passar parâmetros adicionais para o shell depois -c command_string
(consulte man sh
):
$ ls
$(echo damn.)
$ find * -exec sh -c 'echo "{}"' \;
damn.
$ find * -exec sh -c 'echo "$1"' - {} \;
$(echo damn.)
Você vê que a $
coisa é avaliada pelo shell no primeiro exemplo. Imagine que havia um arquivo chamado $(rm -rf /)
:-)
(Observação: -
não é necessária, mas a primeira variável após o comando ser atribuída à variável $0
, que é uma variável especial que normalmente contém o nome do programa que está sendo executado e a configuração para um parâmetro é um pouco impura, embora tenha vencido provavelmente não causará nenhum dano aqui, portanto, definimos isso apenas para -
começar $1
.)
Portanto, seu comando pode ser algo como
find -exec bash -c 'ffmpeg -i "$1" -sameq "$1".mp3 && rm "$1".mp3' - {} \;
Mas há uma maneira melhor. encontre suportes and
e or
, para que você possa fazer coisas assim find -name foo -or -name bar
. Mas isso também funciona com -exec
, que avalia como true se o comando sair com êxito e false se não. Veja este exemplo:
$ ls
false true
$ find * -exec {} \; -and -print
true
Ele somente executa a impressão se o comando foi bem-sucedido, o que foi feito, true
mas não para false
.
Portanto, você pode usar duas instruções exec encadeadas com an -and
e ela somente executará a segunda se a primeira tiver sido executada com êxito.
-and
e-or
não são portáteis. O POSIX especifica-a
e-o
, e de fato-a
é sempre assumido (portanto, não é necessário)."\;"
não funciona, mas" \;"
fazEu descobri agora. Quando você precisa executar dois comandos no exec em uma descoberta, é necessário ter dois execs separados. Isso finalmente funcionou para mim.
fonte
echo
antes dos comandos e veja o que ele faz.echo
é bastante confiável - você não pode dizer a diferença entreecho "one argument"
eecho one argument
(a saída deste último é falsa, pois na verdade está passandoecho
dois argumentos completamente separados). É muito melhor fazer algo assim-exec bash -c 'printf "%q " "$@"' _ ffmpeg -i {} -sameq {}.mp3 \; -printf '\n'
, que imprimirá a saída de maneira a tornar os caracteres não imprimíveis visíveis, para que você possa detectar novas linhas do DOS e outras curiosidades.Tente colocar um espaço antes de cada \;
Trabalho:
Não funciona:
fonte
Apenas para sua informação:
Eu apenas tentei usar o comando "find -exec" em um sistema Cygwin (emulado UNIX no Windows) e parece que a barra invertida antes do ponto e vírgula deve ser removida:
find ./ -name "blabla" -exec wc -l {} ;
fonte
find /etc/nginx -name '*.conf' -exec echo {} ;
efind /etc/nginx -name '*.conf' -exec echo {}\;
deu o mesmo resultado. :({}
.Caso alguém veja "args -exec args" semelhantes nos scripts bash do Amazon Opsworks Chef, eu precisava adicionar outra barra invertida para escapar do \;
fonte
Além disso, se alguém tiver o argumento "find: missing to -exec", isso pode ajudar:
Em algumas conchas, você não precisa fazer a fuga, ou seja, não precisa do "\" na frente do ";".
fonte
;
não ser citado ou escapado aqui significa que pode ser consumido pelo shell, e não lido por elefind
. Além disso,-f
e- f
são duas coisas diferentes.Você precisa escapar, eu acho.
fonte
{} E && causarão problemas devido à expansão da linha de comando. Eu sugeriria tentar:
fonte
{}
variável para excluir o arquivo correto?{}
expande? A menos que contenha dois pontos ou vírgulas que permanecerão como estão.Você tem que colocar um espaço entre
{}
e\;
Portanto, o comando será como:
fonte
Se você ainda está recebendo "find: missing argument to -exec", tente agrupar o argumento execute entre aspas.
fonte