Um -execcomando 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 -execcomando, é 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 ande 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, truemas não para false.
Portanto, você pode usar duas instruções exec encadeadas com an -ande ela somente executará a segunda se a primeira tiver sido executada com êxito.