Problema com espaços quando usado no comando find

3

Estou tentando colocar um arquivo zip com o conteúdo do diretório em cada diretório que não contém nenhum subdiretório.

O comando a seguir funciona se não houver espaço em nomes de domínio e / ou nomes de arquivos, mas falhará se houver:

find pictures/ -type d -links 2 -execdir sh -c "pwd; echo '{}'; zip -v '{}/{}.zip' '{}/*' -x \*.zip -x \*.id" \;

Eu não entendo por que ele falha desde que eu citei o '{}' como de costume. Também tentei "{}". Dito de forma diferente, deve criar A / B / C / C.zip com o conteúdo de A / B / C / *. Se houver espaços em 'C', obtenho:

zip warning: name not matched: ./C/*
zip error: Nothing to do! (./C/./C.zip)
    
por dargaud 18.07.2016 / 16:50

2 respostas

2

Com sua versão de find , o {} na string é substituído pelo nome do arquivo. É quase sempre um erro usar {} como parte de uma string, porque o nome do arquivo é inserido assim. Aqui, o nome do arquivo é usado como um fragmento de script de shell. Se houver um diretório chamado a'$(touch wibble)' , seu comando executará o código do shell

pwd; echo 'a'$(touch wibble)''; zip -v 'a'$(touch wibble)'/a'$(touch wibble)'.zip' 'a'$(touch wibble)'/*' -x \*.zip -x \*.id"'

Observe como isso executa o comando touch wibble (quatro vezes).

Você precisa passar o nome do arquivo como um argumento para o snippet do shell. Essa é a única maneira de usar find -exec ou find -execdir para chamar um shell de forma confiável (exceto nos casos em que os nomes de arquivos são restritos para não ter caracteres especiais, incluindo espaços). O primeiro argumento após sh -c SCRIPT pode ser acessado a partir do script como "$0" .

Além disso, zip não aceita curingas em sua lista de arquivos para zip, portanto, o curinga deve ser deixado sem aspas, para ser expandido pelo shell.

find pictures/ -type d -links 2 -execdir sh -c 'pwd; echo "$0"; zip -v "$0/$0.zip" "$0/"* -x \*.zip -x \*.id' {} \;
    
por 19.07.2016 / 02:44
2

Altere assim:

find pictures -type d -links 2 -execdir \
    sh -c 'pwd; echo "$1"; zip -vr "$1/$1.zip" "$1" -x \*.zip -x \*.id' sh {} \;
    
por 18.07.2016 / 17:35