Пробіли та парентези у вікні PATH змінна викручує пакетні файли


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.

Отже, що це за фігня?

Конкретно:

  • Каталог на шляху, який належним чином вибрано лапками, але без пробілів = штрафом
  • Каталог на шляху, який належним чином вийшов із лапок, має пробіли, але немає дужок = добре
  • Каталог на шляху, який належним чином вийшов із лапок, має пробіли та має круглі дужки = ПОМИЛКА

Що тут відбувається? Як я можу це виправити? Я, мабуть, вдасться до точки стику, щоб мої інструменти все ще працювали як вирішення, але якщо ви маєте про це розуміння, будь ласка, повідомте мене :)


Виходячи з мого розуміння існуючих питань, наведена вище відповідь є правильною, і вона покладається на врахування того, що команда SET є командою, а PATH є частиною її аргументу, балансом якої є новий рядок PATH. Отже, ІМО, справа не в тому, що вона є малодокументованою, а в тому, що вона більше схожа на неясний крайовий випадок. Я щойно витратив пару годин на це питання.
Девід А. Грей

Відповіді:


14

Це може статися, якщо в рядку "блоку" є неміцні дужки (які також використовують круглі дужки для розмежування).

Зазвичай це можна виправити, увімкнувши затримку розширення та !var!замість цього використовуйте змінні %var%. Не набагато більше порад, які я міг би дати, не побачивши код.


19

Примітка для користувачів Windows у 64-бітних системах

Progra ~ 1 = 'Файли програм' Progra ~ 2 = 'Файли програм (x86)'

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


1
Дуже корисно для позбавлення пробілів у змінній середовищі $ PATH при використанні MSYS в Windows. autoconf не грав добре, поки я не вніс цю зміну.
Майк

13

Там повинен або (а) НЕ буде ніяких лапок в PATH змінної MS-Windows , навколишнього середовища (команда PATH) або (б) повинні бути лапки навколо всього висловлювання слідуючи (команда SET) . На жаль, це не дуже добре документально підтверджено в MS, хоча вони заявляють, що якщо будуть використані лапки, вони будуть включені у значення змінної (Windows XP Command Line Reference) .

$ 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.



1
Ви насправді писали MS-DOS, коли мали на увазі MS-Windows, а ваші команди - для MS-Windows. ОП запитали про MS-Windows. То чому ти його називаєш MS-DOS, я не знаю. Навіть ваші посилання говорили про NT (тобто - Windows. Раніше це було 9X та NT, зараз це просто NT). Windows і MS-DOS - це дві різні операційні системи. Я бачив, що раніше командна команда Windows помилково називала DOS, але навіть це не так неправильно, як те, що ви її назвали.
барлоп

@barlop, звичайно, ти маєш рацію. Дякуємо за правки До Windows-95 Windows була додатком, побудованим поверх DOS. Ви можете запустити Windows, ввівши winкоманду в DOS. Насправді до Windows-3.1 все, як Zork та WordStar, були додатками DOS. Тоді, починаючи з Windows-98, DOS не було. Але я думаю, що деякі старі таймери, як я, все ще помилково називають оболонку CMD як оболонку DOS. Вибачте за плутанину і ще раз дякую за роз’яснення наміру моєї відповіді.
Марк Мікофськи

@MarkMikofski Насправді Windows 9X (95/98 / ME), можливо, також був побудований на DOS. Ви можете, наприклад, відредагувати якийсь файл (можливо, msdos.sys) якийсь варіант (-ів), наприклад bootGUI = 0, і зупинити завантаження вікон tokyopc.org/newsletter/1996/08/msdosed.html Чи можете ви потім завантажувати вікна звідти, я не ' я не знаю. А завантажувальний диск Win9X вважається DOS. Старі таймери, які знають, про що вони говорять, як і ви, як правило, останні люди, які помиляються, викликаючи командний рядок Windows DOS. І перші люди, які найбільше прихильні, що це не DOS.
барлоп

1
Ви пробували поради (SET PATH=%PATH%;C:\Program Files (x86)\path with special characters)? Це абсолютно неправильно!
JosefZ

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

Джої у своїй відповіді говорить

Це може статися, якщо в рядку "блоку" є неміцні дужки (які також використовують круглі дужки для розмежування).

і це правда. Якщо є непомічені дужки, слід уникати їх. Ось що я зробив; Я замінив

set PATH=some_path;%PATH%

з

set PATH="some_path;%PATH%"

і це вирішило проблему.


2
Ні. Вам слід скористатисяset "PATH=some_path;%PATH%"
JosefZ

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

У Windows 8 я знайшов дуже мало успіху з будь-яким із цих методів. Дужки не працюють, цитати працюють, але "шлях", який ви модифікували таким чином, не є шляхом, який використовується для пошуку виконуваних файлів, натомість cmdвсе ще, здається, використовує системний шлях, який він успадкував, коли ви відкрили вікно.

Приклад: після визначення архітектури процесора я хочу додати пару шляхів до змінної середовища PATH. Насправді навіть просто додавання їх тимчасово працювало б, оскільки мені вони потрібні лише під час запуску пакетного файлу. Але це навіть не працює.

echo %path%відображає систему PATH на момент cmdзапуску.

set path="%path%;%programfiles(x86)%\company\program\subdir"працює, але тепер %path%містить усе, оточене цитатами, і якщо я спробую запустити програму в subdir з іншого місця, це не вдасться. Використання дужок навколо всієї справи замість лапок не працює .

Ще одна річ, яку я помітив, це те, що та сама команда буде працювати, якщо її вводити інтерактивно cmd, але не якщо вона зустрічається у пакетному файлі. Це страшно. Ще одна дивина - це переривчаста втрата останнього символу значення змінної середовища! Ще одна невідповідність полягає у сторонніх програмах: одні можуть обробляти %var%параметр a, інші - ні.


1

У мене виникли величезні проблеми з виконанням наступних робіт у програмі Win8, поки я не додав подвійних лапок навколо значення, яке я встановлював для змінної File. З урахуванням того, що, коли 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.