2016-05-08 16 views
1

Ich habe ein Skript, das nach Dateien eines bestimmten Typs in einem angegebenen Verzeichnis sucht und, wenn sie vorhanden sind, eine Datei mit den Basisnamen generiert, bevor ein erstellt wird tar.gz. Nach der Komprimierung überprüfe ich, ob der Tarball alle Dateien enthält, indem ich einen Diff-Check durchführe.Untersuchen eines Diff-Fehlers in einem Bash-Skript, wenn Variablen anstelle von fest codierten Dateinamen verwendet werden

Ich habe ein Paar Variablen erstellt, die die vorkomprimierte Dateiliste und die im Tarball gefundenen sind. Wenn ich eine wenn Anweisung einschließlich diff laufen der Variablen, erhalte ich diesen Fehler:

diff: missing operand after `/my/original/dir/filelist.txt' 
diff: Try `diff --help' for more information. 

Ich arbeitete dies um, indem sie die Dateien verweisen selbst, anstatt die angelegten Variablen. Wenn ich die if-Anweisung in einem separaten Bash-Skript ausführe, funktioniert es problemlos mit den Variablen, so dass ich völlig verloren bin, was mein Fehler in meinem größeren Skript ist. Im Folgenden stelle ich sowohl das Snippet aus dem großen Skript als auch die diff-Anweisung als eigenes Skript zur Verfügung.

Die if diff in seinem eigenen Skript:

#!/bin/sh 
filelist=(filelist.txt) 
tarfiles=(tarfiles.txt) 
#differences=$(diff filelist.txt tarfiles.txt) #Uncomment if below fails 
differences=$(diff $filelist $tarfiles) 
if $differences > /dev/null ; then 
    echo Same 
else 
    echo Different 
fi 

Die oben funktioniert gut.

einschließlich Nun ist diese am Ende meiner größeren Skript:

TARFILES=$(tar -tzf "$ARCHIVES/tarredfiles.tar.gz" | awk -F/ '{ if($NF != "") print $NF }' > $LOGS/tarfiles.txt) 

FILELIST=($LOGS/filelist.txt) 

#Check to see if it all worked 

DIFF=$(diff $FILELIST $TARFILES)  

cd $LOGS #I shouldn't need to do this but I do as a safety mechanism 

#if diff filelist.txt tarfiles.txt > /dev/null ; then 

if diff $FILELIST $TARFILES > /dev/null ; then 
    echo "Today's files have been archived and checked." 
else 
    echo "Some or none of today's files have been archived, check the logs to find the error." 
    echo (diff $TARFILES $FILELIST) > $LOGS/$(date '+%Y%m%d')errors.txt 

fi 

Ich habe versucht, die Variablen in „“ umschließt und es scheint keinen Unterschied zu machen.

+0

außerhalb Ihres Skripts, haben Sie ein kleines Testverzeichnis dafür erstellt? Haben Sie 'cat filelist.txt tarfiles.txt' gemacht und bestätigt (vorausgesetzt, dass die Dateien korrekt sind), dass diese Listen in der gleichen Sortierreihenfolge sind, dass das Format der Auflistung gleich ist, dass es keine führenden oder nachgestellten Leerzeichen gibt Linien? Zuletzt haben Sie sich die Ausgabe (aus der cmd-Zeile) von 'diff filelst.txt tarfiles.txt' angesehen? Während Ihr Code angemessen aussieht, wissen wir nicht genau, wie Ihr Fehler aussieht UND welche Tests Sie an Ihrem Projekt durchgeführt haben. Viel Glück.! – shellter

+0

Der Fehler msg 'fehlende Operand nach" /my/original/dir/filelist.txt "' zeigt an, dass die Variable für tarfiles nicht in der cmd Zeile erscheint. Verwenden Sie 'set -vx', um zu sehen, dass Code mit Zeilen ausgeführt wird, die mit' + 'beginnen, was anzeigt, dass der exakte Befehl mit allen Variablen ausgeführt wird, die auf ihre Werte erweitert sind. Es tut mir leid, aber ich habe verpasst, dass du deine Fehlermitteilungen klar beschrieben hast, aber das Bestätigen deiner Daten ist immer noch ein wichtiger Schritt. Viel Glück. – shellter

+0

Vielen Dank für die Tipps zur Verwendung von set-vx. Dies wird sehr nützlich für mich sein, wenn ich mehr Skripte schreibe. – FocusedEnergy

Antwort

2

Die Art und Weise, wie Sie TARFILES ausfüllen, führt dazu, dass sie leer ist. Was möchten Sie in der Variable speichern?

Diese Linie

TARFILES=$(tar -tzf "$ARCHIVES/tarredfiles.tar.gz" | awk -F/ '{ if($NF != "") print $NF }' > $LOGS/tarfiles.txt) 

führt die folgenden

  • Extrakte eine Liste der Dateinamen (-t) aus der komprimierten (-z) tar-Datei (-f) Schritte tarredfiles.tar.gz im Verzeichnis mit dem Namen genannt durch die $ARCHIVES Variablen

  • sendet (Rohre), die Liste der Dateinamen in awk wo Sie die letzte Komponente des Dateinamens drucken, das ist das letzte Feld ($NF) jeder Leitung, wenn sie durch / (-F/)

  • Sendet (Umleitungen), die alle, die geteilt ist Ausgabe in die Protokolldatei $LOGS/tarfiles.txt

  • Erfasst jeden anderen Ausgang (von dem es keine gibt!) und speichert ihn in der Variablen TARFILES.

Also, die VariableTARFILES ist immer leer, aber die Dateitarfiles.txt hat Inhalt drin.

Es scheint, dass Sie die diff möchten die Inhalte von tarfiles.txt mit dem Inhalt von filelist.txt zu vergleichen, aber Sie versuchen, Ihre Variablen in einer Art und Weise zu verwenden, die mit dem nicht wirklich kompatibel ist.

ein Ausdruck der Form:

TARFILES=$(command goes here) 

fängt die Ausgang dieses Befehls.

Und

TARFILES=$(command goes here > some-file.txt) 

sendet die Ausgabe des Befehls in die Datei, und fängt dann nichts.

Was Sie wollen, ist so etwas wie:

TARFILES=some-file.txt 
command goes here > $TARFILES 

, die die Variable gesetzt wird der Name Ihrer Datei zu sein, und dann einen Befehl ausführen, der Inhalt in diese Datei setzen.

Also, speziell:

TARFILES=$LOGS/tarfiles.txt 
tar -tzf "$ARCHIVES/tarredfiles.tar.gz" | awk -F/ '{ if($NF != "") print $NF }' > $TARFILES 

Wenn Arbeits Shell Skripte wird, ist es sehr häufig verwendete Befehle ausgeführt werden, die Ausgabe zu erzeugen, die in Dateien geht, usw. Eine Sache, die Sie brauchen etwa in der wirklich klar zu sein Logik Ihres Skripts ist, wenn Sie möchten, dass Ihre Variablen tatsächlichen Inhalt enthalten (dh die Ausgabe eines Befehls), und wenn Sie möchten, dass sie Dateinamen enthalten.

In Ihrem Fall möchten Sie diff auf 2 Dateien ("tarfiles" und "filelist") ausführen, die eine Liste von Dateinamen enthalten, so dass es ein bisschen mehr zu verfolgen, aber im Wesentlichen Sie wollen um "tarfiles" mit der Ausgabe eines Befehls zu füllen, und führe dann ein diff aus, wo du die 2 Dateinamen "tarfiles" und "filelist" übergibst. Daher möchten Sie nie $(...) verwenden, um tarfiles.txt zu bevölkern, da Sie auf diese Weise die Ausgabe eines Befehls in eine Variable erfassen und was Sie versuchen, einen Dateinamen in Ihrer Variablen zu speichern.

+0

Vielen Dank für Ihre Suche. tarfiles.txt wird mit '>' gefüllt und ich kann dies überprüfen, indem ich das erste Skript nach der Generierung im langen Skript ausfühle. Ich kann auch auskommentieren "' wenn diff filelist.txt tarfiles.txt>/dev/null; dann 'mit Erfolg. Nur wenn ich versuche, $ FILELIST zu verwenden, scheitert diff mit' diff: fehlender Operand nach '/.../logs/filelist.txt'' Ich habe deinen Vorschlag mit tee | versucht, aber nur die erste Datei aus dem Tarball wurde zurückgegeben mit: 'diff: extra operand' firstfile.txt'' – FocusedEnergy

+0

Meine Frage * Was ist es, was du versuchst? Speichern in der Variablen? * ist wichtig, und Sie haben es nicht beantwortet. Ich kann nicht genau sagen, was Sie hier erreichen wollen. Ich kann sehen, wo die Dinge schief laufen - es ist klar, dass die Schritte, die Sie unternehmen wird kein funktionierendes Ergebnis liefern - aber ich kann Ihnen keinen Rat geben, wie Sie es beheben können, ohne zu verstehen, was Sie tun wollen.Von Ihrem Kommentar aus nehme ich an, dass Sie wollen, dass 'TARFILES' auf die Datei verweist 'tarfiles.txt' Wenn Sie das wollen, werde ich meine Antwort aktualisieren – Tim

+0

Nochmals vielen Dank $ TARFILES gibt den Inhalt der Datei tarfiles.txt zurück, die eine Liste von f ist ilenames (nur) in einem zuvor generierten Tarball und dies wird mit $ FILELIST verglichen, das filelist.txt referenziert und es enthält die Dateinamen von Dateien, die in den Tarball komprimiert worden sein sollen. Also habe ich ein Verzeichnis von Dateien, listet sie auf und schreibe in eine Datei. Ich tar die Dateien dann und ich versuche zu überprüfen, ob alle Dateien komprimiert wurden. Ich suche im Tarball, speichere es und versuche dann diff zu starten. Wenn ich explizit auf die Dateien referenziere, funktioniert es oder wenn ich das diff in einem anderen Skript ausführe. – FocusedEnergy