Bagaimana Anda menghindari kelebihan populasi Variabel Lingkungan PATH di Windows?

115

Saya ingin tahu apa saja pendekatan yang Anda gunakan untuk mengelola executable di sistem Anda. Misalnya saya memiliki hampir semua yang dapat diakses melalui baris perintah, tetapi sekarang saya sampai pada batas string jalur, jadi saya tidak dapat menambahkan dir lagi.

Jadi apa yang Anda rekomendasikan? Dahulu kala, saya mencoba menggunakan softLink dari executable di Dir yang termasuk dalam jalur, tetapi pendekatan itu tidak berhasil. Lempar "hanya dapat dieksekusi" ke Dir yang dikenal, memiliki masalah yang hampir semua aplikasi memerlukan satu set file, jadi ini juga buruk. Buang file yang dapat dieksekusi dan semua file-nya ke Dir yang dikenal, mmm ini akan berhasil, tetapi kemungkinan untuk mendapatkan konflik dalam nama file sangat tinggi. Buat HardLink? saya tidak tahu Bagaimana menurut anda?

mjsr
sumber
mengapa Anda menggunakan begitu banyak jalur? path biasanya digunakan untuk dir umum, ketika aplikasi Anda harus berbagi extended object / app / lib dengan orang lain. Gunakan begitu banyak membuat aplikasi mulai lebih lambat. Bisakah Anda memberikan detail lebih lanjut tentang cara Anda menggunakan, membuat path environment var?
pinichi
1
hai pinichi, banyak aplikasi yang menggunakan standar "C: \ Program File \ AppNAme \ ...", dan dalam kasus saya, banyak aplikasi ini dapat berjalan dalam mode baris perintah atau perlu diakses oleh aplikasi lain ( misalnya executable Miktex yang diharapkan oleh editor Tex mana pun), jadi mereka harus berada di PATH. Saya tidak ingin tahu pendekatan yang lebih baik karena pendekatan saya tidak berkelanjutan
mjsr
1
Alat ini akan memampatkan jalur. Hasilnya sangat mengesankan: uweraabe.de/Blog/2014/09/09/the-garbled-path-variable/#more-337
InTheNameOfScience

Jawaban:

84

Salah satu cara yang bisa saya pikirkan adalah menggunakan variabel lingkungan lain untuk menyimpan jalur parsial; misalnya, jika Anda punya

C:\this_is_a\long_path\that_appears\in_multiple_places\subdir1;
C:\this_is_a\long_path\that_appears\in_multiple_places\subdir2;

maka Anda dapat membuat variabel lingkungan baru seperti

SET P1=C:\this_is_a\long_path\that_appears\in_multiple_places

setelah itu jalan awal Anda menjadi

%P1%\subdir1;
%P1%\subdir2;

EDIT: Pilihan lain adalah membuat bindirektori yang menyimpan .batfile yang mengarah ke .exefile yang sesuai .

EDIT 2: Komentar Ben Voigt untuk jawaban lain menyebutkan bahwa menggunakan variabel lingkungan lain seperti yang disarankan mungkin tidak mengurangi panjangnya %PATH%karena mereka akan diperluas sebelum disimpan. Ini mungkin benar dan saya belum mengujinya. Pilihan lain adalah menggunakan formulir 8dot3 untuk nama direktori yang lebih panjang, misalnya C:\Program Filesbiasanya sama dengan C:\PROGRA~1. Anda dapat menggunakan dir /xuntuk melihat nama yang lebih pendek.

EDIT 3: Tes sederhana ini membuat saya percaya Ben Voigt benar.

set test1=hello
set test2=%test1%hello
set test1=bye
echo %test2%

Di akhir ini, Anda akan melihat keluaran hellohellodaripada byehello.

EDIT 4: Jika Anda memutuskan untuk menggunakan file batch untuk menghilangkan jalur tertentu dari %PATH%, Anda mungkin khawatir tentang cara menyampaikan argumen dari file batch Anda ke file yang dapat dieksekusi sehingga prosesnya transparan (yaitu, Anda tidak akan melihat perbedaan apa pun antara memanggil file batch dan memanggil executable). Saya tidak memiliki banyak pengalaman menulis file batch, tetapi ini tampaknya berfungsi dengan baik.

@echo off

rem This batch file points to an executable of the same name
rem that is located in another directory. Specify the directory
rem here:

set actualdir=c:\this_is\an_example_path

rem You do not need to change anything that follows.

set actualfile=%0
set args=%1
:beginloop
if "%1" == "" goto endloop
shift
set args=%args% %1
goto beginloop
:endloop
%actualdir%\%actualfile% %args%

Sebagai aturan umum, Anda harus berhati-hati dalam menjalankan file batch dari internet, karena Anda dapat melakukan segala macam hal dengan file batch seperti memformat hard drive Anda. Jika Anda tidak mempercayai kode di atas (yang saya tulis), Anda dapat mengujinya dengan mengganti baris

%actualdir%\%actualfile% %args%

dengan

echo %actualdir%\%actualfile% %args%

Idealnya Anda harus tahu persis apa yang dilakukan setiap baris sebelum Anda menjalankannya.

Mitch Schwartz
sumber
1
bentuk 8dot3 berfungsi dengan baik, tetapi untuk direktori yang sangat besar tidak terlalu bagus, misalnya "C: \ Program Files (x86) \ Microsoft Visual Studio 2008 SDK \ VisualStudioIntegration \ Tools \ Sandcastle \ ProductionTools \". Hal lain yang menghemat sedikit adalah bahwa sebagai pengguna saya dapat membuat variabel PATH berbasis di Jalur Sistem, dan menambahkan Dir lainnya. Semua pendekatan ini berjenis "memadatkan string itu", tetapi dapatkah kita memiliki direktori biner terpusat, seperti halnya Unix?
mjsr
1
Hmm, mengenai direktori yang sangat panjang, menurut saya yang terjadi adalah sebaliknya: semakin panjang direktori, semakin banyak karakter yang Anda simpan dengan menggunakan format 8dot3. Jika sulit dinavigasi cmd, perhatikan bahwa Anda dapat menggunakan *untuk menyimpan pengetikan. Jadi misalnya, dari root, ketik dir /x pro*. Anda akan melihat direktori yang Anda inginkan di sana bersama dengan nama 8dot3-nya. Kemudian gunakan cduntuk menavigasi ke sana dan ulangi prosesnya.
Mitch Schwartz
1
Mengenai UNIX, ada $PATHyang bekerja sangat mirip dengan %PATH%di Windows, jadi saya tidak yakin apa maksud Anda sebenarnya. Sesuai ketentuan, nama direktori UNIX cenderung lebih pendek daripada di Windows, dan akibatnya $PATHjuga cenderung lebih pendek.
Mitch Schwartz
2
Terima kasih Mitch, Edit 4 yang Anda berikan adalah apa yang saya inginkan!, Sekarang saya dapat memiliki folder terpusat dengan semua binari yang saya butuhkan. Saya akan menguji lebih dalam untuk melihat apakah ada masalah dengan beberapa aplikasi
mjsr
2
Bagian 'edit 4' Anda terlalu rumit untuk menyampaikan argumen ke executable. Lihat jawaban Michael Burr.
Dave Andersen
83

Ini akan mengurai variabel lingkungan% PATH% Anda dan mengubah setiap direktori menjadi nama pendek yang setara dan kemudian menyatukannya kembali:

@echo off

SET MyPath=%PATH%
echo %MyPath%
echo --

setlocal EnableDelayedExpansion

SET TempPath="%MyPath:;=";"%"
SET var=
FOR %%a IN (%TempPath%) DO (
    IF exist %%~sa (
        SET "var=!var!;%%~sa"
    ) ELSE (
        echo %%a does not exist
    )
)

echo --
echo !var:~1!

Ambil output dan perbarui variabel PATH dalam variabel lingkungan.

Todd Smith
sumber
Terima kasih itu sangat berguna !! Itu mempersingkat jalan saya dari tahun 1990 menjadi 1338 dan semuanya masih berfungsi seperti pesona! Saya memilih pendekatan Anda karena saya ingin menyimpan semuanya di jalur saya dan penautan melalui file batch akan terlalu memakan waktu. TERIMA KASIH!
ndrizza
2
Ini juga berguna karena memberi tahu saya tentang semua direktori yang tidak ada di jalur saya yang telah terakumulasi dari waktu ke waktu.
Nate Glenn
27
Rapid Environment Editor adalah cara lain untuk melakukan ini. Ini menyoroti direktori yang tidak ada dan memiliki opsi "ubah jalur panjang menjadi pendek".
Russell Gallop
3
@RussellGallop: itu, Pak, adalah alat yang luar biasa.
elo80ka
1
Catat kutipan penutup yang hilang setelahnya %%~sa. Saya mencoba memperbarui jawabannya tetapi tidak mengizinkan saya kecuali saya mengubah 6 karakter
zr870
28

jika Anda menggunakan windows vista atau lebih tinggi, Anda dapat membuat tautan simbolis ke folder tersebut. sebagai contoh:

mklink /d C:\pf "C:\Program Files"

akan membuat link jadi folder c:\pfAnda program files. Saya memangkas 300 karakter dari jalur saya dengan menggunakan trik ini.

bmg002
sumber
Ini adalah alternatif yang bagus untuk menggunakan variabel lingkungan untuk mewakili jalur parsial.
porcus
1
Ini pasti akan lebih membantu, tetapi jika Anda ingin solusi yang lebih "benar" (didukung?), Anda dapat mengganti contoh c:\Program Filesdan c:\Program Files (x86)dengan variabel yang telah ditentukan sebelumnya %ProgramFiles%dan %ProgramFiles(x86)% tenforums.com/tutorials/… Ini hanya menyimpan beberapa karakter , tetapi jika Anda BENAR-BENAR hampir memaksimalkan PATH, itu bisa menjadi perbedaannya. Untuk masalah itu, saya akan membuat% pf% dan% pfx% yang menyelesaikan jalur yang benar. Terima kasih atas idenya! :)
rainabba
Masalah dengan menggunakan variabel seperti% pf% dan% pfx% adalah Anda mendapatkan masalah yang sama seperti membuat tautan simbolik - pembaruan perangkat lunak dapat menambahkan hal-hal lagi ke variabel jalur. Masalah lain dengan menggunakan variabel seperti itu adalah tidak cepat dan mudah untuk membuat skrip di sekitarnya atau menjelajahinya dari penjelajah. Dengan menggunakan metode yang saya jelaskan, Anda benar-benar dapat membuka c: \ PF. Windows melihatnya seperti folder sehingga Anda dapat menulis bat atau PowerShell terhadapnya dengan mudah juga.
bmg002
10

Jika ada yang tertarik ...

Saya merasa saya tidak pernah benar-benar membutuhkan semua jalur tersebut sekaligus, jadi saya membuat sekumpulan file batch "inisialisasi" yang memodifikasi jalur yang sesuai.

Misalnya, jika saya ingin melakukan pengembangan C ++ di Eclipse, saya akan melakukan:

> initmingw
> initeclipse
> eclipse

Ini juga berguna untuk menghindari konflik antara file yang dapat dieksekusi dengan nama yang sama (seperti kompiler C ++ dan D, yang keduanya memiliki make.exe).

File batch saya biasanya terlihat seperti ini:

@echo off
set PATH=C:\Path\To\My\Stuff1;%PATH%
set PATH=C:\Path\To\My\Stuff2;%PATH%

Saya menemukan pendekatan ini relatif bersih dan belum mengalami masalah.

YellPika
sumber
7

Saya biasanya tidak perlu khawatir tentang ini (saya belum mengalami batas ukuran jalur - saya bahkan tidak tahu apa yang ada di sistem Windows modern), tetapi inilah yang mungkin saya lakukan untuk menghindari meletakkan direktori program di jalan:

  • sebagian besar utilitas baris perintah dimasukkan ke dalam c:\utildirektori yang berada di jalur tersebut
  • jika tidak, saya akan menambahkan file cmd / batch sederhana ke c:\utildirektori yang terlihat seperti:

    @"c:\program files\whereever\foo.exe" %*
    

yang pada dasarnya membuat alias untuk perintah tersebut. Itu belum tentu sempurna. Beberapa program benar-benar bersikeras untuk berada di jalur (yang sangat jarang saat ini), dan program lain yang mencoba menjalankannya mungkin tidak menemukannya dengan benar. Tetapi untuk sebagian besar kegunaan itu bekerja dengan baik.

Tetapi secara umum, saya tidak perlu khawatir tentang menghindari penambahan direktori ke path.

Michael Burr
sumber
Ketika Anda mulai mengikuti "jalur" ini, berhati-hatilah bahwa skrip batch tidak dapat memanggil skrip batch lain tanpa sintaks "CALL [bat]". Jadi, jika Anda ingin memastikan exe yang diteruskan atau tidak dipanggil dari sebuah kelelawar, gunakan "panggil php script.php" alih-alih hanya "php script.php" (yang berfungsi dua arah). operator kelelawar adalah untuk mencegah konflik nama PATH (versi kelipatan dari exe yang sama)
131
@ 131: Maukah Anda menjelaskan apa yang Anda maksud dengan '"jalan" ini? Apakah yang Anda maksud jalur file tertentu dari contoh tersebut? Atau lebih tepatnya metode umum yang disarankan oleh jawaban ini?
ATAU Mapper
@ORMapper: ketika 131 berkata, 'Ketika Anda mulai mengikuti "jalan" ini', yang dia maksud adalah, 'Ketika Anda menggunakan teknik ini'.
Michael Burr
1
Saat Anda menulis, "program lain yang mencoba memanggilnya mungkin tidak menemukannya dengan benar" - contoh kasus: Sayangnya, program ini dapat mengirim panggilan otomatis ke aplikasi baris perintah, misalnya dengan alat build seperti NAnt, tentunya. Pemulihannya adalah menjalankan perintah dengan prepended cmd /c, tetapi itu berarti skrip build menjadi khusus Windows: / Saya telah menanyakannya di pertanyaan terpisah .
ATAU Mapper
5

Ide lain: Gunakan DIR / X untuk menentukan nama pendek yang dihasilkan untuk nama file non-8dot3. Kemudian gunakan ini di% PATH% Anda.

Misalnya, 'C: \ Program Files' menjadi 'C: \ PROGRA ~ 1'.

Android Eve
sumber
1
Ups, saya baru menyadari ini sudah disarankan oleh @Mitch. Saya akan memberinya +1 untuk itu. :)
Android Eve
2

Saya menulis dan menggunakan setiap waktu aliran standar (stdin / stderr / stdout) & kode keluar program PROXY (disebut dispatcher https://github.com/131/dispatcher )

Semua program CLI yang saya gunakan (node, php, python, git, svn, rsync, plink ...) yang saya gunakan sebenarnya adalah file exe yang sama (sekitar 10kb, yang saya beri nama berbeda), yang saya masukkan sama direktori. File teks bening statis tiruan melakukan "nama file proxy untuk pemetaan exe nyata".

Dispatcher menggunakan Process management win32 API tingkat rendah agar sepenuhnya transparan.

Dengan menggunakan software ini, saya hanya memiliki SATU direktori tambahan yang diatur di PATH saya untuk semua program yang mungkin saya gunakan.

131
sumber
1

Membuat folder c: \ bin menambahkan ke jalur Anda dan tautan keras seperti yang Anda katakan dapat mempersingkat string. Mungkin menambahkan variabel pf ke sistem vars dengan nilai c: \ Program Files lalu ganti c: \ Program Files dengan% pf% di jalur.

Edit:

Buat drive virtual. subst p: "c: \ program files"

troynt
sumber
1
Saya pikir jalur akan berisi variabel yang diperluas, dalam hal ini tidak akan menjadi lebih pendek.
Ben Voigt
0

Saya mengikuti langkah-langkah ini untuk membuat entri dapat dikelola:

  1. Dibuat pengguna yang berbeda untuk kombinasi penggunaan paket perangkat lunak yang berbeda. Contoh: (a) Membuat web pengguna untuk menyediakan semua perangkat lunak pengembangan web; (b) Membuat database pengguna untuk menyediakan semua paket perangkat lunak database dan data warehousing. Ingat beberapa perangkat lunak dapat membuat lebih dari satu entri. Atau kadang saya memecah ini menjadi pengguna khusus oracle dan khusus MSSQL dan oracle. Saya menempatkan MySQL / PostgreSQL, tomcat, wamp, xamp semua ke dalam akun pengguna webr.

  2. Jika memungkinkan, instal paket umum seperti office, photoshop, .. sebagai sistem khusus yang tersedia untuk semua pengguna dan paket khusus sesuai kebutuhan pengguna. Tentu saja saya harus masuk ke pengguna yang berbeda dan menginstalnya. Tidak semua perangkat lunak menyediakan opsi ini. Jika opsi "instal untuk pengguna ini saja" tidak tersedia, instal untuk seluruh sistem.

  3. Saya menghindari menginstal program ke folder Program File (x86) atau ke Program File. Saya selalu menginstal ke direktori dasar. Misalnya MySQL 64 bit masuk ke "C: \ mysql64" dan MySQL 32 bit masuk ke folder "C: \ mysql". Saya selalu menganggap menambahkan sufiks 64 hanya untuk perangkat lunak 64bit. Jika tidak ada sufiks, maka itu adalah 32 bit. Saya mengikuti hal yang sama ke Java dan lainnya. Dengan cara ini jalur saya akan lebih pendek, tidak termasuk "C: \ Program File (x86)". Untuk beberapa perangkat lunak, file konfigurasi mungkin perlu diedit untuk menunjukkan di mana tepatnya file .exe berada. Hanya program yang meminta untuk diinstal ke "C: \ Program File (x86)" yang akan diinstal ke folder itu. Saya selalu ingat untuk mempersingkat nama. Saya menghindari nomor versi seperti detail seperti tomcat / rilis / versi-2.5.0.3. Jika saya perlu tahu versi, Saya membuat file dengan versi nama dan memasukkannya ke dalam folder kucing jantan. Secara umum persingkat tautan sebanyak mungkin.

  4. Sertakan kumpulan apa pun untuk mengganti tautan yang disingkat ke jalur, jika semua langkah di atas melewati batas Windows.

Kemudian Masuk ke penggunaan khusus (aplikasi seluler, atau database / gudang data atau pengembangan web .. ..) pengguna dan lakukan tugas yang relevan.

Anda juga dapat membuat jendela virtual di dalam jendela. Selama Anda memiliki satu salinan OS berlisensi, membuat beberapa jendela virtual dengan kunci yang sama dimungkinkan. Anda dapat meletakkan paket khusus untuk tugas tertentu di mesin itu. Anda harus meluncurkan VM terpisah setiap kali. Beberapa paket intensif memori seperti pembuat film animasi 3D semuanya harus dimasukkan ke mesin utama, bukan ke VM karena VM hanya akan memiliki sebagian dari RAM yang tersedia untuk penggunaannya. Ini menyakitkan untuk mem-boot setiap VM.

Dr. A. Anukanth
sumber
0

Solusi di atas hanya berfungsi jika Anda dapat memangkas jalan Anda. Dalam kasus saya, itu sebenarnya bukan pilihan, dan itu merepotkan untuk menjalankan skrip setiap kali saya membuka prompt perintah. Jadi saya menulis skrip sederhana yang berjalan secara otomatis saat membuka command prompt, dan menambahkan konten file teks ke jalur Anda.

Ada juga beberapa konteks di mana menjalankan skrip ini merusak sesuatu (katakanlah, di github atau shell cygwin), jadi saya juga menambahkan file yang berisi daftar jalur yang, jika command prompt dimulai di dalamnya, variabel jalur isn tidak diubah melalui skrip startup yang biasanya memperbarui jalur.

@echo off

:: Modify these to the actual paths of these two files
set dontSetupFile=C:\Users\Yams\Dontsetup.txt
set pathFile=C:\Users\Yams\Path.txt

:: Retrieve the current path (for determining whether or not we should append to our path)
set curDir=%cd%

:: Be done if the current path is listed in the dontSetupFile
SetLocal EnableDelayedExpansion
for /F "delims=" %%i in (%dontSetupFile%) do (
    if "%%i"=="%curDir%" GOTO AllDone
)



:: Append the pathFile to our current PATH
set pathAppend=
for /F "delims=" %%i in (%pathFile%) do (set pathAppend=!pathAppend!%%i)

set PATH=%PATH%;%pathAppend%


:: The only way to actually modify a command prompt's path via a batch file is by starting
::   up another command prompt window. So we will do this, however, if this script is
::   automatically called on startup of any command prompt window, it will infinately 
::   recurse and bad things will happen.

:: If we already ran, we are done
if "%yams%"=="onion" GOTO AllDone

:: Otherwise, flag that we just ran, and then start up a new command prompt window
::   with this flag set
set yams=onion

cmd \K set PATH=%PATH%;

:: When that command prompt exits, it will load back up this command prompt window, and
::   then the user will need to exit out of this as well. This causes this window to
::   automatically exit once the cmd it just spawned is closed.
exit()

:: Path is set up, we are done!
:AllDone
@echo on

Dan Path.txt akan terlihat seperti ini

C:\Program Files (x86)\Google\google_appengine;
C:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static;
C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;
C:\Program Files\Microsoft SQL Server\110\Tools\Binn;
C:\Program Files\Microsoft DNX\Dnvm;
C:\Program Files (x86)\Windows Kits\8.0\Windows Performance Toolkit;

Sedangkan Dontsetup.txt akan terlihat seperti

C:\Program Files (x86)\Windows Kits\8.0\Windows Performance Toolkit
C:\Program Files (x86)\Git\cmd
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin

Untuk membuat ini berjalan secara otomatis saat startup, buka regedit, arahkan ke HKEY_LOCAL_MACHINE / SOFTWARE / Microsoft / Command Processor, lalu klik kanan di sebelah kanan dan tekan new -> Multi-String Value. Beri nama AutoRun. Setel nilainya menjadi

C:\Users\Yams\setUpPath.bat

atau di mana pun Anda menyimpan file batch di atas.

Phylliida
sumber
0

Tidak mencobanya, tetapi akankah memisahkan PATH menjadi beberapa bagian berfungsi dan menggabungkannya dalam pekerjaan variabel akhir?

Contoh awalnya katakanlah Anda memiliki sesuatu seperti

PATH={LONGPATH1};{LONGPATH2};....{2048th char}....{LONGPATH_N-1};{LONGPATH_N}

Sebagai gantinya Anda membuat:

_PATH1 = {LONGPATH1};{LONGPATH2};....{2048 char}
_PATH2 = {2049th char}...{LONGPATH_N-1};{LONGPATH_N}
rem // may be more parts
PATH = %_PATH1%;%_PATH2%
Philipp Munin
sumber