Win: sys.argv Problem bei "c:\"

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Freitag 7. November 2008, 11:19

Test Skript:

Code: Alles auswählen

import sys

arg = sys.argv[1]
print arg
print repr(arg)
Test 1:

Code: Alles auswählen

python test.py "c:\test"
Ausgabe:
c:\test
'c:\\test'
Das ist ja ok... Aber das nicht:
Test 2:

Code: Alles auswählen

python test.py "c:\"
Ausgabe:
c:"
'c:"'
Was macht da das Anführungszeichen???


Das gibt es wohl irgendein Problem mit dem Backslash...

Getestet mit Python 2.5.2 unter Vista 64.

Work-a-round: strip('"') machen :?

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
pudeldestodes
User
Beiträge: 65
Registriert: Samstag 9. Juni 2007, 23:45

Freitag 7. November 2008, 11:50

Öh - escapest du nicht das Anführungszeichen?
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Freitag 7. November 2008, 11:53

Ich übergebe den Pfad per Drag&Drop aus dem Exlorere über eine Batch Datei zum Skript:

Code: Alles auswählen

@REM
@REM Helper batch for windows.
@REM
@REM Put a link from this file on your desktop.
@REM Then you can easy drop files on the link.
cd /d "%~dp0"
python.exe md5sum_calc.py "%~1"
@pause
Ich kann nicht einfach statt "%~1" nur %~1 machen oder so. Dann würden Pfade mit Leerzeichen nicht als ein Parameter ankommen...

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
name
User
Beiträge: 254
Registriert: Dienstag 5. September 2006, 16:35
Wohnort: Wien
Kontaktdaten:

Freitag 7. November 2008, 12:28

Ja das \ escaped das Letzte ", das is dein Problem.
Ohloh | Mein Blog | Jabber: segfaulthunter@swissjabber.eu | asynchia – asynchrone Netzwerkbibliothek

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

Freitag 7. November 2008, 12:33

Da " eh nicht in Dateinamen erlaubt sind, könntest du ja einfach das " durch'n \ replacen. Es gibt ja eh nur einen Fall wo das zutrifft... Is'n bissel gehackt, aber es funktioniert.
fk
User
Beiträge: 7
Registriert: Freitag 7. November 2008, 14:54

Freitag 7. November 2008, 15:08

jens hat geschrieben:Ich übergebe den Pfad per Drag&Drop aus dem Exlorere über eine Batch Datei zum Skript:

Code: Alles auswählen

@REM
@REM Helper batch for windows.
@REM
@REM Put a link from this file on your desktop.
@REM Then you can easy drop files on the link.
cd /d "%~dp0"
python.exe md5sum_calc.py "%~1"
@pause
Ich kann nicht einfach statt "%~1" nur %~1 machen oder so. Dann würden Pfade mit Leerzeichen nicht als ein Parameter ankommen...
Du könntest %* anstatt %~1 nehmen (oder macht das ~ irgendwas, was ich vergessen hab?) und dann in deinem Skript irgendwas wie

Code: Alles auswählen

" ".join(sys.argv[1:])
machen.

fk
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Freitag 7. November 2008, 15:52

fk hat geschrieben:Du könntest %* anstatt %~1 nehmen (oder macht das ~ irgendwas, was ich vergessen hab?) und dann in deinem Skript irgendwas wie

Code: Alles auswählen

" ".join(sys.argv[1:])
machen.
Schlägt fehl, wenn man dem zwei Dateien übergibt die Leerzeichen haben. Auch ansonsten finde ich diesen Workaround recht hässlich, dafür ist ja ``argv`` eine Liste damit man eben nicht den String parsen muss sondern dass das von dem aufrufenden Programm, also der Shell gemacht wird.

Andere Lösung: Shell mitliefern, die das richtig macht und die in einer Batch-Datei starten und von der aus das Python-Programm ausführen. Könnte zumindest funktionieren.

Noch eine andere Lösung: Kein Konsolenprogramm verwenden, dann braucht man keine Batch-Datei.

Weitere Lösung: Keine Batchdatei sondern ein Python-Programm verwenden. Dem sollten dann die Parameter richtig übergeben werden.

Beste Lösung: OS nehmen, bei dem nicht schon die Grundfunktionen kaputt sind.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Freitag 7. November 2008, 16:21

Ich hab ja schon eine Lösung im OP angegeben, das funktioniert auch:
jens hat geschrieben:Work-a-round: strip('"') machen :?
Die Frage ist, wer hat schuld? Das OS oder sys.argv?

Ich Tippe darauf, das die Shell auch "c:" und "C:\test" übergibt und das sys.argv einfach was falsch macht...

Und es liegt nicht an der Batch-Datei. Die Tests habe ich ja durch direkten Aufruf gemacht!

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
fk
User
Beiträge: 7
Registriert: Freitag 7. November 2008, 14:54

Freitag 7. November 2008, 16:35

Die Frage ist, wer hat schuld? Das OS oder sys.argv?

Ich Tippe darauf, das die Shell auch "c:\" und "C:\test\" übergibt und das sys.argv einfach was falsch macht...

Und es liegt nicht an der Batch-Datei. Die Tests habe ich ja durch direkten Aufruf gemacht!
Das System, bzw. die Shell. Das ist wie bei Python-Zeichenketten: '\' ist das Escapezeichen, um Zeichen einzufügen, die eine spezielle Bedeutung haben, wie eben z.B. Anführungszeichen. Bei deinem direkten Aufruf hat die Shell eben auch gedacht, sie sollte das " escapen, also einfach ohne spezielle Bedeutung einfügen.

Davon abgesehen hab ich sowas (Batchdatei zum Sachen-ausm-Explorer-Draufziehen) auch mal gemacht, da hat %1 ohne Anführungszeichen perfekt funktioniert, auch für Verzeichnisse mit Leerzeichen (zum Glück mach ich nicht regelmäßig was mit Windowsbatchdateien :D )
fhoech
User
Beiträge: 143
Registriert: Montag 9. April 2007, 18:26

Freitag 7. November 2008, 18:14

Das System, bzw. die Shell. Das ist wie bei Python-Zeichenketten: '\' ist das Escapezeichen, um Zeichen einzufügen, die eine spezielle Bedeutung haben, wie eben z.B. Anführungszeichen. Bei deinem direkten Aufruf hat die Shell eben auch gedacht, sie sollte das " escapen, also einfach ohne spezielle Bedeutung einfügen.
Nicht unter Windows, hier ist ein Backslash auf der Shell oder in .CMD/.BAT-Dateien einfach ein Backslash (ein englischer Spruch, der mir dazu einfällt: "yes, it is THAT broken" ;)), als Escapezeichen fungieren unter bestimmten Bedingungen ^ (für runde und spitze Klammern z.B.) oder % (für %%variablen%%).
In diesem Fall ist Python das Problem (übrigens auch die aktuelle v2.6).
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

Freitag 7. November 2008, 19:07

Benutz mal statt "%~1" einfach %1, es wird trotzdem gequotet. Habs grade getestet... Und dann gibts auch kein Problem mit dem c:\, es wird bei mir dann richtig umgesetzt...
fhoech
User
Beiträge: 143
Registriert: Montag 9. April 2007, 18:26

Freitag 7. November 2008, 19:20

Ja, das funktioniert, wenn die übergebenen Parameter entweder keine Quotes enthalten, oder das letzte Zeichen innerhalb der Quotes kein Backslash ist, aber gequotet wird da nichts. Man muss immer selbst quoten, aber nur bei Parametern die Leerzeichen oder &<>() enthalten, sonst kann man die Quotes auch weglassen (und deshalb funktioniert auch %1, da bei der Übergabe von C:\ ja weder Quotes noch Leerzeichen vorhanden sind).

Die Lösung mit strip('"') scheint mir immer noch am saubersten.
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

Freitag 7. November 2008, 19:51

fhoech hat geschrieben:Ja, das funktioniert, wenn die übergebenen Parameter entweder keine Quotes enthalten, oder das letzte Zeichen innerhalb der Quotes kein Backslash ist, aber gequotet wird da nichts. Man muss immer selbst quoten, aber nur bei Parametern die Leerzeichen oder &<>() enthalten, sonst kann man die Quotes auch weglassen (und deshalb funktioniert auch %1, da bei der Übergabe von C:\ ja weder Quotes noch Leerzeichen vorhanden sind).

Die Lösung mit strip('"') scheint mir immer noch am saubersten.
Will nich wütend reagieren, aber du irrst dich.

in %~1 wird durch das ~ das Quoting entfernt ;) Drag'n Drop fügt automatisch'n " um die gezogene Datei/Verzeichnis herum. Deswegen gehts mit %~1 nicht allein, ein "" muss herum. Aber wenn du nur %1 nimmst gehts mit jedem Verzeichnis ohne Probleme, egal ob da 1000 Leerzeichen oder sonstwas drinsteckt.

(Und komischerweise funktioniert mit %1 C:\ ohne Probleme, mit "%~1" klappt C:\ nicht.)

Edit: Nochmal nachgesehen... Wenn man nur den Ausdruck %1 verwendet, quotet es nur, wenn es nötig ist (Leerzeichen, Spezialzeichen, usw)... ansonsten wird's nich gemacht. Deswegen klappts mit %1, wenn man nur das Laufwerk draufzieht... Weil dann nur der Ausdruck test.py C:\ ausgeführt wird, nicht test.py "C:"
fk
User
Beiträge: 7
Registriert: Freitag 7. November 2008, 14:54

Freitag 7. November 2008, 20:58

Stimmt, \ benutzt man ja für Dateipfade ... :oops: Irgendwie logisch. Naja, die beste Lösung für alle Probleme mit Batchdateien ist wohl immernoch, was anderes (als Batchdateien) zu nehmen.
Benutzeravatar
name
User
Beiträge: 254
Registriert: Dienstag 5. September 2006, 16:35
Wohnort: Wien
Kontaktdaten:

Samstag 8. November 2008, 13:51

fk hat geschrieben:Stimmt, \ benutzt man ja für Dateipfade ... :oops: Irgendwie logisch. Naja, die beste Lösung für alle Probleme mit Batchdateien ist wohl immernoch, was anderes (als Batchdateien) zu nehmen.
Oder gleich ein ordentliches System :wink:
Ohloh | Mein Blog | Jabber: segfaulthunter@swissjabber.eu | asynchia – asynchrone Netzwerkbibliothek

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.
Antworten