Spasi dan Parenthesis di windows Variabel PATH mengacaukan file batch


14

Jadi, variabel jalur saya (System-> Adv Settings-> Env Vars-> System-> PATH) diatur ke:

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;

Meskipun, jelas, tanpa baris baru.

Perhatikan garis yang mengandung PathWithSpaces- yang pertama tidak memiliki spasi, yang kedua memiliki spasi, dan yang ketiga memiliki spasi diikuti oleh tanda kurung.

Sekarang, perhatikan output dari file batch ini:

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

atau secara khusus garis:

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

Jadi, omong kosong apa ini?

Secara khusus:

  • Direktori di jalur yang diloloskan dengan benar dengan tanda kutip, tetapi tanpa spasi = baik
  • Direktori di jalur yang diloloskan dengan benar dengan tanda kutip, dan memiliki spasi tetapi tanpa tanda kurung = baik
  • Direktori di jalur yang diloloskan dengan benar dengan tanda kutip, dan memiliki spasi dan memiliki tanda kurung = ERROR

Apa yang terjadi di sini? Bagaimana saya bisa memperbaikinya? Saya mungkin akan menggunakan titik persimpangan untuk membiarkan alat saya masih berfungsi sebagai solusi, tetapi jika Anda memiliki wawasan tentang ini, tolong beri tahu saya :)


Berdasarkan pemahaman saya tentang masalah yang dihadapi, jawaban di atas adalah yang benar, dan itu bergantung pada memperhitungkan bahwa SET adalah perintah, dan PATH adalah bagian dari argumennya, yang sisanya adalah string PATH baru. Jadi, IMO, bukan karena jarang didokumentasikan, tetapi lebih seperti kasus tepi yang tidak jelas. Saya baru saja menghabiskan beberapa jam untuk masalah ini.
David A. Gray

Jawaban:


13

Ini bisa terjadi jika ada tanda kurung yang tidak dilepas dalam garis di dalam "blok" (yang juga menggunakan tanda kurung untuk membatasi).

Anda biasanya dapat memperbaikinya dengan mengaktifkan ekspansi yang tertunda dan menggunakan variabel dengan !var!sebagai gantinya %var%. Tidak banyak saran yang bisa saya berikan tanpa melihat kode.



13

Seharusnya (a) tidak ada tanda kutip di variabel lingkungan MS-Windows PATH (perintah PATH) atau (b) harus ada tanda kutip yang mengelilingi seluruh ekspresi mengikuti (perintah SET) . Sayangnya, ini tidak didokumentasikan dengan baik oleh MS, meskipun mereka menyatakan bahwa jika tanda kutip digunakan, mereka akan dimasukkan dalam nilai variabel (Referensi Baris Perintah Windows XP) .

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

Ini dapat menyebabkan masalah yang tidak konsisten dan karenanya sulit didiagnosis. Misalnya jika jalur Anda menyertakan "C: \ Python27", mesin Anda akan mengatakan "'python' tidak dikenali sebagai perintah internal atau eksternal, program yang dapat dijalankan atau file batch." ketika Anda mencoba menjalankan python. Namun beberapa perpustakaan mungkin masih tersedia.

Anda tidak perlu "melarikan diri" spasi atau tanda kurung. Jika Anda perlu keluar dari karakter khusus, maka beri tanda kutip di seluruh ekspresi, termasuk nama variabel.

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

atau Anda juga bisa menggunakan tanda kurung.

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

Catatan, tanda kutip ganda harus datang berpasangan.

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

Namun, mungkin tidak ada karakter apa pun yang merupakan nama jalur yang valid, yang akan menyebabkan masalah dengan perintah SET.



1
Anda benar-benar menulis MS-DOS ketika Anda bermaksud MS-Windows, dan perintah Anda adalah untuk MS-Windows. OP memang bertanya tentang MS-Windows. Jadi mengapa Anda menyebutnya MS-DOS saya tidak tahu. Bahkan tautan Anda mengatakan NT (Yaitu - Windows. Dulu 9X dan NT, sekarang hanya NT). Windows dan MS-DOS adalah dua sistem operasi yang berbeda. Saya telah melihat prompt perintah windows yang keliru disebut DOS sebelumnya, tetapi bahkan itu tidak salah seperti apa yang Anda sebut itu.
barlop

@barlop, tentu saja Anda benar. Terima kasih atas hasil editnya. Hingga Windows-95, Windows adalah aplikasi yang dibangun di atas DOS. Anda dapat memulai Windows dengan mengetik winperintah di DOS. Sebenarnya sebelum Windows-3.1, semuanya, seperti Zork dan WordStar adalah aplikasi DOS. Kemudian mulai dengan Windows-98, tidak ada DOS. Tapi saya pikir beberapa timer lama seperti saya masih merujuk ke shell CMD yang keliru sebagai shell DOS. Maaf atas kebingungannya, dan terima kasih lagi karena telah menjelaskan maksud jawaban saya.
Mark Mikofski

@MarkMikofski Sebenarnya Windows 9X (95/98 / ME) bisa dibilang dibangun di DOS juga. Misalnya Anda dapat mengedit beberapa file (mungkin msdos.sys) beberapa opsi seperti bootGUI = 0 dan menghentikan windows memuat tokyopc.org/newsletter/1996/08/msdosed.html Apakah Anda dapat memuat windows dari sana saya tidak saya tidak tahu. Dan disk boot Win9X dianggap DOS. Timer lama yang tahu apa yang mereka bicarakan saat Anda lakukan, biasanya adalah orang terakhir yang melakukan kesalahan dengan memanggil perintah windows prompt DOS. Dan apakah orang pertama yang paling bersikeras bahwa itu bukan DOS.
barlop

1
Apakah Anda mencoba memberi saran (SET PATH=%PATH%;C:\Program Files (x86)\path with special characters)? Benar-benar salah!
JosefZ

2

Microsoft mendokumentasikan masalah dalam " Kesalahan menjalankan skrip shell perintah yang menyertakan tanda kurung ".

Solusi yang mereka sarankan adalah menggunakan ekspansi yang tertunda.

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

Untuk mengatur jalur di blok if, daripada menggunakan SET PATH=, Anda mungkin harus menggunakan PATHperintah.

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

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

Untuk variabel lain, solusi lain mungkin menggunakan tanda kutip, tetapi di sekitar semuanya:

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

1

Joey dalam jawabannya berkata

Ini bisa terjadi jika ada tanda kurung yang tidak dilepas dalam garis di dalam "blok" (yang juga menggunakan tanda kurung untuk membatasi).

dan itu benar. Jika ada tanda kurung yang tidak boleh dilepas, kita harus menghindarinya. Itu yang saya lakukan; Saya diganti

set PATH=some_path;%PATH%

dengan

set PATH="some_path;%PATH%"

dan ini memecahkan masalah.


2
Nggak. Anda harus menggunakanset "PATH=some_path;%PATH%"
JosefZ

1

Saya pernah mengalami hal serupa. Microsoft menjelaskan masalah ini di sini: http://support.microsoft.com/kb/329308

Pada dasarnya, alih-alih mengubah variabel Path melalui System-> Adv Settings-> Env Vars-> System-> PATH, coba

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

1

Di Windows 8 saya menemukan sedikit keberhasilan dengan salah satu metode ini. Tanda kurung tidak berfungsi, kutipan berfungsi, tetapi "jalur" yang Anda modifikasi dengan cara ini bukanlah jalur yang digunakan untuk mencari executable, sebaliknya cmdtampaknya masih menggunakan jalur sistem yang diwarisi ketika Anda membuka jendela.

contoh: setelah menentukan arsitektur prosesor, saya ingin menambahkan beberapa jalur ke variabel lingkungan PATH. Sebenarnya, bahkan hanya menambahkan mereka sementara akan bekerja karena saya hanya membutuhkannya saat file batch sedang berjalan. Tetapi itu bahkan tidak berhasil.

echo %path%menampilkan PATH sistem pada saat cmddiluncurkan.

set path="%path%;%programfiles(x86)%\company\program\subdir"berfungsi tetapi sekarang %path%berisi semua yang dikelilingi oleh tanda kutip, dan jika saya mencoba menjalankan sebuah program di subdir dari tempat lain, itu gagal. Menggunakan tanda kurung di sekitar semuanya alih-alih tanda kutip tidak berfungsi .

Hal lain yang saya perhatikan adalah bahwa perintah yang sama akan bekerja jika dimasukkan secara interaktif cmd, tetapi tidak jika ditemui dalam file batch. Itu menakutkan. Namun keanehan lainnya adalah hilangnya karakter terakhir dari nilai variabel lingkungan secara intermiten! Inkonsistensi lain adalah dengan program pihak ketiga: beberapa dapat menangani %var%sebagai parameter, yang lain tidak.


1

Saya memiliki masalah besar membuat pekerjaan berikut di Win8 sampai saya menambahkan tanda kutip ganda di sekitar nilai yang saya atur ke fromFile variabel. Tanpa itu, ketika fromFile berisi nama file dengan tanda kurung, baris berikutnya yang mencoba melakukan substitusi string untuk menghasilkan variabel toFile gagal. Perhatikan bahwa saya menggunakan ekspansi yang tertunda di sana untuk mengevaluasi variabel pada waktu eksekusi alih-alih pada waktu penguraian (masing-masing instance 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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.