Wir haben diesen Code in einem Shell-Skript, das die Ausgabe für das Protokollieren durch Apache weiterleitet.
declare -a values=( $taintRequestVals )
for item in ${!values[@]}
do
cat $apacheLog | sed "s/${values[$item]}=[^&\t\n]*/${values[$item]}=***/g" | /bin/grep ${values[$item]}=
done
Es ist jedoch äußerst ineffizient. Innerhalb von Sekunden access.log
vervierfachte sich die Anzahl der Einträge exponentiell, bis der Root-Slice des Servers voll war. Wir suchen nach einer besseren Möglichkeit, vertrauliche Daten wie Passwörter zu verschleiern, während Apache in schreibt access.log
.
Antwort1
Das Problem dabei ist, dass Sie gleichzeitig aus dem Apache-Protokoll lesen und darin schreiben. Was auch immer Sie dem Protokoll hinzugefügt haben, gelangt durch den cat
Aufruf auch zurück in die Pipeline (kein Wortspiel beabsichtigt :)). Dadurch entsteht eine unangenehme positive Rückkopplungsschleife, die so lange weiterläuft, bis Ihr Dateisystem voll ist. Die Antwort aufdiese FrageVielleicht interessiert es Sie, warum das passiert.
Wie sollten Sie dann vorgehen? Eine naive Lösung wäre, die Datei an Ort und Stelle wie folgt zu ändern:
for item in ${!values[@]};do
sed -i "..." "$apacheLog" #cat isn't needed here
done
und leiten Sie die Ausgabe nicht weiter: das Skript selbst ändert die Dateivor Ort. Lesen Sie auch die Antwort von Terdon, um zu erfahren, wie Sie den sed
Aufruf zur Verbesserung der Effizienz nur einmal (ohne Schleife) tätigen können.
Das Problem bei diesem Ansatz ist jedoch, dass ein aktiver Apache-Server wahrscheinlich Dinge in die Datei protokolliert, während Sie daran arbeiten, und dass dann seltsame Dinge passieren können. Eine bessere Lösung wäre, in der Apache-Dokumentation nach Möglichkeiten zu suchen, vertrauliche Informationen aus den Protokollen herauszuhalten.
Übrigens bereinigen Sie mit Ihrem Vorgehen nicht einmal die Protokolle: Die bereinigten Zeilen werden wieder an die (immer noch fehlerhafte) Protokolldatei angehängt.
Antwort2
So wie es aussieht, gibt es verschiedene Verbesserungen, die Sie vornehmen können. Erstens und am wenigsten wichtig: Sie haben einesinnloser Einsatz der Katze. Viel wichtiger ist, dass Sie es sed
mehrere Male ausführen und jedes Mal die gesamte Datei ausdrucken. Ich bin mir nicht ganz sicher, was Sie mit machen. grep
Versuchen Sie, nur die Zeilen auszudrucken, die die bestimmte Variable enthalten?
Eine Möglichkeit, die Dinge besser zu machen, wäre, es sed
einmal auszuführen und alle Ersetzungen durchführen zu lassen. Etwas wie:
replace=""
for item in ${!values[@]}
do
## build the sed line
replace="s/${values[$item]}=[^&\t\n]*/${values[$item]}=***/g;$replace"
done
### run the replacement using sed's -i option so it
### changes the original file
eval sed -i \""$replace"\" $apacheLog