Seite 1 von 1

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

Verfasst: Freitag 7. November 2008, 11:19
von jens
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 :?

Verfasst: Freitag 7. November 2008, 11:50
von pudeldestodes
Öh - escapest du nicht das Anführungszeichen?

Verfasst: Freitag 7. November 2008, 11:53
von jens
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...

Verfasst: Freitag 7. November 2008, 12:28
von name
Ja das \ escaped das Letzte ", das is dein Problem.

Verfasst: Freitag 7. November 2008, 12:33
von BlackVivi
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.

Verfasst: Freitag 7. November 2008, 15:08
von fk
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

Verfasst: Freitag 7. November 2008, 15:52
von Leonidas
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.

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

Verfasst: Freitag 7. November 2008, 16:21
von jens
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!

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

Verfasst: Freitag 7. November 2008, 16:35
von fk
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 )

Verfasst: Freitag 7. November 2008, 18:14
von fhoech
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).

Verfasst: Freitag 7. November 2008, 19:07
von BlackVivi
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...

Verfasst: Freitag 7. November 2008, 19:20
von fhoech
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.

Verfasst: Freitag 7. November 2008, 19:51
von BlackVivi
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:"

Verfasst: Freitag 7. November 2008, 20:58
von fk
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.

Verfasst: Samstag 8. November 2008, 13:51
von name
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: