Existe-t-il un moyen de forcer gzip à ne pas écraser les fichiers en cas de conflit?

17

J'écris un script dans lequel je compresse des fichiers.

Il y a une possibilité que je puisse compresser un fichier, créer un fichier du même nom et essayer de le compresser également, par exemple

$ 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

En utilisant gzip --force, je peux forcer gzip à écraser foo.gz, mais dans ce cas, je pense qu'il y a de fortes chances que je puisse perdre des données si j'écrase foo.gz. Il ne semble pas y avoir de commutateur de ligne de commande pour forcer gzip à laisser les .gzfichiers seuls ... une version non interactive de la pression de 'n' à l'invite.

J'ai essayé gzip --noforceet gzip --no-force, en espérant que ceux-ci pourraient suivre la norme des options GNU, mais ni l'un ni l'autre n'a fonctionné.

Existe-t-il une solution simple à cela?

Éditer:

Il s'avère que c'est l'une des fois où il est payant de lire la page d'informations plutôt que la page de manuel.

Depuis la page info:

`--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.

Le texte manquait dans la page de manuel et lorsqu'elle n'était pas exécutée en arrière-plan

Lors de l'exécution en arrière-plan, gzip ne demandera pas et ne remplacera pas sauf si l' -foption est invoquée.

Barton Chittenden
la source
3
Je ne sais pas comment gzip vérifie s'il est en arrière-plan, mais l'ajout de '&' dans bash sur le système sur lequel je travaille ne le fait pas. Être de l'autre côté d'une pipe semble fonctionner, alors au lieu de: find ./ ! -name "*gz" -exec gzip {} \; & cela fonctionne: find ./ ! -name "*gz" -print0 | xargs -0 -n 1 -t gzip gzip rapporte: gzip: ./2012-July.txt.gz already exists; not overwritten
Bill McGonigle
1
@BillMcGonigle Votre commentaire devrait être LA réponse!
Rockallite

Réponses:

9

Il m'est apparu que la meilleure façon d'éviter l'effet indésirable est de ne pas demander au programme d'effectuer l'effet indésirable. Autrement dit, ne lui dites pas de compresser un fichier si le fichier est déjà présent sous forme compressée.

par exemple:

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

ou plus court (exécuter trues'il y a un fichier.gz, compresser le fichier sinon)

[ -f "$file.gz" ] && echo "skipping $file" || gzip "$file"    
Ярослав Рахматуллин
la source
Malheureusement, cela est exécuté comme une commande système dans un script perl (longue histoire sur la raison pour laquelle nous n'utilisons pas quelque chose comme IO :: Compress :: Gzip, croyez-moi, j'y ai pensé). La commande de compression elle-même est stockée dans un fichier de configuration. Votre dernière commande ressemble beaucoup à ce dont j'ai besoin, mais je pense que j'ai trouvé quelque chose qui répondra un peu mieux à mes besoins. Je vais accepter votre réponse, car c'est une meilleure solution générale que la mienne, mais voyez ci-dessous ce que je vais réellement utiliser.
Barton Chittenden du
Vous pouvez piquer un fichier en Perl ...
Ярослав Рахматуллин
1
Je ne sais pas ce que vous entendez par poke a file.
Barton Chittenden
Le manque d'association / utilisation d'image dans les communications quotidiennes en anglais américain me surprend à chaque fois :) Laissez-moi essayer d'expliquer. Imaginez une image d'un enfant qui pique un corbeau mort avec un bâton pour voir s'il est vivant ou non. Piquer est utilisé pour sonder les attributs ici. De même, piquer un fichier signifierait vérifier quelque chose à son sujet, comme s'il était présent. Quoi qu'il en soit, je pense que l'acte de piquer devrait à tout le moins signifier "atteindre le contact avec un objet extérieur" , et cela suffit pour dire "obtenir des informations sur un fichier" avec une image, au lieu de l'énoncer.
Ярослав Рахматуллин
"poke" est souvent un argot de pirate pour définir un emplacement de mémoire. Voir: en.wikipedia.org/wiki/PEEK_and_POKE#Generic_usage_of_.22POKE.22
Bill McGonigle
12

La chose la plus proche que j'ai pu trouver à une seule commande est la suivante:

yes n | gzip archive/foo

La yescommande imprime ysuivie d'un saut de ligne vers stdout jusqu'à ce qu'elle reçoive un signal. S'il a un argument, il l'imprimera au lieu de y. Dans ce cas, il imprime njusqu'à la sortie de gzip, fermant ainsi le tuyau.

C'est l'équivalent d'entrer nplusieurs fois sur le clavier; cela répondra automatiquement à la questiongzip: archive/foo.gz already exists; do you wish to overwrite (y or n)?

En général, je pense qu'il vaut mieux ne pas essayer de compresser les fichiers si le fichier gzippé correspondant existe; ma solution est plus bruyante, mais elle correspond à mes besoins particuliers pour un remplacement direct de la gzipcommande, assis dans un fichier de configuration.

Barton Chittenden
la source
1
une autre contrariété avec cela est que les gzipsorties2
Steven Penny