Ich habe ein shell ( php
) Skript, das auf folgende Weise mit der Zieldatei in Kontakt kommt:
- prüft, ob Datei und Verzeichnis mit
php
's beschreibbar sindis_writable()
(ich glaube nicht, dass dies ein Problem ist) - Bearbeitet die Datei vor Ort mit dem folgenden
sed
Befehl:
grep -q "$search" "$passwd_file" && { sed -i "s|$search|$replace|" "$passwd_file"; printf "Password changed!\n"; } || printf "Password not changed!\n"
Als Ergebnis bekomme ich (alles andere richtig als) Datei, die sein myuser:www-data
sollte myuser:myuser
.
Ändert sed
sich der Besitz einer Dateigruppe wie es scheint und wie vermeide ich ihn, wenn möglich?
bash
shell
shell-script
permissions
chown
Miloš Đakonović
quelle
quelle
Antworten:
Es gibt ein kleines Problem mit
sed
dem Inplace-Bearbeitungsmodus-i
.sed
Erstellt eine temporäre Datei im selben Verzeichnis namenssedy08qMA
, wobeiy08qMA
es sich um eine zufällig generierte Zeichenfolge handelt. Diese Datei wird mit dem geänderten Inhalt der Originaldatei gefüllt.sed
Entfernt nach dem Vorgang die Originaldatei und benennt die temporäre Datei mit dem Originaldateinamen um. Es ist also keine echte Inplace-Bearbeitung . Es wird eine neue Datei mit Berechtigungen des anrufenden Benutzers und einer neuen Inode-Nummer erstellt. Dieses Verhalten ist meistens nicht schlecht, aber zum Beispiel werden harte Links unterbrochen.Wenn Sie jedoch eine echte Inplace-Bearbeitung wünschen, sollten Sie diese verwenden
ed
. Es liest Befehle aus dem Standard und bearbeitet die Datei direkt ohne temporäre Datei (dies erfolgt übered
den Speicherpuffer). Es ist üblichprintf
, die Befehlsliste zu erstellen:Der
printf
Befehl erzeugt die folgende Ausgabe:Diese beiden Zeilen sind
ed
Befehle. Der erste sucht nach der Zeichenfolgesearch
und ersetzt sie durchreplace
. Der zweite schreibt (w
) die Änderungen an der Datei und beendet (q
).-s
unterdrückt die Diagnoseausgabe.quelle
Der
-i
Parameter vonsed
funktioniert, indem während des Betriebs eine temporäre Datei erstellt und am Ende die eigentliche Datei mit der temporären Datei überschrieben wird. Dies ist höchstwahrscheinlich die Ursache des Problems, da beim Erstellen der temporären Datei standardmäßig der Besitz der Datei verwendet wirdmyuser:myuser
Sie können das
setgid
Bit im übergeordneten Verzeichnis festlegen (nur wenn das übergeordnete Verzeichnis der Gruppe gehörtwww-data
), sodass Dateien, die unter diesem Verzeichnis erstellt wurden, dieselbe Gruppe erben.das zu tun:
Ich denke, dies ist eine sehr typische Verwendung des
setgid
Bits.quelle
sed -i
, habe die folgende Zeile in der Ablaufverfolgung gefunden. Bedeutet das , dass die temporäre Datei im aktuellen Verzeichnis erstellt wurde?open("./sedKyG9Ei", O_RDWR|O_CREAT|O_EXCL, 0600) = 4
Die Verwendung von
ed
stattsed
erscheint hierfür eher überflüssig, da Sie eine zusätzliche Eingabe eingeben müssen. Die Distribution, an der ich gerade arbeite (CentOS 5.10), hat die-c
Option,sed
dass die temporäre Datei "kopiert" wird, anstatt sie einfach umzubenennen, wenn sie mit der-i
Option verwendet wird. Ich habe es getestet und es hat perfekt funktioniert, wobei der ursprüngliche Besitzer und die ursprüngliche Gruppe bei einer Inline-Bearbeitung erhalten blieben. Die Änderungszeit bleibt NICHT erhalten.z.B,
sed -ci -e '3,5d' file.txt
-c
verwendet Kopie anstelle von Umbenennen (dh behält das Eigentum / die Gruppe bei)-i
Inline-Bearbeitung-e
Skript / Ausdruck ausgeführt werdenIch
sed
bin mir nicht sicher, wie weit verbreitet diese Option in anderen Distributionen ist. Solaris 10 hatte es nicht, aber Solaris hat nicht viele Dinge, die ich will.quelle