Überprüfen Sie, ob eine Datei oder ein Ordner bereits gepatcht wurde

22

Ist es möglich zu wissen, ob eine Datei bereits gepatcht wurde, bevor der Patch angewendet wird?

Muss ich das in einem Skript machen, irgendwelche Gedanken?

Gänseblümchen
quelle
1
Mit welchem ​​Programm patchen Sie sie? Was für Patches?
Omnifarious
1
Der Schlüssel ist "-R" - unix.stackexchange.com/a/86872/6622
poige

Antworten:

20

Ja, nur patchmit der --dry-runOption ausführen , es würde entweder fehlschlagen oder erfolgreich sein, was anhand des Beendigungsstatus festgestellt werden kann.

Aber auf häufigere (und fehleranfällige) Weise müssen Sie es wahrscheinlich mit der -ROption ausführen, die "Umkehren" bedeutet, da es nur dann als "angewendet" angesehen werden kann, wenn es in der Lage ist, den gesamten Patch zurückzusetzen. Andernfalls (ohne '-R') könnte es fehlschlagen, nur weil einige Teile der Originaldatei geändert wurden. Unten ist ein einfaches Beispiel:

if ! patch -R -p0 -s -f --dry-run <patchfile; then
  patch -p0 <patchfile
fi

(Im obigen Snippet ziehen Sie es sogar vor, die Stille zu aktivieren, indem Sie patchstdout und stderr auf vollständig umleiten. /dev/null)

Poige
quelle
1
Das funktioniert bei mir nicht. Wenn ich diesen Befehl ausführe und der Patch nicht angewendet wurde, wird gefragt, ob der Patch im interaktiven Modus rückgängig gemacht werden soll. Wenn ich den Batch-Modus verwende, wird der umgekehrte Vorgang ignoriert und der Patch angewendet, wobei 0 zurückgegeben wird.
Synack
1
Hey, versuche es -sfmit patch(kann geschrieben werden als patch -Rsfp0 --dry-run)
poige 20.10.17
1
@synack ist es ok gelaufen?
Poige
16

Nur für den Fall, dass es jemandem hilft, wenn Sie ein Bash-Skript verwenden, funktioniert das von Omnifarious gegebene Beispiel nicht. In der Bash ist der Exit-Status eines erfolgreichen Befehls 0

Also würde folgendes funktionieren:

patch -p0 -N --dry-run --silent < patchfile 2>/dev/null
#If the patch has not been applied then the $? which is the exit status 
#for last command would have a success status code = 0
if [ $? -eq 0 ];
then
    #apply the patch
    patch -p0 -N < patchfile
fi
DivKis01
quelle
Die Überprüfung sollte 1stattdessen erfolgen 0:if [ $? -eq 1 ]
Crisson 20.12.15
2
Nein, 0 ist richtig. Der Patch wird mit einem Wert ungleich Null beendet, wenn der Probelauf aus irgendeinem Grund fehlschlägt. In diesem Fall sollte der Patch nicht angewendet werden.
Fls'Zen
Mein Skript war in der Bash korrekt. Bash betrachtet einen Exit-Code von 0 truefür die Zwecke von if. Gerade weil die meisten Befehle einen Exit-Code von 0 verwenden, um den Erfolg anzuzeigen.
Omnifarious
2

Angenommen, Sie verwenden das patchDienstprogramm und jede zu patchende Datei verfügt über einen eigenen Patch:

if patch <options> -N --dry-run --silent <patchfile 2>/dev/null; then
    echo The file has not had the patch applied,
    echo and the patch will apply cleanly.
else
    echo The file may not have had the patch applied.
    echo Or maybe the patch doesn't apply to the file.
fi
Alleswissend
quelle
Wenn Sie die Dateien zuvor gepatcht haben und wissen möchten, ob sie eine bestimmte Datei berührt haben, können Sie die erste Patch-Runde mit der -BOption ausführen , durch die eine Sicherung durchgeführt wird. Dann prüfen Sie, ob die Sicherung vorhanden ist.
Peterph
8
Könnten Sie etwas näher darauf eingehen, warum Sie sich für nohupdiesen ifFall entschieden haben?
Zrajm
@zrajm - Ich kann mich nicht erinnern, warum ich das getan habe. Und als ich bemerkte (aufgrund eines Antrags auf Genehmigung einer Bearbeitung), dass es dort war, war es so lange her, dass es keine Chance mehr gibt, dass ich den Grund jemals wiederfinden werde. Es erscheint mir jetzt ziemlich sinnlos, es anzusehen.
Omnifarious
0

In meinem Fall wollte ich diese Überprüfung durchführen, damit beim Ausführen des Patch-Befehls nicht ein interaktives Terminal gefragt wird, was zu tun ist (insbesondere für CI).

Es stellt sich heraus, dass Sie, wenn Sie nur das benötigen, auch das --forwardArgument verwenden können und den Patch überspringen, wenn er bereits angewendet wurde!

maxime1992
quelle
0

Das hat bei mir funktioniert.

"scripts": {
    "symfony-scripts": [
        "patch -N --silent -p0 < patches/vendor/somefile.js.patch &2>/dev/null",
        "Incenteev\\ParameterHandler\\ScriptHandler::buildParameters",
neisantos
quelle