ช่องว่างและวงเล็บในตัวแปร Windows PATH ไขไฟล์แบตช์


14

ดังนั้นตัวแปรเส้นทางของฉัน (ระบบ -> Adv การตั้งค่า -> Env Vars-> ระบบ -> เส้นทาง) ตั้งค่าเป็น:

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.

ดังนั้นพล่ามนี้คืออะไร?

โดยเฉพาะ:

  • ไดเร็กทอรีในพา ธ ที่ถูก Escape อย่างเหมาะสมด้วยเครื่องหมายคำพูด แต่ไม่มีช่องว่าง = fine
  • ไดเร็กทอรีในพา ธ ที่มีการอ้างอิงอย่างถูกต้องและมีช่องว่าง แต่ไม่มีเครื่องหมายวงเล็บ = ละเอียด
  • ไดเร็กทอรีในพา ธ ที่ถูก Escape อย่างเหมาะสมด้วยเครื่องหมายคำพูดและมีช่องว่างและมีเครื่องหมายวงเล็บ = ERROR

เกิดอะไรขึ้นที่นี่? ฉันจะแก้ไขสิ่งนี้ได้อย่างไร ฉันอาจจะใช้จุดเชื่อมต่อเพื่อให้เครื่องมือของฉันยังคงทำงานตามปกติ แต่ถ้าคุณมีความเข้าใจในเรื่องนี้โปรดแจ้งให้เราทราบ :)


จากความเข้าใจในประเด็นที่มีอยู่คำตอบข้างต้นเป็นคำตอบที่ถูกต้องและขึ้นอยู่กับการพิจารณาว่า SET เป็นคำสั่งและ PATH เป็นส่วนหนึ่งของการโต้แย้งความสมดุลซึ่งเป็นสตริง PATH ใหม่ ดังนั้น IMO ไม่ใช่ว่าจะมีการจัดทำเอกสารอย่างกระจัดกระจาย แต่มันก็เป็นมากกว่ากรณีที่คลุมเครือ ฉันเพิ่งใช้เวลาสองสามชั่วโมงกับปัญหานี้
David A. Gray

คำตอบ:


13

สิ่งนี้สามารถเกิดขึ้นได้หากมีวงเล็บที่ไม่ใช้ค่า Escape ในบรรทัดภายใน "บล็อก" (ซึ่งใช้วงเล็บในการกำหนดค่าด้วย)

คุณมักจะสามารถแก้ไขได้โดยการเปิดล่าช้าการขยายตัวและการใช้ตัวแปรที่มีแทน!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

ควรมีอย่างใดอย่างหนึ่ง (ก) ไม่ได้เป็นคำพูดใด ๆ ใน MS-Windows ของ PATH ตัวแปรสิ่งแวดล้อม(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' ไม่ได้รับการยอมรับว่าเป็นคำสั่งภายในหรือภายนอก, โปรแกรมที่ทำงานได้หรือแบตช์ไฟล์" เมื่อคุณพยายามรันหลาม อย่างไรก็ตามห้องสมุดบางแห่งอาจยังคงมีอยู่

คุณไม่จำเป็นต้องเว้นวรรคหรือ "หลบหนี" ในวงเล็บ หากคุณต้องการหลีกเลี่ยงอักขระพิเศษให้ใส่เครื่องหมายคำพูดล้อมรอบนิพจน์ทั้งหมดรวมถึงชื่อตัวแปร

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 OP ได้ถามเกี่ยวกับ MS-Windows เหตุใดคุณจึงเรียกมันว่า MS-DOS ฉันไม่รู้ แม้แต่ลิงก์ของคุณก็บอกว่า NT (นั่นคือ - Windows มันเคยเป็น 9X และ NT แต่ตอนนี้มันเป็นแค่ NT) Windows และ MS-DOS เป็นระบบปฏิบัติการที่แตกต่างกันสองระบบ ฉันเคยเห็นพรอมต์คำสั่ง windows เรียกผิดพลาดว่า DOS มาก่อน แต่ถึงอย่างนั้นก็ไม่ผิดเหมือนที่คุณเรียกมัน
barlop

@barlop แน่นอนคุณถูกต้อง ขอบคุณสำหรับการแก้ไข จนกระทั่ง Windows-95 นั้น Windows เป็นแอปพลิเคชั่นที่สร้างขึ้นบน DOS คุณสามารถเริ่ม Windows โดยพิมพ์winคำสั่งใน DOS ในความเป็นจริงก่อน Windows-3.1 ทุกอย่างเช่น Zork และ WordStar เป็นแอปพลิเคชัน DOS จากนั้นเริ่มต้นด้วย Windows-98 ไม่มี DOS แต่ฉันคิดว่าตัวจับเวลาเก่า ๆ อย่างฉันยังคงอ้างถึงเชลล์ CMD โดยผิดพลาดว่าเป็นเชลล์ดอส ขออภัยในความสับสนและขอขอบคุณอีกครั้งสำหรับการชี้แจงเจตนาของคำตอบของฉัน
Mark Mikofski

@MarkMikofski จริง ๆ แล้ว Windows 9X (95/98 / ME) นั้นสร้างขึ้นบน DOS ด้วย ตัวอย่างเช่นคุณสามารถแก้ไขไฟล์บางไฟล์ (อาจเป็น msdos.sys) บางตัวเลือกเช่น bootGUI = 0 และหยุดการโหลด windows tokyopc.org/newsletter/1996/08/msdosed.html ไม่ว่าคุณจะโหลดหน้าต่างจากที่นั่นหรือไม่ ไม่รู้ และดิสก์สำหรับบูต Win9X ถือเป็น DOS ตัวจับเวลาเก่าที่รู้ว่าสิ่งที่พวกเขากำลังพูดถึงในขณะที่คุณทำมักจะเป็นคนสุดท้ายที่ทำผิดพลาดในการเรียกคำสั่ง windows พร้อมรับคำ DOS และเป็นคนแรกที่ยืนกรานมากที่สุดว่าไม่ใช่ดอส
barlop

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

โจอี้ตอบว่า

สิ่งนี้สามารถเกิดขึ้นได้หากมีวงเล็บที่ไม่ใช้ค่า Escape ในบรรทัดภายใน "บล็อก" (ซึ่งใช้วงเล็บในการกำหนดค่าด้วย)

และนั่นเป็นเรื่องจริง หากมีวงเล็บที่ไม่ใช้ค่า Escape ควรจะหลีกเลี่ยงได้ นั่นคือสิ่งที่ฉันทำ; ฉันแทนที่

set PATH=some_path;%PATH%

กับ

set PATH="some_path;%PATH%"

และสิ่งนี้แก้ปัญหาได้


2
Nope คุณควรใช้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%มีทุกอย่างที่ล้อมรอบด้วยคำพูดและถ้าฉันพยายามที่จะเรียกใช้โปรแกรมในส่วนย่อยจากที่อื่นก็ล้มเหลว ใช้วงเล็บรอบสิ่งที่ทั้งแทนคำพูดที่ไม่ได้ทำงาน

สิ่งที่ฉันสังเกตเห็นอีกอย่างก็คือว่าคำสั่งเดียวกันจะทำงานได้ถ้าป้อนแบบโต้ตอบcmdแต่ไม่พบในไฟล์แบตช์ มันช่างน่ากลัว อีกสิ่งที่แปลกประหลาดคือการสูญเสียตัวอักษรตัวสุดท้ายของค่าตัวแปรสภาพแวดล้อมเป็นระยะ ๆ ! ความไม่สอดคล้องกันอีกประการหนึ่งคือกับโปรแกรมของบุคคลที่สาม: บางโปรแกรมสามารถจัดการ%var%พารามิเตอร์ได้


1

ฉันมีปัญหาอย่างมากในการทำงานต่อไปนี้ใน Win8 จนกระทั่งฉันเพิ่มเครื่องหมายคำพูดคู่ให้เรียงกันตามค่าที่ฉันตั้งจากตัวแปรไฟล์ โดยที่เมื่อ, 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.