Alguns princípios gerais de programação de shell:
- Sempre coloque aspas duplas em torno das substituições de variáveis (a menos que você saiba que precisa do comportamento sem aspas).
"$foo"
significa o valor da variávelfoo
, mas$foo
das cotas externas sofre processamento adicional . - O mesmo vale para substituições de comandos:
"$(foo)"
. -
while read i; do …
remove espaços em branco iniciais e finais e barras invertidas. Usewhile IFS= read pr i; do …
para linhas de processo exatamente .
find $filePath type -d
apenas lista diretórios.
Piping find
into while read
não é a maneira mais fácil ou robusta de executar um comando shell para cada arquivo. Use a ação -exec
em find
para processar arquivos de maneira robusta sem problemas com nomes de arquivos que contenham caracteres especiais, como espaço em branco. Se você precisar de mais de um comando, invoque sh
; para processar um arquivo de cada vez:
find … -exec sh -c 'command1 "$0"; command2 "$0"' {} \;
Para acelerar um pouco as coisas, você pode usar um idioma mais complexo que agrupa arquivos para reduzir o número de sucessivas invocações de shell:
find … -exec sh -c 'for x; do command1 "$x"; command2 "$x"; done' _ {} +
Todas as verificações no início do seu script são inúteis ou praticamente inúteis. Você não se importa se o argumento é um link simbólico, por exemplo, e sua mensagem de erro nesse caso está incorreta.
Eu assumo que seu script é chamado com dois argumentos, o diretório de origem e o diretório de destino. Você pode usar mkdir -p
para criar diretórios de destino conforme necessário. Isso ajuda a executar find
no diretório atual, para evitar a manipulação do nome do arquivo para calcular os caminhos de destino.
Chame file
para verificar o tipo de um arquivo com base em seu conteúdo. Você pode querer ajustar os formatos de arquivo aceitos.
cd "$1" || exit
find . -type f -exec sh -c '
# $0 = target directory; $1 = source file
case "$(file "$1");" in
video/x-flv\;*)
mkdir -p "$0/${1%/*}" # create target subdirectory if needed
cp -p "$1" "$0/$1" # copy the file under the same relative path
esac
' "$2" {} \;