14

Итак, моя переменная пути (System-> Adv Settings-> Env Vars-> System-> PATH) установлена в:

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;

Хотя, очевидно, без перевода строки.

Обратите внимание на строки, содержащие PathWithSpaces - у первого нет пробелов, у второго - пробел, а у третьего - пробел, за которым следует скобка.

Теперь обратите внимание на вывод этого пакетного файла:

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;"

или конкретно строка:

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

Итак, что это за фигня?

В частности:

  • Каталог в пути, который правильно экранирован кавычками, но без пробелов = штраф
  • Каталог в пути, который корректно экранируется кавычками и имеет пробелы, но без скобок = штраф
  • Каталог в пути, правильно экранированный кавычками, с пробелами и круглыми скобками = ОШИБКА

Что тут происходит? Как я могу это исправить? Я, вероятно, прибегну к точке соединения, чтобы мои инструменты все еще работали как обходной путь, но если у вас есть какое-либо понимание этого, пожалуйста, дайте мне знать :)

8 ответов8

17

Примечание для пользователей Windows в 64-битных системах

Progra ~ 1 = «Программные файлы» Progra ~ 2 = «Программные файлы (x86)»

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

12

Там должен либо (а) не будет никаких кавычек в PATH переменной MS-Windows , окружающей среды (команда PATH) или (б) должны быть кавычки вокруг всего выражения следуя (команда SET). К сожалению, это не очень хорошо задокументировано MS, хотя они утверждают, что, если используются кавычки, они будут включены в значение переменной (Справочник по командной строке Windows XP).

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

Это может вызвать проблемы, которые являются непоследовательными и поэтому трудно диагностируемыми. Например, если ваш путь включает в себя «C:\Python27», ваш компьютер скажет «Python» не распознан как внутренняя или внешняя команда, работающая программа или пакетный файл ». когда вы пытаетесь выполнить Python. Однако некоторые библиотеки все еще могут быть доступны.

Вам не нужно "экранировать" пробелы или скобки. Если вам нужно экранировать специальные символы, заключите в кавычки все выражение, включая имя переменной.

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

или вы можете использовать скобки тоже.

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

Обратите внимание, что двойные кавычки должны быть в парах.

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

Однако, вероятно, нет никаких символов, которые являются допустимыми путями, которые могли бы вызвать проблему с командой SET.

12

Это может произойти, если в строке внутри "блока" есть неэкранированные скобки (которые также используют скобки для разграничения).

Обычно это можно исправить, включив отложенное расширение и используя переменные с !var! вместо %var% . Я не могу дать гораздо больше советов, не видя код.

2

Microsoft документирует проблему в « Ошибка запуска сценариев командной оболочки, которые содержат скобки ».

Решение, которое они предлагают, заключается в использовании отложенного расширения.

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

Для установки пути в блоке if вместо использования SET PATH= , вам, вероятно, следует использовать команду PATH .

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

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

Для других переменных другим решением может быть использование кавычек, но вокруг всего этого:

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

В Windows 8 я нашел очень мало успеха с любым из этих методов. Круглые скобки не работают, кавычки работают, но "путь", который вы изменяете таким образом, не является путем, который используется для поиска исполняемых файлов, вместо этого cmd прежнему использует системный путь, который он унаследовал при открытии окна.

пример: после определения архитектуры процессора я хочу добавить пару путей к переменной среды PATH. На самом деле, даже простое добавление их временно будет работать, так как они нужны мне только во время работы пакетного файла. Но это даже не работает.

echo %path% отображает системный PATH во время запуска cmd .

set path="%path%;%programfiles(x86)%\company\program\subdir" работает, но теперь %path% содержит все, что заключено в кавычки, и если я пытаюсь запустить программу в subdir откуда-то еще, это не удается. Использование круглых скобок вместо кавычек не работает.

Еще одна вещь, которую я заметил, заключается в том, что та же команда будет работать, если она введена в интерактивном режиме в cmd , но не при обнаружении в командном файле. Это страшно. Еще одна странность - прерывистая потеря последнего символа значения переменной окружения! Другое несоответствие касается сторонних программ: некоторые могут обрабатывать %var% в качестве параметра, другие - нет.

1

Джои в своем ответе говорит

Это может произойти, если в строке внутри "блока" есть неэкранированные скобки (которые также используют скобки для разграничения).

и это правда. Если есть неэкранированные скобки, нужно избегать их. Это то, что я сделал; Я заменил

set PATH=some_path;%PATH%

с

set PATH="some_path;%PATH%"

и это решило проблему.

1

Я испытал нечто подобное. Microsoft объясняет проблему здесь: http://support.microsoft.com/kb/329308

По сути, вместо изменения переменной Path через System-> Adv Settings-> Env Vars-> System-> PATH, попробуйте

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

У меня были огромные проблемы с выполнением следующей работы в Win8, пока я не добавил двойные кавычки вокруг значения, которое я устанавливал для переменной fromFile. С учетом этого, когда fromFile содержал имя файла с круглыми скобками, следующая строка, которая пыталась выполнить подстановку строки для генерации переменной toFile, не работала. Обратите внимание, что я использую отложенное расширение для оценки переменной во время выполнения, а не во время синтаксического анализа (соответствующего экземпляра CALL)

::-- 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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .