substitua 'while' por uma função mais adequada, portanto, o loop esperaria que cada processo terminasse

2

Eu tenho um script bash que procura arquivos recursivamente em várias subpastas e, em seguida, usa ffmpeg para cada arquivo. no debug, funciona muito bem se eu usar echo ffmpeg , mas o problema é que, no trabalho real, onde realmente é necessário usar ffmpeg e esperar meia hora para cada vídeo, o script bash não pode executar com êxito o ffmpeg para cada arquivo

Meu snippet está abaixo:

find * \( -name '*.mkv' -o -name '*avi' -o -name '*mp4' -o -name '*flv' -o -name '*ogg' -o -name '*mov' ! -name '*-[900p-by-ZiriusPH].mkv' \) -print |
while IFS= read file    ## IFS= prevents "read" stripping whitespace
do
    ffmpeg -i "$file" "$target" && rm -rf "$file"
done

a coisa é, porque o ffmpeg demora muito para responder, e while continuaria listando e executando. Então, estou esperando o que posso fazer para garantir que o loop seja processado somente após o done ter terminado?

Alguém pode me ajudar? Obrigado!

Geez, eu não sei porque foi marcado como possível duplicado com outra pergunta minha: Convertendo 'para file em' to 'find' para que meu script possa se aplicar recursivamente

Estou pedindo uma ação de loop que permita que meu script espere que cada função dentro do loop termine antes de iterar para o próximo objeto. Está muito longe de perguntar como find arquivos recursivamente. Obrigado!

    
por The Wolf 16.04.2015 / 20:29

2 respostas

4

Em vez de encontrar o encanamento, você pode passar por um arquivo intermediário. Isso garantirá que a etapa de descoberta e etapa de looping acontece em seqüência, sem sobreposição. Algo como o seguinte (alterei sua expressão para brevidade):

find \( -name '*.mkv' -o -name '*avi' \) >files
<files while IFS= read file
do
    ffmpeg -i "$file" "$target" && rm -f "$file"
done

Note que isso ainda não é completamente seguro; usar find -exec seria mais simples se seus requisitos não incluíssem find estritamente antes da primeira chamada para ffmpeg . Com esse requisito, usar find -print0 junto com xargs ou GNU parallel poderia fazer o trabalho.

    
por 16.04.2015 / 21:06
1

O motivo pelo qual o código não está sendo executado corretamente é a incompatibilidade dos grupos AND e OR no comando find inicial:

find * \( -name '*.mkv' -o -name '*avi' -o -name '*mp4' -o -name '*flv' -o -name '*ogg' -o -name '*mov' ! -name '*-[900p-by-ZiriusPH].mkv' \) -print

A ligação para os parâmetros é para imprimir os arquivos correspondidos por

  • Nome * .mkv
  • OU Nome * .avi
  • OU Nome * mp4
  • OU Nome * flv
  • OU Nome * .ogg
  • OU Nome * .ogg
  • OR (Nome * .mov E Nome NÃO * - [900p-by-ZiriusPH] .mkv)

A última condição será verdadeira para muitos arquivos, que eu suspeito que não é o que você queria. Se você mover a condição AND NOT para fora das condições OR agrupadas, verá que ela funciona conforme o esperado.

find * \( -name '*.mkv' -o -name '*avi' -o -name '*mp4' -o -name '*flv' -o -name '*ogg' -o -name '*mov' \) ! -name '*-[900p-by-ZiriusPH].mkv' -print
    
por 16.04.2015 / 21:59