Wie behandeln Sie eine schließende Klammer im Pfad-Namen in einer for-Schleife?
Habe ich einen langen Pfadnamen zu einem Programm, das ich ausführen muss, die in einer for /f-Schleife, die eine schließende Klammer ")", und von denen brauche ich zum Parsen der Ausgabe:
for /f "tokens=1" %%G in ('"C:\Documents and Settings\myaccount\Desktop\Test_release (x86)\program.exe" list') do (echo Will do something with %%G)
...wo 'Liste' ist ein parameter übergeben zu meinem Programm. Ich bekomme den Fehler "'C:\Documents' nicht erkannt wird als Befehl interne oder externe, betriebsbereiten Programm oder batch-Datei".
Ich weiß das problem ist, dass die schließende Klammer in der Tat schließt die "für" - block, so wird das Ende doppelte Anführungszeichen nicht "gesehen", so der lange Pfad-Namen nicht eingeschlossen in doppelten Anführungszeichen mehr. Was ich nicht verstehe, ist warum ist dies passiert, denn mein Weg ist eingeschlossen in doppelten Anführungszeichen? Ich habe auch versucht die option usebackq:
for /f "usebackq tokens=1" %%G in (`"C:\Documents and Settings\myaccount\Desktop\Test_release (x86)\program.exe" list`) do (echo Will do something with %%G)
...ohne bessere Ergebnisse. Ich versuchte zu entkommen, wie dieses "^)" oder so "^^)", nichts zu tun. Versucht Verdoppelung der Anführungszeichen:
for /f "tokens=1" %%G in ('""C:\Documents and Settings\myaccount\Desktop\Test_release (x86)\program.exe"" list') do (echo Will do something with %%G)
Funktioniert immer noch nicht.
Ich bin darüber hinaus in der Tat über eine variable enthält den Pfad, die nicht im Voraus wissen (gebaut von %CD%), und EnableDelayedExpansion aktiviert ist. Ich habe versucht, die verzögerte Erweiterung (die zwar behoben, die ähnliche Probleme in anderen Situationen) um zu verhindern, dass die variable expansion zu Lesen, die Zeit und die Verzögerung bei der Ausführung:
setlocal EnableDelayedExpansion
set _var=%CD%\program.exe
@REM _var now contains C:\Documents and Settings\myaccount\Desktop\Test_release (x86)\program.exe
for /f "tokens=1" %%G in ('"!_var!" list') do (echo %%G)
endlocal
Immer noch nicht funktioniert, verstehe nicht warum.
Aber, Verdoppelung der Anführungszeichen mit einer verzögerten expansion im obigen code:
for /f "tokens=1" %%G in ('""!_var!"" list') do (echo %%G)
funktioniert!... warum... warum tun Sie dieses??? Welchen Effekt hat es? Ich verstehe es nicht. Außerdem befürchte ich, dass es möglicherweise ein problem in einigen bestimmten Umständen.
Irgendeine Idee?
- Entschuldigen Sie mich. Sie schrieb, Sie versucht zu entkommen, die Klammern. Sind Sie sicher, dass Sie es so?:
for /f "tokens=1" %%G in ('"C:\Documents and Settings\myaccount\Desktop\Test_release ^(x86^)\program.exe" list') do (echo Will do something with %%G)
- Ja, ich habe es wie schon erwähnt direkt unter meinem 2. Beispiel, ohne Erfolg.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Kommentare in den Antworten auf diese Frage geben XP gibt unterschiedliche Verhalten dann neuere Windows-Versionen.
Es ist bekannt FÜR /F bug in XP: http://www.dostips.com/forum/viewtopic.php?p=9062#p9062. Aber dieses problem ist nicht mit diesem bug.
Das eigentliche problem ergibt sich aus, wie FÜR /F führt einen Befehl in der IN () - Klausel. Es nutzt
CMD \C command
(Siehe Wie funktioniert die Windows-Kommando-Interpreter (CMD.EXE) analysieren Skripts?)Können Sie dieses Verhalten beobachten, durch hinzufügen folgender Zeile zu Aacini ist PROG.BAT Beispiel.
Die nächste Ausgabe beschäftigt sich mit, wie Sie CMD befasst sich mit Zitaten, die in der /C-Befehl, und warum XP anders verhält als in neueren Windows-Versionen.
Dieser Befehl schlägt fehl, in XP, aber gelingt es in Vista und darüber hinaus:
Den Befehl, der FÜR die Ausführung versucht (der Ausdruck %cmdcmdline%) ist in beiden Versionen identisch (abgesehen von unterschieden in %COMSPEC%):
XP hat eine CMD-design-Fehler im Umgang mit den Zitaten. Der Fehler ist sogar dokumentiert (aber es wird nicht erkannt als Makel). Vista und darüber hinaus teilweise Korrektur der Designfehler, aber nicht die Mühe, zu korrigieren der Dokumentation.
Hier ist ein Auszug aus der HILFE CMD
Wollen wir CMD-Folgen-Regel 1, so dass die Anführungszeichen erhalten bleiben, aber
(
und)
gegen den besonderen Charakter der Einschränkung auf XP, also in der Regel 2 beachtet und in der CMD-Ausführung versuchtSollte es ziemlich offensichtlich, warum dies scheitert!
Ich kann nicht daran denken, irgendeinen Grund, warum die Sonderzeichen Einschränkung existiert in der Regel 1. Es Niederlagen der ganze Zweck von dem, was MS versucht, zu machen.
Anscheinend ist der design-Fehler ist teilweise behoben, Vista und darüber hinaus, aber Sie haben sich nicht aktualisiert, die HILFE-Dokumentation. Vista ignoriert die Sonderzeichen
(
und)
und Prozesse der Befehl mit Regel 1, die Zitate sind erhalten geblieben, und alles funktioniert.Update 2015-05-17: Leider, Vista und darüber hinaus noch behandeln
@
,^
, und&
als Besondere Zeichen, auch wenn es sich um gültige Zeichen in Datei-Namen. Natürlich<
,>
, und|
werden als Sonderzeichen behandelt, aber Sie sind nicht gültig in Dateinamen sowieso. Also für Vista und darüber hinaus, die Unterlagen für Regel 1 Lesen solltewhere special is one of: &<>@^|
.Habe ich verfolgt, das Verhalten, die jeder hat dokumentiert, und es ist alles im Einklang mit den obigen.
Es ist ein Weg, um den Befehl auszuführen, die auf XP ohne Verwendung einer verzögerten expansion variable, und es ist kompatibel mit Vista und darüber hinaus.
Den öffnenden und schließenden Hochkommas escaped, so dass die
)
nicht beeinträchtigt, die FÜR den parser. Der Befehl, der ausgeführt wird, für die IN () - Klausel istBeide XP und Vista führen Sie die Regel 2, weil es mehr als zwei Anführungszeichen, also CMD ausführt
und alles funktioniert!
Den rest dieser Antwort ist veraltet, aber beibehalten, um einen Kontext zu bereits vorhandenen Kommentaren.
Ihrem sehr 1. code-Beispiel funktionieren sollte; es kann nicht (das sollen) nicht geben Sie die Fehlermeldung, die Sie beschreiben. Die Fehlermeldung bricht der Weg in den ersten Raum, was bedeutet, dass der Pfad war nicht escaped quotiert. Aber Sie sind "sicher" war er zitiert.
Den Schlüssel zu dem problem ist drei Stücke von Informationen, die in der Nähe des Ende Ihres Beitrags:
Sind Sie eigentlich Verwendung einer variable mit der verzögerten Erweiterung
dies nicht funktioniert:
for /f "tokens=1" %%G in ('"!_var!" list') do (echo %%G)
dies funktioniert:
for /f "tokens=1" %%G in ('""!_var!"" list') do (echo %%G)
Wenn der Wert von var ist bereits zitiert, du bekommst das Verhalten, das Sie beschreiben.
Den Wert Ihrer var muss
"C:\Documents and Settings\myaccount\Desktop\Test_release (x86)\program.exe"
, einschließlich der Anführungszeichen.Machen diese Erklärung mehr lesbar, ich werde verkürzen den Weg zu
"test (this)\prog.exe"
"!var!"
schlägt fehl, weil es erweitert, um""test (this)\prog.exe""
, die effektiv unquotes den Weg. Der string besteht aus drei Bereichen, zwei, die zitiert werden, und in der Mitte, dass ist nicht:""!var!""
funktioniert, weil es erweitert, um"""test (this)\prog.exe"""
und der Weg ist jetzt wieder zitiert. Es gibt nun fünf Bereiche, die innerhalb der Zeichenfolge:Die einfache Antwort auf die Frage, wie Sie Vorgehen sollten:
Wenn der Wert von var ist schon zitiert, dann nutzen Sie einfach
!var!
Bearbeiten - das funktioniert nicht auf XP: "!var!" funktioniert sowohlWenn der Wert von var ist nicht zitiert, dann verwenden Sie
"!var!"
Bearbeiten - das funktioniert nicht auf XP: ""!var!"" funktioniert auf beidenMachte ich einige tests zu finden, warum die direkte Methode, die Sie zuerst verwendet hat nicht funktioniert. Habe ich zunächst ein Verzeichnis mit dem Namen
test (this)
im inneren, die ich erstellt eine batch-Datei mit dem Namenprog.bat
:Dann hab ich erstmal versucht, Zugriff auf den Inhalt solcher Datei mit
for /f
. Beachten Sie, dassuseback
option ist erforderlich, da der Dateiname Leerzeichen enthalten und müssen in Anführungszeichen eingeschlossen werden:Vorherigen Ergebnis beweisen, dass der Pfad korrekt angegeben. Nun, zu ausführen die Batch-Datei, anstatt es zu Lesen, nur einschließen, der seinen Namen in back quotes, richtig?
Dann, weil die Nachricht sagte, dass
test
ist der name des Befehls nicht gefunden wird, habe ich mir eine Batch-Datei mit dem Namentest.bat
:Aha! Früheren Ergebnis zeigen, dass in diesem Fall die Anführungszeichen werden ignoriert und nur
test (this)\prog.bat
ausgeführt wird, richtig?Was nun? Naja, das problem ist JETZT bezogen auf die Klammern:
Mein Fazit ist, dass die
for /f
Befehl einen Fehler, wenn beide back-quotes und Zitate sind verwendet in Kombination mit "usebackq" - option und der Dateiname Leerzeichen enthält, und dass dieser Fehler entfällt, wenn eine verzögerte Erweiterung von Umgebungsvariablen verwendet.