ich bin Python-Anfänger und habe ein Problem, welches ich auch durch
eifriges Googlen nicht lösen konnte:
Von einem Linux-System aus, will ich mit Hilfe eines kleinen Python
programms ein Windows-System herunterfahren
cmd = 'net rpc SHUTDOWN -C "shutdown" -f -I %s -U Administrator%passwort'
% (dest_addr)
p = os.popen(cmd)
p.readline()
Die Fehlermeldung lautet:
TypeError: not enough arguments for format string
was ich so interpretiere, dass Python versucht das % zwischen
Benutzername und Passwort als weiteres Argument interpretiert
und nicht als Zeichen.
Wie kann ich das % maskieren?
Gruß...........Markus
>> Wie kann ich das % maskieren?
>
> Mit %%
Danke!
Wenn ich das Programm jetzt ausführe, wird das Passwort für
die Windows-Kiste verlangt, obwohl es hinter %% steht.
Führe ich den Befehl in der Konsole aus (mit %, nicht %%),
funktioniert der Shutdown ohne weiteres.
Was nun?
Gruß...........Markus
Zeig uns erst mal den Code, und was genau cmd dann enthaelt.
Ausserdem solltest du statt os.popen das Modul subprocess verwenden, und dir
da anschauen was fuer einen returncode du bekommst, und ob stderr was
ausspuckt.
Diez
Das Script basiert auf ping.py, zu finden u.a hier:
http://www.g-loaded.eu/2009/10/30/python-ping/
Die letzte Funktion habe ich folgendermaßen geändert:
def verbose_ping(timeout = 2, count = 2):
fobj = open("test.txt", "r")
for line in fobj:
dest_addr = line
for i in xrange(count):
print "ping %s..." % dest_addr,
try:
delay = do_one(dest_addr, timeout)
except socket.gaierror, e:
print "failed. (socket error: '%s')" % e[1]
break
if delay == None:
print "failed. (timeout within %ssec.)" % timeout
else:
delay = delay * 1000
print "get ping in %0.4fms" % delay
cmd = 'net rpc SHUTDOWN -C "shutdown" -f -I %s -U Administrator%%passwort' % (dest_addr)
p = os.popen(cmd)
p.readline()
print
if __name__ == '__main__':
verbose_ping()
Markus
> def verbose_ping(timeout = 2, count = 2):
> fobj = open("test.txt", "r")
> for line in fobj:
> dest_addr = line
> for i in xrange(count):
> print "ping %s..." % dest_addr,
> try:
> delay = do_one(dest_addr, timeout)
Fehlt die Definition.
Du solltest dich bemuehen beim posten von code ein moeglichst minimales
Beispiel zu praesentieren, welches das Verhalten zeigt, um das es dir geht.
Das geht natuerlich nicht immer, aber in diesem Fall schon.
> except socket.gaierror, e:
> print "failed. (socket error: '%s')" % e[1]
> break
> if delay == None:
> print "failed. (timeout within %ssec.)" % timeout
> else:
> delay = delay * 1000
> print "get ping in %0.4fms" % delay
> cmd = 'net rpc SHUTDOWN -C "shutdown" -f -I %s -U Administrator%%passwort'
> % (dest_addr) p = os.popen(cmd)
> p.readline()
> print
>
>
> if __name__ == '__main__':
> verbose_ping()
>
Das Kommando das ausgespuckt wird sieht bei mir so aus:
net rpc SHUTDOWN -C "shutdown" -f -I bar -U Administrator%passwort
(bar ist dummy-ip)
Soweit also ganz gut. Fuer mich kommt da bei einem Rechner, den ich nicht
*wirklich* runterfahren will
Could not connect to server 10.1.15.10
The username or password was not correct.
Connection failed: NT_STATUS_LOGON_FAILURE
Das ist mein testskript:
import subprocess
dest_addr = "sky"
cmd = 'net rpc SHUTDOWN -C "shutdown" -f -I %s -U Administrator%%passwort -d
10' % (dest_addr)
print cmd
p = subprocess.Popen(cmd, shell=True)
p.wait()
Was gibt das aus?
Diez
ping 172.17.200.21
... get ping in 0.0000ms
net rpc SHUTDOWN -C "shutdown" -f -I 172.17.200.21
-U Administrator%passwort
Enter root's password:
Could not connect to server 172.17.200.21
The username or password was not correct.
Connection failed: NT_STATUS_LOGON_FAILURE
Could not connect to server 172.17.200.21
The username or password was not correct.
Connection failed: NT_STATUS_LOGON_FAILURE
/bin/sh: -U: not found
Markus
Bitte lass das Skript laufen welches ich dir gegeben habe. Nicht das, was du
gebaut hast.
Denn der obige output indiziert, dass da so einiges komisches
passiert. "net" wuerde niemals nach "root" fragen, dass mus etwas anderes
sein. Sudo vielleicht, oder was auch immer.
Diez
Hat dest_addr einen Zeilenumbruch?
Probier es bitte ansonsten erstmal mit einer fixen IP, ohne Textersetzung.
Uli
Sehr gut, das wird's sein - er liest die IPs aus einer Datei, und die
hat natuerlich Zeilenenden.
Meine Vermutung, "net" wuerde nicht nach dem Passwort von root fragen
war also falsch - wahrscheinlich fragt es einfach mal nach dem passwort
des aktuellen Users, um das mitzuschicken.
Diez
Gut, leider habe ich wegen des Wochenendes nicht die Möglichkeit, das
Ganze auszuprobieren. Die IPs werden aus einer Datei ausgelesen, das
stimmt. Der net-Befehl im Python-Script hat keinen Zeilenumbruch.
Wenn es wirklich daran liegt, dass jede IP im Textfile am Ende einen
solchen hat, wäre das für mich erstaunlich. Ein Bash-Script hat damit
doch auch kein Problem. Wenn es doch so ist, was hilft?
Markus
line = line.strip()
Und wenn es keine semantischen Unterschiede zwischen
Programmierspraechen gaebe, haetten wir nur eine. Das waere dann
wahrscheinlich Algol oder sowas.
Diez
>>> cmd = 'net rpc SHUTDOWN -C "shutdown" -f -I %s -U
>>> Administrator%%passwort -d 10' % (dest_addr)
>>> print cmd
>>> p = subprocess.Popen(cmd, shell=True)
> Hat dest_addr einen Zeilenumbruch?
>
> Probier es bitte ansonsten erstmal mit einer fixen IP, ohne Textersetzung.
Bzw. probier mal print repr(cmd) statt print cmd
Thomas
>> Gut, leider habe ich wegen des Wochenendes nicht die Möglichkeit, das
>> Ganze auszuprobieren. Die IPs werden aus einer Datei ausgelesen, das
>> stimmt. Der net-Befehl im Python-Script hat keinen Zeilenumbruch. Wenn
>> es wirklich daran liegt, dass jede IP im Textfile am Ende einen solchen
>> hat, wäre das für mich erstaunlich. Ein Bash-Script hat damit doch auch
>> kein Problem. Wenn es doch so ist, was hilft?
>
>
> line = line.strip()
>
> Und wenn es keine semantischen Unterschiede zwischen
> Programmierspraechen gaebe, haetten wir nur eine. Das waere dann
> wahrscheinlich Algol oder sowas.
Hört sich ein wie ein Mundwasser...
Markus
Also hier der letzte Teil des Scripts, wie es jetzt aussieht. Rest siehe weiter oben im Thread
def verbose_ping(timeout = 2, count = 2):
fobj = open("test.txt", "r")
for line in fobj:
dest_addr = line
for i in xrange(count):
print "ping %s..." % dest_addr,
try:
delay = do_one(dest_addr, timeout)
except socket.gaierror, e:
print "failed. (socket error: '%s')" % e[1]
break
if delay == None:
print "failed. (timeout within %ssec.)" % timeout
else:
delay = delay * 1000
print "get ping in %0.4fms" % delay
cmd = 'net rpc SHUTDOWN -C "shutdown" -f -I %s -U Administrator%%baccHus' % (dest_addr)
print repr(cmd)
#p = os.popen(cmd)
p = subprocess.Popen(cmd, shell=True)
p.wait()
if __name__ == '__main__':
verbose_ping()
Die Fehlermeldung lautet, ob mit fester IP oder ausgelesener:
ping 172.17.200.21
... get ping in 0.0000ms
'net rpc SHUTDOWN -C "shutdown" -f -I 172.17.200.21 -U Administrator%%passwort'
Naja, du hast ja auch ein return mittem im string deines commandos, weil der
sich ueber zwei zeilen erstreckt.
Mach das mal zu einer zeile.
Diez