Come si evita di riempire eccessivamente la variabile d'ambiente PATH in Windows?


115

Vorrei sapere quali sono gli approcci che utilizzi per gestire gli eseguibili nel tuo sistema. Ad esempio ho quasi tutto accessibile tramite la riga di comando, ma ora arrivo al limite della stringa del percorso, quindi non posso aggiungere più dir.

Allora cosa mi consigliate? Molto tempo fa, ho provato a utilizzare i softLink degli eseguibili in una directory che apparteneva al percorso, ma tale approccio non ha funzionato. Lancia "solo eseguibile" in una directory nota, ha i problemi che quasi tutte le applicazioni richiedono un set di file, quindi anche questo è un male. Getta l'eseguibile e tutti i suoi file in una directory nota, mmm funzionerà, ma la possibilità di ottenere un conflitto nel nome dei file è molto alta. Creare un collegamento fisso? Non lo so. Cosa ne pensi?


perchè usi così tanti percorsi? Il percorso viene solitamente utilizzato per la directory comune, quando la tua app deve condividere oggetto di estensione / app / lib con altri. Usa così tanto per far partire l'app più lentamente. Puoi fornire maggiori dettagli su come utilizzi, create path environment var?
pinichi

1
ciao pinichi, beh, molte applicazioni usano lo standard "C: \ Program File \ AppNAme \ ...", e nel mio caso molte di queste applicazioni possono essere eseguite in modalità da riga di comando o devono essere accessibili ad altre app ( per esempio gli eseguibili di Miktex che qualsiasi editor di Tex si aspetta che esistano), quindi devono essere nel PERCORSO. Non voglio conoscere un approccio migliore perché il mio è insostenibile
mjsr

1
Questo strumento comprimerà i percorsi. Il risultato è impressionante: uweraabe.de/Blog/2014/09/09/the-garbled-path-variable/#more-337
InTheNameOfScience

Risposte:


84

Un modo a cui posso pensare è usare altre variabili di ambiente per memorizzare percorsi parziali; ad esempio, se hai

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

quindi puoi creare una nuova variabile d'ambiente come

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

dopo di che diventano i tuoi percorsi originali

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

EDIT: un'altra opzione è creare una bindirectory che contenga .batfile che puntano ai .exefile appropriati .

EDIT 2: il commento di Ben Voigt a un'altra risposta afferma che l'utilizzo di altre variabili di ambiente come suggerito potrebbe non ridurre la lunghezza di %PATH%perché verrebbero espanse prima di essere archiviate. Questo potrebbe essere vero e non l'ho testato. Un'altra opzione è usare i moduli 8dot3 per nomi di directory più lunghi, ad esempio C:\Program Filesè tipicamente equivalente a C:\PROGRA~1. Puoi usare dir /xper vedere i nomi più brevi.

EDIT 3: Questo semplice test mi porta a credere che Ben Voigt abbia ragione.

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

Alla fine di questo, vedrai output hellohelloinvece di byehello.

MODIFICA 4: Nel caso in cui decidi di utilizzare file batch per eliminare determinati percorsi %PATH%, potresti essere preoccupato di come trasmettere argomenti dal tuo file batch al tuo eseguibile in modo che il processo sia trasparente (cioè, non noterai alcuna differenza tra la chiamata del file batch e la chiamata dell'eseguibile). Non ho molta esperienza nella scrittura di file batch, ma sembra funzionare bene.

@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%

Come regola generale, dovresti stare attento all'esecuzione di file batch da Internet, poiché puoi fare ogni genere di cose con i file batch come la formattazione del tuo disco rigido. Se non ti fidi del codice sopra (che ho scritto), puoi testarlo sostituendo la riga

%actualdir%\%actualfile% %args%

con

echo %actualdir%\%actualfile% %args%

Idealmente dovresti sapere esattamente cosa fa ogni riga prima di eseguirla.


1
il modulo 8dot3 funziona bene, ma per directory veramente grandi non è troppo grande, ad esempio "C: \ Program Files (x86) \ Microsoft Visual Studio 2008 SDK \ VisualStudioIntegration \ Tools \ Sandcastle \ ProductionTools \". Un'altra cosa che fa risparmiare un po 'è che come utente potevo creare una variabile PATH basata sul percorso di sistema e aggiungere qualsiasi altra directory. Tutti questi approcci sono del tipo "compatta quella stringa", ma possiamo avere una directory centralizzata di binari, come ha Unix?
mjsr

1
Hmm, per quanto riguarda directory molto lunghe, penso sia vero il contrario: più lunga è la directory, più caratteri si salvano utilizzando il formato 8dot3. Se è difficile navigare cmd, tieni presente che puoi usare *per salvare la digitazione. Quindi, ad esempio, da root, digita dir /x pro*. Vedrai la directory desiderata lì insieme al suo nome 8dot3. Quindi utilizzare cdper accedere ad esso e ripetere il processo.
Mitch Schwartz

1
Per quanto riguarda UNIX, c'è $PATHche funziona in modo molto simile a %PATH%Windows, quindi non sono sicuro di quale sia esattamente il tuo punto. Per convenzione, i nomi delle directory UNIX tendono ad essere più brevi rispetto a Windows e, di conseguenza, $PATHtendono anche ad essere più brevi.
Mitch Schwartz

2
Grazie Mitch, la modifica 4 che fornisci è quello che volevo !, ora posso avere una cartella centralizzata con tutti i binari di cui ho bisogno.
Proverò

2
La sezione "modifica 4" è eccessivamente complicata per il passaggio di argomenti all'eseguibile. Vedi la risposta di Michael Burr.
Dave Andersen

83

Questo analizzerà la tua variabile d'ambiente% PATH% e convertirà ogni directory nel suo nome abbreviato equivalente e poi ricostruirà tutto:

@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!

Prendi l'output e aggiorna la variabile PATH nelle variabili di ambiente.


Grazie che è stato molto utile !! Ha accorciato il mio percorso dal 1990 al 1338 e tutto funziona ancora a meraviglia! Ho scelto il tuo approccio perché volevo mantenere tutto nel mio percorso e il collegamento su file batch sarebbe stato troppo dispendioso in termini di tempo. GRAZIE!
ndrizza

2
Questo è stato utile anche perché mi ha parlato di tutte le directory inesistenti nel mio percorso che si erano accumulate nel tempo.
Nate Glenn

27
Rapid Environment Editor è un altro modo per farlo. Evidenzia directory inesistenti e ha un'opzione "converti percorso lungo in breve".
Russell Gallop

3
@RussellGallop: quello, signore, è uno strumento fantastico.
elo80ka

1
Nota la citazione di chiusura mancante dopo %%~sa. Ho provato ad aggiornare la risposta ma non me lo consente a meno che non modifico 6 caratteri
zr870

28

se utilizzi Windows Vista o versioni successive, puoi creare un collegamento simbolico alla cartella. per esempio:

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

creerebbe un collegamento così c:\pfsarebbe la tua program filescartella. Ho rasato 300 caratteri dal mio percorso usando questo trucco.


Questa è una bella alternativa all'utilizzo di una variabile d'ambiente per rappresentare un percorso parziale.
porcus

1
Questo sarebbe sicuramente d'aiuto di più, ma se desideri una soluzione più "corretta" (supportata?), Puoi sostituire le istanze di c:\Program Filese c:\Program Files (x86)con le variabili predefinite %ProgramFiles%e %ProgramFiles(x86)% tenforums.com/tutorials/… Questi salvano solo pochi caratteri ciascuno , ma se sei VERAMENTE sul punto di massimizzare il PERCORSO, potrebbe essere la differenza. Del resto, creerò% pf% e% pfx% che risolvono i percorsi corretti. Grazie per l'idea! :)
rainabba

Il problema con l'utilizzo di variabili come% pf% e% pfx% è che si verificano gli stessi problemi della creazione di collegamenti simbolici: gli aggiornamenti software possono aggiungere di nuovo elementi alla variabile del percorso. L'altro problema con l'utilizzo di variabili del genere è che non è facile e veloce creare script intorno ad esso o sfogliarli da Explorer. Usando il metodo che ho descritto, puoi letteralmente aprire c: \ PF. Windows lo vede proprio come una cartella, quindi puoi scrivere bat o powershell anche su di esso abbastanza facilmente.
bmg002

10

Nel caso qualcuno sia interessato ...

Trovo di non aver mai davvero bisogno di tutti quei percorsi contemporaneamente, quindi creo un mucchio di file batch di "inizializzazione" che modificano il percorso di conseguenza.

Ad esempio, se volessi fare un po 'di sviluppo C ++ in Eclipse, farei:

> initmingw
> initeclipse
> eclipse

Questo è utile anche per evitare conflitti tra eseguibili con lo stesso nome (come i compilatori C ++ e D, che hanno entrambi un make.exe).

I miei file batch in genere hanno questo aspetto:

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

Trovo questo approccio relativamente pulito e devo ancora incontrare problemi con esso.


7

In genere non devo preoccuparmi di questo (non ho incontrato un limite di dimensione del percorso - non so nemmeno cosa sia sui moderni sistemi Windows), ma ecco cosa potrei fare per evitare di inserire la directory di un programma in il sentiero:

  • la maggior parte delle utilità della riga di comando vengono lanciate in una c:\utildirectory che si trova nel percorso
  • altrimenti, aggiungerò un semplice file cmd / batch alla c:\utildirectory che assomiglia a qualcosa di simile:

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

che essenzialmente crea un alias per il comando. Non è necessariamente perfetto. Alcuni programmi insistono davvero per essere nel percorso (che è piuttosto raro al giorno d'oggi) e altri programmi che tentano di invocarlo potrebbero non trovarlo correttamente. Ma per la maggior parte degli usi funziona bene.

Ma in generale, non mi sono dovuto preoccupare di evitare di aggiungere directory al percorso.


Quando inizi a seguire questo "percorso", fai attenzione che uno script batch non può chiamare un altro script batch senza la sintassi "CALL [bat]". Quindi, se vuoi assicurarti che il tuo exe inoltrato o meno sia chiamato da un bat, usa "call php script.php" invece di "php script.php" (che funziona in entrambi i modi) Un ottimo motivo per usarlo. bat dispatcher serve a prevenire conflitti di nomi PATH (versione multipla dello stesso exe)
131

@ 131: Ti dispiacerebbe spiegare cosa intendi con 'questo "percorso"'? Intendi il percorso del file particolare dell'esempio? O piuttosto il metodo generale suggerito da questa risposta?
O Mapper

@ORMapper: quando 131 dice: "Quando inizi a seguire questo" percorso "", significa "Quando usi questa tecnica".
Michael Burr

1
Come hai scritto, "altri programmi che tentano di invocarlo potrebbero non trovarlo correttamente" - Caso in questione: Sfortunatamente, può lanciare chiamate automatiche ad applicazioni a riga di comando, ad esempio da strumenti di compilazione come NAnt, fuori rotta. Un rimedio è invocare il comando con un anteposto cmd /c, ma ciò a sua volta significa che lo script di build diventa specifico per Windows: / Ho chiesto a riguardo in una domanda separata .
O Mapper

5

Un'altra idea: utilizzare DIR / X per determinare i nomi brevi generati per i nomi di file non 8dot3. Quindi usali nel tuo% PATH%.

Ad esempio, "C: \ Programmi" diventa "C: \ PROGRA ~ 1".


1
Ops, mi sono appena reso conto che questo era già stato suggerito da @Mitch. Gli darò un +1 per questo. :)
Android Eve


2

Ho scritto e utilizzato ogni volta uno stream standard (stdin / stderr / stdout) e un programma PROXY con codice di uscita (chiamato dispatcher https://github.com/131/dispatcher )

Tutti i programmi CLI che utilizzo (node, php, python, git, svn, rsync, plink ...) che sto utilizzando sono in realtà lo stesso file exe (circa 10kb, che nomino in modo diverso), che ho inserito nello stesso directory. Un file di testo in chiaro statico fittizio esegue il "nome del file proxy per la mappatura exe reale".

Dispatcher utilizza l'API Win32 per la gestione dei processi di basso livello per essere assolutamente trasparente.

Utilizzando questo software, ho solo UNA directory aggiuntiva impostata nel mio PERCORSO per tutti i programmi che potrei usare.


1

La creazione di una cartella c: \ bin aggiunta al percorso e l'hardlink come hai detto potrebbero abbreviare la stringa. Forse aggiungi una variabile pf alle variabili di sistema con valore c: \ Programmi quindi sostituisci c: \ Programmi con% pf% nel percorso.

Modificare:

Crea un disco virtuale. subst p: "c: \ file di programma"


1
Penso che il percorso conterrebbe le variabili espanse, nel qual caso non diventerebbe più breve.
Ben Voigt

0

Seguo questi passaggi per rendere gestibili le voci:

  1. Creati diversi utenti per diverse combinazioni di utilizzo dei pacchetti software. Esempio: (a) Creato un utente web per rendere disponibile tutto il software di sviluppo web; (b) Creato un database utente per rendere disponibili tutti i pacchetti software di database e data warehousing. Ricorda che alcuni software possono creare più di una voce. O a volte lo divido in utenti specifici per Oracle e specifici per MSSQL e specifici per Oracle. Ho inserito MySQL / PostgreSQL, tomcat, wamp, xamp tutti nell'account utente webr.

  2. Se possibile, installa pacchetti comuni come Office, Photoshop, .. come specifici del sistema disponibili per tutti gli utenti e pacchetti speciali come specifici per l'utente. Ovviamente ho dovuto accedere a diversi utenti e installarli. Non tutto il software può fornire questa opzione. Se l'opzione "installa solo per questo utente" non è disponibile, installala per l'intero sistema.

  3. Evito di installare programmi nella cartella Program File (x86) o in Program File. Ho sempre installato nella directory di base. Ad esempio MySQL 64 bit va nella cartella "C: \ mysql64" e MySQL 32 bit va nella cartella "C: \ mysql". Presumo sempre di aggiungere un suffisso 64 solo per il software a 64 bit. Se nessun suffisso, allora è a 32 bit. Seguo la stessa cosa per Java e altri. In questo modo il mio percorso sarà più breve, escluso "C: \ Program File (x86)". Per alcuni software potrebbe essere necessario modificare il file di configurazione per mostrare dove si trova esattamente il file .exe. Solo il programma che richiede di essere installato in "C: \ Program File (x86)" verrà installato in quella cartella. Ricordo sempre di abbreviare i nomi. Evito il numero di versione come tomcat / release / version-2.5.0.3 tali dettagli. Se ho bisogno della versione conosciuta, Creo un file per versione nome e lo metto nella cartella Tomcat. In generale abbreviare il collegamento il più possibile.

  4. Includere qualsiasi batch per sostituire il collegamento abbreviato al percorso, se tutti i passaggi precedenti hanno superato il limite di Windows.

Quindi accedere all'utente specifico per l'utilizzo (applicazione mobile, database / data warehousing o sviluppo web .. ..) ed eseguire le attività pertinenti.

Puoi anche creare finestre virtuali all'interno di Windows. Finché si dispone di una copia del sistema operativo con licenza, è possibile creare più finestre virtuali con la stessa chiave. È possibile inserire pacchetti specifici per una particolare attività in quella macchina. È necessario avviare ogni volta una VM separata. Alcuni pacchetti ad alta intensità di memoria come i produttori di film di animazione 3D dovrebbero essere tutti inseriti nella macchina principale, non nella VM poiché la VM avrà solo una parte della RAM disponibile per il suo utilizzo. Tuttavia, è un problema avviare ogni VM.


0

Le soluzioni di cui sopra funzionano solo se puoi tagliare il tuo percorso. Nel mio caso, quella non era davvero un'opzione, ed era una seccatura dover eseguire uno script ogni volta che aprivo un prompt dei comandi. Quindi ho scritto un semplice script che viene eseguito automaticamente all'apertura del prompt dei comandi e aggiunge il contenuto di un file di testo al percorso.

Ci sono anche alcuni contesti in cui l'esecuzione di questo script interrompe le cose (ad esempio, in una shell github o cygwin), quindi ho anche aggiunto un file che contiene un elenco di percorsi che, se il prompt dei comandi viene avviato in essi, la variabile path non è non viene modificato tramite lo script di avvio che normalmente aggiorna il percorso.

@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

E Path.txt avrà un aspetto simile

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;

Mentre Dontsetup.txt avrà un aspetto simile a

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

Per farlo funzionare automaticamente all'avvio, apri regedit, vai a HKEY_LOCAL_MACHINE / SOFTWARE / Microsoft / Command Processor, quindi fai clic con il pulsante destro del mouse a destra e premi nuovo -> Valore multistringa. Chiamalo AutoRun. Imposta il suo valore su

C:\Users\Yams\setUpPath.bat

o in qualsiasi altro luogo in cui hai archiviato il file batch sopra.


0

Non l'ho provato, ma la divisione di PATH in parti funzionerà e unirle nel lavoro finale della variabile?

Esempio inizialmente diciamo che hai qualcosa di simile

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

Invece crei:

_PATH1 = {LONGPATH1};{LONGPATH2};....{2048 char}
_PATH2 = {2049th char}...{LONGPATH_N-1};{LONGPATH_N}
rem // may be more parts
PATH = %_PATH1%;%_PATH2%
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.