Existe uma maneira de forçar o gzip a não sobrescrever arquivos em conflito?

17

Estou escrevendo um script no qual estou compactando arquivos.

Existe a possibilidade de eu poder compactar um arquivo, criar um arquivo com o mesmo nome e tentar compactá-lo também, por exemplo

$ ls -l archive/
total 4
-rw-r--r-- 1 xyzzy xyzzy  0 Apr 16 11:29 foo
-rw-r--r-- 1 xyzzy xyzzy 24 Apr 16 11:29 foo.gz

$ gzip archive/foo
gzip: archive/foo.gz already exists; do you wish to overwrite (y or n)? n   
    not overwritten

Ao usar gzip --force, posso forçar o gzip a sobrescrever foo.gz, mas nesse caso, acho que há uma boa chance de que eu possa perder dados se sobrescrever foo.gz. Não parece haver uma opção de linha de comando para forçar o gzip a deixar os .gzarquivos em paz ... uma versão não interativa de pressionar 'n' no prompt.

Eu tentei gzip --noforcee gzip --no-force, esperando que isso seguisse o padrão de opções do GNU, mas nenhum deles funcionou.

Existe uma solução alternativa direta para isso?

Editar:

Acontece que essa é uma das vezes que vale a pena ler a página de informações em vez da página de manual.

Na página de informações:

`--force'
`-f'
     Force compression or decompression even if the file has multiple
     links or the corresponding file already exists, or if the
     compressed data is read from or written to a terminal.  If the
     input data is not in a format recognized by `gzip', and if the
     option `--stdout' is also given, copy the input data without
     change to the standard output: let `zcat' behave as `cat'.  If
     `-f' is not given, and when not running in the background, `gzip'
     prompts to verify whether an existing file should be overwritten.

Faltava o texto na página de manual e quando não estava em execução em segundo plano

Quando executado em segundo plano, o gzip não será solicitado e não será substituído, a menos que a -fopção seja invocada.

Barton Chittenden
fonte
3
Não tenho certeza de como o gzip verifica se está em segundo plano, mas adicionar '&' no bash no sistema em que estou trabalhando não o faz. Sendo do outro lado de um tubo parece funcionar, embora, por isso, em vez de: find ./ ! -name "*gz" -exec gzip {} \; & isso funciona: find ./ ! -name "*gz" -print0 | xargs -0 -n 1 -t gzip relatórios gzip: gzip: ./2012-July.txt.gz already exists; not overwritten
Bill McGonigle
1
@BillMcGonigle Seu comentário deve ser A resposta!
23917 Rockallite

Respostas:

9

Percebi que a melhor maneira de evitar o efeito indesejado é não pedir ao programa para executar o efeito indesejado. Ou seja, simplesmente não diga para compactar um arquivo se o arquivo já estiver presente na forma compactada.

por exemplo:

if [ ! -f "$file.gz" ]; then 
    gzip "$file"; 
else 
    echo "skipping $file"
fi

ou menor (execute truese houver um arquivo.gz, comprima o arquivo de outra forma)

[ -f "$file.gz" ] && echo "skipping $file" || gzip "$file"    
Ярослав Рахматуллин
fonte
Infelizmente, isso está sendo executado como um comando do sistema dentro de um script perl (uma longa história sobre por que não estamos usando algo como IO :: Compress :: Gzip, confie em mim, pensei nisso). O próprio comando de compactação é armazenado em um arquivo de configuração. Seu último comando parece próximo ao que eu preciso, mas acho que encontrei algo que atenderá às minhas necessidades um pouco melhor. Vou aceitar sua resposta, porque é uma solução geral melhor que a minha, mas veja abaixo o que realmente vou usar.
Barton Chittenden
Você pode cutucar um arquivo no Perl ...
Ярослав Рахматуллин
1
Não estou claro o que você quer dizer com poke a file.
Barton Chittenden
A falta de associação / uso da imagem nas comunicações cotidianas no inglês americano me surpreende toda vez :) Deixe-me tentar explicar. Conjure a imagem de uma criança cutucando um corvo morto com um graveto para ver se está vivo ou não. Picar é usado para pesquisar atributos aqui. Da mesma forma, cutucar um arquivo significaria verificar algo sobre ele, como se ele estivesse presente. De qualquer forma, eu sinto o ato de picar deve, no mínimo, significa "atingir contato com um objeto exterior" , e que é o suficiente para dizer "obter algumas informações sobre um arquivo" com uma imagem, em vez de ortografia-lo para fora.
Você está em
"cutucar" geralmente é uma gíria de hacker para definir um local de memória. Veja: en.wikipedia.org/wiki/PEEK_and_POKE#Generic_usage_of_.22POKE.22
Bill McGonigle
12

A coisa mais próxima que eu poderia encontrar de um único comando é o seguinte:

yes n | gzip archive/foo

O yescomando imprime yseguido de um avanço de linha para stdout até receber um sinal. Se houver um argumento, ele será impresso em vez de y. Nesse caso, ele imprime naté o gzip sair, fechando o tubo.

É o equivalente a entrar nrepetidamente no teclado; isso responderá automaticamente à perguntagzip: archive/foo.gz already exists; do you wish to overwrite (y or n)?

Em geral, acho que é melhor não tentar compactar os arquivos se o arquivo compactado em gzip existir; minha solução é mais ruidosa, mas atende às minhas necessidades particulares de substituição substituta do gzipcomando, em um arquivo de configuração.

Barton Chittenden
fonte
1
Outro incômodo com isto é que gzipsaídas2
Steven Penny