Leerzeichen und Klammern in der Windows-Variable PATH vermasseln Batch-Dateien

14

Meine Pfadvariable (System-> Adv Settings-> Env Vars-> System-> PATH) lautet also:

C:\Python26\Lib\site-packages\PyQt4\bin;
%SystemRoot%\system32;
%SystemRoot%;
%SystemRoot%\System32\Wbem;
%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\;
C:\Python26\;
C:\Python26\Scripts\;
C:\cygwin\bin;
"C:\PathWithSpaces\What_is_this_bullshit";
"C:\PathWithSpaces 1.5\What_is_this_bullshit_1.5";
"C:\PathWithSpaces (2.0)\What_is_this_bullshit_2.0";
"C:\Program Files (x86)\IronPython 2.6";
"C:\Program Files (x86)\Subversion\bin";
"C:\Program Files (x86)\Git\cmd";
"C:\Program Files (x86)\PuTTY";
"C:\Program Files (x86)\Mercurial";
Z:\droid\android-sdk-windows\tools;

Obwohl natürlich ohne die Zeilenumbrüche.

Beachten Sie die Zeilen, die Folgendes enthalten PathWithSpaces: Die erste enthält keine Leerzeichen, die zweite ein Leerzeichen und die dritte ein Leerzeichen, gefolgt von einer Klammer.

Beachten Sie nun die Ausgabe dieser Batchdatei:

C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\>vcvars32.bat
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin>"C:\Program Files (x86
)\Microsoft Visual Studio 9.0\Common7\Tools\vsvars32.bat"
Setting environment for using Microsoft Visual Studio 2008 x86 tools.
\What_is_this_bullshit_2.0";"C:\Program was unexpected at this time.
C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin>      set "PATH=C:\Pro
gram Files\Microsoft SDKs\Windows\v6.0A\bin;C:\Python26\Lib\site-packages\PyQt4\
bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\
WindowsPowerShell\v1.0\;C:\Python26\;C:\Python26\Scripts\;C:\cygwin\bin;"C:\Path
WithSpaces\What_is_this_bullshit";"C:\PathWithSpaces 1.5\What_is_this_bullshit_1
.5";"C:\PathWithSpaces (2.0)\What_is_this_bullshit_2.0";"C:\Program Files (x86)\
IronPython 2.6";"C:\Program Files (x86)\Subversion\bin";"C:\Program Files (x86)\
Git\cmd";"C:\Program Files (x86)\PuTTY";"C:\Program Files (x86)\Mercurial";Z:\dr
oid\android-sdk-windows\tools;"

oder speziell die Zeile:

\What_is_this_bullshit_2.0";"C:\Program was unexpected at this time.

Also, was ist das für ein Mist?

Speziell:

  • Verzeichnis im Pfad, das ordnungsgemäß mit Anführungszeichen, aber ohne Leerzeichen geschützt ist = in Ordnung
  • Verzeichnis in Pfad, das ordnungsgemäß mit Anführungszeichen versehen ist und Leerzeichen, aber keine Klammer = fine enthält
  • Verzeichnis im Pfad, das ordnungsgemäß mit Anführungszeichen versehen ist, Leerzeichen und eine Klammer = ERROR enthält

Was ist denn hier los? Wie kann ich das beheben? Ich werde wahrscheinlich auf einen Knotenpunkt zurückgreifen, um meine Tools weiterhin als Problemumgehung zu verwenden, aber wenn Sie einen Einblick in diese haben, lassen Sie es mich bitte wissen :)

Hennes
quelle
Ausgehend von meinem Verständnis der vorliegenden Probleme ist die obige Antwort die richtige und beruht darauf, zu berücksichtigen, dass SET der Befehl ist und PATH Teil seines Arguments ist, dessen Saldo die neue PATH-Zeichenfolge ist. Also, IMO, es ist nicht so, dass es nur spärlich dokumentiert ist, sondern eher wie ein dunkler Randfall. Ich habe gerade ein paar Stunden mit diesem Thema verbracht.
David A. Gray

Antworten:

13

Dies kann passieren, wenn sich in einer Zeile innerhalb eines "Blocks" Klammern ohne Trennzeichen befinden (die auch Klammern zur Begrenzung verwenden).

Sie können es in der Regel beheben , indem Sie mit auf eine verzögerte Expansion und Verwendung Variablen Drehen !var!statt %var%. Es gibt nicht viel mehr Ratschläge, die ich geben könnte, ohne den Code zu sehen.

Joey
quelle
19

Hinweis für Windows-Benutzer auf 64-Bit-Systemen

Progra ~ 1 = 'Programmdateien' Progra ~ 2 = 'Programmdateien (x86)'

https://confluence.atlassian.com/display/DOC/Setting+the+JAVA_HOME+Variable+in+Windows

Robb
quelle
1
Sehr nützlich, um Leerzeichen in der Umgebungsvariablen $ PATH zu entfernen, wenn MSYS unter Windows verwendet wird. Autoconf spielte nicht gut, bis ich diese Änderung vorgenommen habe.
Mike
13

Es sollte entweder (a) nicht alle Anführungszeichen gesetzt wird in dem MS-Windows - PATH - Umgebungsvariable (PATH - Befehl) oder (b) sollte es den gesamten Ausdruck umgeben sein Anführungszeichen nach dem (SET - Befehl) . Leider ist dies von MS nicht sehr gut dokumentiert, obwohl sie angeben, dass Anführungszeichen im Wert der Variablen enthalten sind (Windows XP-Befehlszeilenreferenz) .

$ SET BLAH="blah blah(1)"
$ ECHO %BLAH%
"blah blah(1)"
$ SET BLAH=blah blah(1)
$ ECHO %BLAH%
blah blah(1)

Dies kann zu inkonsistenten und daher schwer zu diagnostizierenden Problemen führen. Wenn Ihr Pfad beispielsweise "C: \ Python27" enthält, meldet Ihr Computer "'Python' wird nicht als interner oder externer Befehl, ausführbares Programm oder Batch-Datei erkannt." wenn Sie versuchen, Python auszuführen. Möglicherweise sind jedoch noch einige Bibliotheken verfügbar.

Leerzeichen oder Klammern müssen nicht "umgangen" werden. Wenn Sie Sonderzeichen maskieren müssen, setzen Sie den gesamten Ausdruck in Anführungszeichen, einschließlich des Variablennamens.

SET "PATH=%PATH%;C:\Program Files (x86)\path with special characters"

oder Sie können auch Klammern verwenden.

(SET VAR=can't contain ampersand, parentheses, pipe, gt or lt)

Beachten Sie, dass doppelte Anführungszeichen paarweise angegeben werden müssen.

(SET VAR=illegal characters!@#$%^*_-+={}[]\:;""',./?)
echo %VAR%
illegal characters!@#$%*_-+={}[]\:;""',./?

Es gibt jedoch wahrscheinlich keine Zeichen, die gültige Pfadnamen sind, die ein Problem mit dem SET-Befehl verursachen würden.

Mark Mikofski
quelle
1
siehe hierzu stackoverflow.com/questions/307198/…
Mark Mikofski
1
Sie haben tatsächlich MS-DOS geschrieben, als Sie MS-Windows meinten, und Ihre Befehle waren für MS-Windows. Das OP fragte nach MS-Windows. Warum Sie es also MS-DOS nennen, weiß ich nicht. Sogar Ihre Links sagten NT (das ist - Windows. Früher war es 9X und NT, jetzt ist es nur noch NT). Windows und MS-DOS sind zwei verschiedene Betriebssysteme. Ich habe gesehen, dass die Windows-Eingabeaufforderung zuvor fälschlicherweise DOS aufgerufen hat, aber auch das ist nicht so falsch, wie Sie es genannt haben.
Barlop
@barlop, natürlich hast du recht. Danke für die Änderungen. Bis Windows-95 war Windows eine Anwendung, die auf DOS aufbaute. Sie können Windows starten, indem Sie den winBefehl in DOS eingeben . Tatsächlich waren vor Windows-3.1 alles, wie Zork und WordStar, DOS-Anwendungen. Ab Windows-98 gab es dann kein DOS mehr. Aber ich denke, einige Oldtimer wie ich bezeichnen die CMD-Shell immer noch fälschlicherweise als DOS-Shell. Entschuldigen Sie die Verwirrung und nochmals vielen Dank, dass Sie die Absicht meiner Antwort klargestellt haben.
Mark Mikofski
@MarkMikofski Eigentlich wurde Windows 9X (95/98 / ME) wohl auch auf DOS gebaut. Sie könnten einige Datei (vielleicht msdos.sys) zum Beispiel bearbeitet einig Option (en) wie BootGUI = 0 und Stopp - Fenster Laden tokyopc.org/newsletter/1996/08/msdosed.html Ob könnten Sie dann Fenster laden von dort I don‘ Ich weiß es nicht. Und eine Win9X-Bootdiskette wird als DOS betrachtet. Oldtimer, die genau wissen, wovon sie sprechen, wie Sie, begehen normalerweise als letzte den Fehler, das DOS der Windows-Eingabeaufforderung aufzurufen. Und sind die ersten, die fest davon überzeugt sind, dass es sich nicht um DOS handelt.
Barlop
1
Haben Sie versucht, beraten (SET PATH=%PATH%;C:\Program Files (x86)\path with special characters)? Es ist total falsch!
JosefZ
2

Microsoft dokumentiert das Problem in " Fehler beim Ausführen von Befehlsshellskripten mit Klammern ".

Die Lösung, die sie vorschlagen, ist die Verwendung einer verzögerten Expansion.

SETLOCAL ENABLEDELAYEDEXPANSION
SET VAR=string containing ( and ) ...
IF "y" == "y" (
    ECHO !VAR! %VAR%
)
ENDLOCAL

Wenn Sie einen Pfad in einem if-Block festlegen möchten, anstatt ihn zu verwenden SET PATH=, sollten Sie wahrscheinlich den PATHBefehl verwenden.

SET AddToPath=C:\Program Files (x86)\Whatever

SETLOCAL ENABLEDELAYEDEXPANSION
IF "%X%" == "%Y%" (
    ECHO Adding !AddToPath! to path !PATH!
    PATH !AddToPath!;!PATH!
)

Für andere Variablen kann eine andere Lösung darin bestehen, Anführungszeichen zu verwenden, aber um das Ganze herum:

SET "MyVar=C:\Program Files (x86)\Whatever"
mivk
quelle
1

Joey in seiner Antwort sagt

Dies kann passieren, wenn sich in einer Zeile innerhalb eines "Blocks" Klammern ohne Trennzeichen befinden (die auch Klammern zur Begrenzung verwenden).

und das stimmt. Wenn es nicht entkappte Klammern gibt, sollte man sie gut entkoppeln. Das ist, was ich tat; ich ersetzte

set PATH=some_path;%PATH%

mit

set PATH="some_path;%PATH%"

und das löste das problem.

Piotr Dobrogost
quelle
2
Nee. Sie sollten verwendenset "PATH=some_path;%PATH%"
JosefZ
1

Ich habe etwas Ähnliches erlebt. Microsoft erläutert das Problem hier: http://support.microsoft.com/kb/329308

Anstatt die Variable Path über System-> Adv Settings-> Env Vars-> System-> PATH zu ändern, sollten Sie grundsätzlich versuchen

My Computer->Manage->Computer Management (local)-> Properties-> Advanced-> Environment variables-> Settings
Phearce
quelle
1

In Windows 8 habe ich mit keiner dieser Methoden Erfolg gehabt. Klammern funktionieren nicht, Anführungszeichen funktionieren, aber der "Pfad", den Sie auf diese Weise ändern, ist nicht der Pfad, der zum Auffinden von ausführbaren Dateien verwendet wird, sondern cmdscheint weiterhin den Systempfad zu verwenden, den er beim Öffnen des Fensters übernommen hat.

Beispiel: Nach dem Bestimmen der Prozessorarchitektur möchte ich der Umgebungsvariablen PATH einige Pfade hinzufügen. Eigentlich würde es sogar funktionieren, wenn ich sie nur vorübergehend hinzufüge, da ich sie nur benötige, während eine Batch-Datei ausgeführt wird. Das geht aber gar nicht.

echo %path%Zeigt den Systempfad zum Zeitpunkt des Starts an cmd.

set path="%path%;%programfiles(x86)%\company\program\subdir"funktioniert, %path%enthält aber jetzt alles, was von Anführungszeichen umgeben ist. Wenn ich versuche, ein Programm in einem Unterverzeichnis von einer anderen Stelle aus auszuführen, schlägt dies fehl. Klammern um das Ganze anstelle von Anführungszeichen zu verwenden, funktioniert nicht .

Eine andere Sache, die mir aufgefallen ist, ist, dass derselbe Befehl funktioniert, wenn er interaktiv eingegeben wird cmd, aber nicht, wenn er in einer Batch-Datei auftritt. Das ist erschreckend. Eine weitere Kuriosität ist der zeitweise Verlust des letzten Zeichens des Werts einer Umgebungsvariablen! Eine weitere Inkonsistenz besteht bei Programmen von Drittanbietern: Einige können a %var%als Parameter behandeln, andere nicht.

Pete
quelle
1

Ich hatte große Probleme, die folgende Arbeit in Win8 zu machen, bis ich doppelte Anführungszeichen um den Wert hinzufügte, den ich auf fromFile-Variable einstellte. Wenn fromFile einen Dateinamen mit Klammern enthielt, schlug die nächste Zeile fehl, in der versucht wurde, die toFile-Variable durch Zeichenfolgen zu ersetzen. Beachten Sie, dass ich dort die verzögerte Erweiterung verwende, um die Variable zur Ausführungszeit anstatt zur Parsingzeit (der jeweiligen CALL-Instanz) auszuwerten.

::-- BATCH file that creates an *_576_5.* file from an *_640_t.* one (copying it)
::-- Author: George Birbilis (http://zoomicon.com)
::-- Credits: String replacement based on http://www.dostips.com/DtTipsStringManipulation.php

@ECHO OFF

::-- Loop for all files recursively --::

FOR /R %%f in (*_640_t.*) DO CALL :process %%f

ECHO(
PAUSE

GOTO :EOF

::-- Per-file actions --::

:process

:: Display progress...
::ECHO Processing %*
<nul (set/p dummy=.)

SETLOCAL ENABLEDELAYEDEXPANSION
SET fromFile="%*"
SET toFile=!fromFile:_640_t=_576_t!

IF NOT EXIST %toFile% CALL :generate %fromFile% %toFile%

GOTO :EOF

::-- Generate missing file --::

:generate

ECHO(
ECHO COPY %*
COPY %*

::PAUSE

GOTO :EOF
George Birbilis
quelle