Gibt es eine Möglichkeit, gzip zu zwingen, Dateien bei Konflikten nicht zu überschreiben?

17

Ich schreibe ein Skript, in dem ich Dateien komprimiere.

Es besteht die Möglichkeit, dass ich eine Datei komprimiere, eine Datei mit demselben Namen erstelle und versuche, diese ebenfalls zu komprimieren, z

$ 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

Mithilfe von gzip --forcekann ich das Überschreiben von gzip erzwingen. foo.gzIn diesem Fall besteht jedoch eine gute Chance, dass beim Überschreiben Daten verloren gehen foo.gz. Es scheint keinen Befehlszeilenschalter zu geben, der gzip zwingt, .gzDateien in Ruhe zu lassen ... eine nicht interaktive Version des Drückens von 'n' an der Eingabeaufforderung.

Ich habe versucht gzip --noforceund gzip --no-forcegehofft, dass diese dem GNU-Optionsstandard folgen, aber keiner von beiden hat funktioniert.

Gibt es eine direkte Umgehung dafür?

Bearbeiten:

Es stellt sich heraus, dass es sich oft lohnt, die Infoseite und nicht die Manpage zu lesen.

Von der Infoseite:

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

Der Manpage fehlte der Text und wenn sie nicht im Hintergrund lief

Wenn gzip im Hintergrund ausgeführt wird, wird es nicht aufgefordert und nicht überschrieben, es sei denn, die -fOption wird aufgerufen.

Barton Chittenden
quelle
3
Ich bin nicht sicher, wie gzip den Hintergrund überprüft, aber das Hinzufügen von '&' in bash auf dem System, an dem ich arbeite, tut es nicht. Auf der anderen Seite einer Pipe zu sein, scheint jedoch zu funktionieren. Stattdessen find ./ ! -name "*gz" -exec gzip {} \; & funktioniert: find ./ ! -name "*gz" -print0 | xargs -0 -n 1 -t gzip gzip meldet: gzip: ./2012-July.txt.gz already exists; not overwritten
Bill McGonigle,
1
@ BillMcGonigle Ihr Kommentar sollte die Antwort sein!
Rockallite

Antworten:

9

Mir ist aufgefallen, dass der beste Weg, den unerwünschten Effekt zu vermeiden, darin besteht , das Programm nicht aufzufordern, den unerwünschten Effekt auszuführen. Das heißt, sagen Sie ihm einfach nicht, dass eine Datei komprimiert werden soll, wenn die Datei bereits in komprimierter Form vorliegt.

z.B:

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

oder kürzer (ausführen, truewenn es eine file.gz gibt, Datei andernfalls komprimieren)

[ -f "$file.gz" ] && echo "skipping $file" || gzip "$file"    
Ярослав Рахматуллин
quelle
Leider wird dies als Systembefehl in einem Perl-Skript ausgeführt (lange Geschichte darüber, warum wir nicht so etwas wie IO :: Compress :: Gzip verwenden, vertrau mir, ich habe darüber nachgedacht). Der Komprimierungsbefehl selbst wird in einer Konfigurationsdatei gespeichert. Ihr letzterer Befehl kommt dem, was ich brauche, sehr nahe, aber ich glaube, ich habe etwas gefunden, das meinen Bedürfnissen etwas besser entspricht. Ich werde Ihre Antwort akzeptieren, weil es eine bessere allgemeine Lösung als meine ist, aber siehe unten, was ich tatsächlich verwenden werde.
Barton Chittenden
Sie können eine Datei in Perl
stecken
1
Mir ist nicht klar, was Sie damit meinen poke a file.
Barton Chittenden
Die mangelnde Assoziation / Bildnutzung in der alltäglichen Kommunikation in amerikanischem Englisch überrascht mich jedes Mal :) Lassen Sie mich versuchen und erklären. Beschwöre das Bild eines Kindes, das eine tote Krähe mit einem Stock stößt, um zu sehen, ob sie lebt oder nicht. Das Stoßen wird verwendet, um hier nach Attributen zu suchen . In ähnlicher Weise würde das Stöbern in einer Datei bedeuten, etwas darüber zu überprüfen, zum Beispiel, ob es überhaupt vorhanden ist. Ich bin jedenfalls der Meinung , dass das Anstoßen mindestens "Kontakt mit einem äußeren Objekt herstellen" bedeutet , und das ist genug, um mit einem Bild "Informationen über eine Datei zu erhalten" , anstatt es auszudrücken.
Ярослав Рахматуллин
"Poke" ist oft Hacker-Slang, um einen Speicherort festzulegen. Siehe: en.wikipedia.org/wiki/PEEK_and_POKE#Generic_usage_of_.22POKE.22
Bill McGonigle
12

Die nächste Sache, die ich zu einem einzelnen Befehl finden konnte, ist die folgende:

yes n | gzip archive/foo

Der yesBefehl wird gedruckt, ygefolgt von einem Zeilenvorschub auf stdout, bis ein Signal empfangen wird. Wenn es ein Argument gibt, wird dieses anstelle von ausgegeben y. In diesem Fall wird gedruckt, nbis gzip beendet wird, wodurch die Pipe geschlossen wird.

Dies entspricht der nwiederholten Eingabe über die Tastatur. Dadurch wird die Frage automatisch beantwortetgzip: archive/foo.gz already exists; do you wish to overwrite (y or n)?

Im Allgemeinen denke ich, dass es besser ist, nicht zu versuchen, die Dateien zu komprimieren, wenn die entsprechende komprimierte Datei vorhanden ist. Meine Lösung ist geräuschvoller, entspricht jedoch meinen besonderen Anforderungen an einen Drop-In-Ersatz für den gzipBefehl, der in einer Konfigurationsdatei gespeichert ist.

Barton Chittenden
quelle
1
ein weiteres Ärgernis dabei ist , dass gzipAusfahrten2
Steven Penny