Ihr Problem ist, dass:
old_val=3 sed "s/$old_val/$new_val/g"
auf der Schale setzt die Variablen zu erweitern, nicht sed
. Das Festlegen von Variablen über Befehlspräfix wirkt sich jedoch nur auf die Umgebung des Befehls aus, nicht auf die Bash. old_val
ist also , nie, das für die Stringinterpolation definiert ist. Pro die bash reference manual (Hervorhebung hinzugefügt):
The environment for any simple command or function may be augmented temporarily by prefixing it with parameter assignments, as described in Shell Parameters. These assignment statements affect only the environment seen by that command.
Also, wenn sed
versuchte old_val
aus seiner eigenen Umgebung zu lesen wäre es um den richtigen Wert zu sehen. Aber was sed
empfängt, ist die Post-Interpolation-Zeichenfolge übergeben, die s//9/g
ist, da Bash-Interpolation old_val
(das nur für sed
existiert) nicht sehen.
Um dies zu beheben, wird die Variable in bash gesetzt durch die Zuordnung als separater Befehl ausgeführt wurde, kein sed
Präfix:
('cd /etc/squid/ && new_val=9 && old_val=3 && sed -i "s/$old_val/$new_val/g" *.conf')
Oder richtiger: Sie sollten wirklich auf shell=True
vermeiden verlassen (es ist gefährlich/leicht zu Missbrauch). Auch wenn Sie sed
, all die Dinge, die Sie wurden mit dem Shell für können an der Python-Schicht erfolgen verwenden müssen:
import os
# Get the (unqualified) names of all the entries with the desired name
files = [f for f in os.listdir('/etc/squid') if f.endswith('.conf')]
# Run w/o shell=True, in list form, letting Python handle the working directory
# and variable formatting
subprocess.Popen(['sed', '-i', 's/{}/{}/g'.format(old_val, new_val)] + files, cwd='/etc/squid')
Dies hat das gleiche Verhalten (arbeitet in /etc/squid
, und übergibt die unqualifizierten Dateinamen so gewann man Wenn sich viele Dateien in einem tief verschachtelten Verzeichnis befinden, treten keine Probleme mit der Befehlszeilenlänge auf.
Natürlich könnten Sie noch weiter gehen und einfach the fileinput
module verwenden, um die Arbeit von sed
in Python zu erledigen; Es bietet die Bearbeitung von Dateien an Ort und Stelle wie sed
(obwohl es wahrscheinlich etwas langsamer sein wird, wenn die Dateien eine sinnvolle Größe haben).
Ich weiß, ich subprocess verwenden könnte, aber ich will wissen, was ich hier vermisst .. – user2939055
Funktioniert bei mir von der Kommandozeile in Ordnung. Ich vermute, Python könnte hier das Problem sein. – miken32
@ miken32: Es ist nicht Python, es ist der Missbrauch von 'bash'.Es funktioniert nicht gut von der Kommandozeile, einfache Repro: 'new_val = 9 && alt_val = 3 sed" s/$ alt_val/$ new_val/g "<(echo" 1234567890 ")' – ShadowRanger