Dấu cách và dấu ngoặc trong windows PATH biến vít lên các tệp bó


14

Vì vậy, biến đường dẫn của tôi (System-> Adv Settings-> Env Vars-> System-> PATH) được đặt thành:

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;

Mặc dù, rõ ràng, không có dòng mới.

Lưu ý các dòng chứa PathWithSpaces- đầu tiên không có khoảng trắng, dòng thứ hai có khoảng trắng và dòng thứ ba có khoảng trắng theo dấu ngoặc đơn.

Bây giờ, hãy chú ý đầu ra của tệp bó này:

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

hoặc cụ thể là dòng:

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

Vì vậy, điều nhảm nhí này là gì?

Đặc biệt:

  • Thư mục trong đường dẫn được thoát đúng với dấu ngoặc kép, nhưng không có dấu cách = fine
  • Thư mục trong đường dẫn được thoát đúng với dấu ngoặc kép và có khoảng trắng nhưng không có dấu ngoặc đơn = fine
  • Thư mục trong đường dẫn được thoát đúng với dấu ngoặc kép và có khoảng trắng và có dấu ngoặc đơn = ERROR

Những gì đang xảy ra ở đây? Làm thế nào tôi có thể sửa lỗi này? Có lẽ tôi sẽ dùng đến một điểm giao nhau để cho các công cụ của tôi vẫn hoạt động như một cách giải quyết, nhưng nếu bạn có cái nhìn sâu sắc về vấn đề này, xin vui lòng cho tôi biết :)


Dựa trên sự hiểu biết của tôi về các vấn đề hiện tại, câu trả lời ở trên là câu trả lời đúng và nó dựa vào việc tính đến việc SET là lệnh và PATH là một phần trong đối số của nó, số dư là chuỗi PATH mới. Vì vậy, IMO, nó không phải là tài liệu thưa thớt, mà nó giống như một trường hợp cạnh khó hiểu. Tôi mới dành vài giờ cho vấn đề này.
David A. Gray

Câu trả lời:


13

Điều này có thể xảy ra nếu có các dấu ngoặc đơn không thoát trong một dòng bên trong một "khối" (cũng sử dụng dấu ngoặc đơn để phân định).

Bạn thường có thể sửa nó bằng cách bật mở rộng bị trì hoãn và sử dụng các biến !var!thay vì %var%. Tôi không thể đưa ra nhiều lời khuyên mà không cần xem mã.



13

Không nên có (a) không có bất kỳ dấu ngoặc kép nào trong biến môi trường MS-Windows PATH (lệnh PATH) hoặc (b) nên có các trích dẫn xung quanh toàn bộ biểu thức theo lệnh (lệnh SET) . Thật không may, điều này không được tài liệu rất tốt bởi MS, mặc dù họ nói rằng nếu sử dụng dấu ngoặc kép, chúng sẽ được bao gồm trong giá trị của biến (Tham chiếu dòng lệnh Windows XP) .

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

Điều này có thể gây ra vấn đề không nhất quán và do đó khó chẩn đoán. Ví dụ: nếu đường dẫn của bạn bao gồm "C: \ Python27", máy của bạn sẽ nói "'python' không được nhận dạng dưới dạng lệnh nội bộ hoặc bên ngoài, chương trình có thể hoạt động hoặc tệp bó." khi bạn cố gắng thực thi python. Tuy nhiên một số thư viện có thể vẫn có sẵn.

Bạn không cần phải "thoát" khoảng trắng hoặc dấu ngoặc đơn. Nếu bạn cần thoát các ký tự đặc biệt, sau đó đặt dấu ngoặc kép quanh toàn bộ biểu thức, bao gồm cả tên biến.

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

hoặc bạn có thể sử dụng dấu ngoặc đơn quá.

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

Lưu ý, dấu ngoặc kép phải đi theo cặp.

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

Tuy nhiên, có lẽ không có bất kỳ ký tự nào là tên đường dẫn hợp lệ, điều đó sẽ gây ra sự cố với lệnh SET.



1
Bạn thực sự đã viết MS-DOS khi bạn có nghĩa là MS-Windows và các lệnh của bạn là dành cho MS-Windows. OP đã hỏi về MS-Windows. Vậy tại sao bạn gọi nó là MS-DOS mà tôi không biết. Ngay cả các liên kết của bạn cũng nói NT (Đó là - Windows. Nó từng là 9X và NT, bây giờ chỉ là NT). Windows và MS-DOS là hai hệ điều hành khác nhau. Tôi đã thấy dấu nhắc lệnh windows bị gọi nhầm là DOS trước đây, nhưng thậm chí điều đó không sai như những gì bạn gọi nó.
barlop

@barlop, tất nhiên là bạn đúng rồi. Cảm ơn các chỉnh sửa. Cho đến Windows-95, Windows là một ứng dụng được xây dựng dựa trên DOS. Bạn có thể khởi động Windows bằng cách gõ winlệnh trong DOS. Trong thực tế trước Windows-3.1, mọi thứ, như Zork và Wordstar đều là các ứng dụng DOS. Sau đó, bắt đầu với Windows-98, không có DOS. Nhưng tôi nghĩ rằng một số bộ tính giờ cũ như tôi vẫn gọi nhầm vỏ shell là nhầm lẫn với vỏ DOS. Xin lỗi vì sự nhầm lẫn, và cảm ơn lần nữa vì đã làm rõ ý định trả lời của tôi.
Đánh dấu Mikofski

@MarkMikofski Trên thực tế, Windows 9X (95/98 / ME) cũng được xây dựng trên DOS. Ví dụ, bạn có thể chỉnh sửa một số tệp (có thể là msdos.sys) một số tùy chọn như bootGUI = 0 và dừng các cửa sổ tải tokyopc.org/newsletter/1996/08/msdoses.html Cho dù bạn có thể tải các cửa sổ từ đó tôi không ' t biết Và một đĩa khởi động Win9X được coi là DOS. Các bộ tính giờ cũ biết bạn đang nói về điều gì, thường là những người cuối cùng mắc lỗi khi gọi lệnh cửa sổ nhắc DOS. Và là những người đầu tiên kiên quyết nhất rằng đó không phải là DOS.
barlop

1
Bạn đã thử khuyên (SET PATH=%PATH%;C:\Program Files (x86)\path with special characters)chưa? Điều đó hoàn toàn sai!
JosefZ

2

Microsoft ghi lại sự cố trong " Lỗi khi chạy tập lệnh shell lệnh bao gồm dấu ngoặc đơn ".

Giải pháp họ đề xuất là sử dụng mở rộng chậm trễ.

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

Để đặt đường dẫn trong khối if, thay vì sử dụng SET PATH=, có lẽ bạn nên sử dụng PATHlệnh.

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

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

Đối với các biến khác, một giải pháp khác có thể là sử dụng dấu ngoặc kép, nhưng xung quanh toàn bộ:

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

1

Joey trong câu trả lời của mình nói

Điều này có thể xảy ra nếu có các dấu ngoặc đơn không thoát trong một dòng bên trong một "khối" (cũng sử dụng dấu ngoặc đơn để phân định).

và đó là sự thật. Nếu có dấu ngoặc đơn không được giải thoát, thì nên thoát khỏi chúng. Đó là những gì tôi đã làm; tôi đã thay thế

set PATH=some_path;%PATH%

với

set PATH="some_path;%PATH%"

và điều này đã giải quyết vấn đề.


2
Không. Bạn nên sử dụngset "PATH=some_path;%PATH%"
JosefZ 7/11/2015

1

Tôi đã trải nghiệm một cái gì đó tương tự. Microsoft giải thích vấn đề ở đây: http://support.microsoft.com/kb/329308

Về cơ bản, thay vì thay đổi biến Đường dẫn qua Hệ thống-> Cài đặt Adv-> Env Vars-> System-> PATH, hãy thử

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

1

Trong Windows 8, tôi đã tìm thấy rất ít thành công với bất kỳ phương pháp nào trong số này. Dấu ngoặc đơn không hoạt động, trích dẫn hoạt động, nhưng "đường dẫn" bạn sửa đổi theo cách này không phải là đường dẫn được sử dụng để định vị các tệp thực thi, thay vào đó cmddường như vẫn đang sử dụng đường dẫn hệ thống mà nó được kế thừa khi bạn mở cửa sổ.

Ví dụ: sau khi xác định kiến ​​trúc bộ xử lý, tôi muốn thêm một vài đường dẫn vào biến môi trường PATH. Trên thực tế, thậm chí chỉ cần thêm chúng tạm thời sẽ hoạt động vì tôi chỉ cần chúng trong khi một tệp bó đang chạy. Nhưng điều đó thậm chí không hoạt động.

echo %path%hiển thị hệ thống PATH tại thời điểm cmdra mắt.

set path="%path%;%programfiles(x86)%\company\program\subdir"hoạt động nhưng bây giờ %path%chứa mọi thứ được bao quanh bởi dấu ngoặc kép và nếu tôi cố chạy một chương trình trong thư mục con từ một nơi khác, nó sẽ thất bại. Sử dụng dấu ngoặc đơn xung quanh toàn bộ thay vì dấu ngoặc kép không hoạt động .

Một điều khác mà tôi nhận thấy là cùng một lệnh sẽ hoạt động nếu được nhập tương tác vào cmd, nhưng không gặp phải trong một tệp bó. Điều đó thật đáng sợ. Một điều kỳ lạ khác là sự mất liên tục của ký tự cuối cùng của giá trị của biến môi trường! Một sự không nhất quán khác là với các chương trình của bên thứ ba: một số có thể xử lý %var%như một tham số, một số khác thì không.


1

Tôi đã gặp rắc rối lớn khi thực hiện các công việc sau trong Win8 cho đến khi tôi thêm dấu ngoặc kép làm tăng giá trị mà tôi đã đặt thành từ biếnFile. Với điều đó, khi fromFile chứa một tên tệp có dấu ngoặc đơn, dòng tiếp theo đang cố gắng thay thế chuỗi để tạo biến toFile đã thất bại. Lưu ý rằng tôi sử dụng mở rộng bị trì hoãn ở đó để đánh giá biến tại thời điểm thực hiện thay vì tại thời điểm phân tích cú pháp (của ví dụ CALL tương ứng)

::-- 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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.