Como você evita o superpopulação da variável de ambiente PATH no Windows?

115

Gostaria de saber quais são as abordagens que você usa para gerenciar os executáveis ​​em seu sistema. Por exemplo, tenho quase tudo acessível através da linha de comando, mas agora cheguei ao limite da string de caminho, então não posso adicionar mais dir.

Então, o que você recomenda? Há muito tempo, tentei usar softLinks dos executáveis ​​em um Dir que pertencia ao caminho, mas essa abordagem não funcionou. Jogue o "executável apenas" para um Dir conhecido, tem os problemas que quase todos os aplicativos exigem um conjunto de arquivos, então isso também é ruim. Jogue o executável e todos os seus arquivos para um Dir conhecido, mmm isso vai funcionar, mas a possibilidade de obter um conflito no nome dos arquivos é muito grande. Criar um HardLink? Eu não sei. O que você acha?

mjsr
fonte
por que você usa tantos caminhos? path geralmente é usado para dir comum, quando seu aplicativo deve compartilhar extend object / app / lib com outros. Use tanto para fazer o aplicativo iniciar mais devagar. Você pode fornecer mais detalhes sobre como usar, criar ambiente de caminho var?
pinichi de
1
oi pinichi, muitos aplicativos usam o padrão "C: \ Program File \ AppNAme \ ...", e no meu caso muitos desses aplicativos podem ser executados em linha de comando ou precisam estar acessíveis a outros aplicativos ( por exemplo, os executáveis ​​do Miktex que qualquer editor Tex espera que existam), portanto, eles precisam estar no PATH. Não quero saber uma abordagem melhor porque a minha é insustentável
mjsr
1
Esta ferramenta comprimirá os caminhos. O resultado é impressionante: uweraabe.de/Blog/2014/09/09/the-garbled-path-variable/#more-337
InTheNameOfScience

Respostas:

84

Uma maneira que consigo pensar é usar outras variáveis ​​de ambiente para armazenar caminhos parciais; por exemplo, se você tiver

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

então você pode criar uma nova variável de ambiente, como

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

após o qual seus caminhos originais se tornam

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

EDIT: Outra opção é criar um bindiretório que contém .batarquivos que apontam para os .exearquivos apropriados .

EDIT 2: O comentário de Ben Voigt a outra resposta menciona que o uso de outras variáveis ​​de ambiente conforme sugerido pode não reduzir o comprimento de %PATH%porque elas seriam expandidas antes de serem armazenadas. Isso pode ser verdade e eu não testei isso. Outra opção, porém, é usar formulários 8dot3 para nomes de diretório mais longos, por exemplo, C:\Program Filesé normalmente equivalente a C:\PROGRA~1. Você pode usar dir /xpara ver os nomes mais curtos.

EDIT 3: Este teste simples me leva a acreditar que Ben Voigt está certo.

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

No final disso, você verá a saída em hellohellovez de byehello.

EDIT 4: No caso de você decidir usar arquivos em lote para eliminar certos caminhos %PATH%, você pode se preocupar em como passar os argumentos de seu arquivo em lote para o executável de forma que o processo seja transparente (ou seja, você não notará nenhuma diferença entre chamar o arquivo em lote e chamar o executável). Não tenho muita experiência em escrever arquivos em lote, mas parece funcionar bem.

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

Como regra geral, você deve ter cuidado ao executar arquivos em lote da Internet, uma vez que pode fazer todo tipo de coisa com arquivos em lote, como formatar seu disco rígido. Se você não confiar no código acima (que escrevi), você pode testá-lo substituindo a linha

%actualdir%\%actualfile% %args%

com

echo %actualdir%\%actualfile% %args%

Idealmente, você deve saber exatamente o que cada linha faz antes de executá-la.

Mitch Schwartz
fonte
1
a forma 8dot3 funciona bem, mas para diretórios muito grandes não é muito bom, por exemplo "C: \ Arquivos de programas (x86) \ Microsoft Visual Studio 2008 SDK \ VisualStudioIntegration \ Tools \ Sandcastle \ ProductionTools \". Outra coisa que economizou um pouco foi que como usuário eu poderia criar uma variável PATH baseada no System Path e adicionar qualquer outro Dir. Todas essas abordagens são do tipo "compacta essa string", mas podemos ter um diretório centralizado de binários, como o Unix?
mjsr
1
Hmm, em relação a diretórios muito longos, eu acho que o oposto é verdadeiro: quanto mais longo o diretório, mais caracteres você salva usando o formato 8dot3. Se for difícil navegar cmd, observe que você pode usar *para economizar digitação. Então, por exemplo, na raiz, digite dir /x pro*. Você verá o diretório desejado junto com seu nome 8dot3. Em seguida, use cdpara navegar até ele e repita o processo.
Mitch Schwartz
1
Em relação ao UNIX, você tem o $PATHque funciona de maneira muito semelhante ao %PATH%Windows, então não tenho certeza de qual é o seu ponto exatamente. Por convenção, os nomes de diretório do UNIX tendem a ser menores do que no Windows e, como resultado, $PATHtambém tendem a ser menores.
Mitch Schwartz
2
Obrigado Mitch, o Edit 4 que você fornece é o que eu queria! Agora posso ter uma pasta centralizada com todos os binários que preciso. Vou testar mais a fundo para ver se há um problema com algum aplicativo
mjsr
2
Sua seção 'editar 4' é excessivamente complicada para passar argumentos para o executável. Veja a resposta de Michael Burr.
Dave Andersen
83

Isso analisará sua variável de ambiente% PATH% e converterá cada diretório em seu nome abreviado equivalente e, em seguida, juntará tudo de novo:

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

Pegue a saída e atualize a variável PATH nas variáveis ​​de ambiente.

Todd Smith
fonte
Obrigado isso foi muito útil !! Encurtou meu caminho de 1990 a 1338 e tudo ainda funciona como um encanto! Escolhi sua abordagem porque queria manter tudo no meu caminho e a vinculação de arquivos em lote teria sido muito demorada. OBRIGADO!
ndrizza
2
Isso também foi útil porque me falou sobre todos os diretórios inexistentes em meu caminho que se acumularam ao longo do tempo.
Nate Glenn
27
O Editor de ambiente rápido é outra maneira de fazer isso. Ele destaca diretórios inexistentes e tem uma opção "converter caminho longo em curto".
Russell Gallop
3
@RussellGallop: essa, senhor, é uma ferramenta incrível.
elo80ka
1
Observe a citação de fechamento faltando depois %%~sa. Tentei atualizar a resposta, mas não consigo, a menos que eu mude 6 caracteres
zr870
28

se estiver usando o Windows Vista ou superior, você pode fazer um link simbólico para a pasta. por exemplo:

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

faria um link para c:\pfsua program filespasta. Eu cortei 300 caracteres do meu caminho usando este truque.

bmg002
fonte
Esta é uma boa alternativa ao uso de uma variável de ambiente para representar um caminho parcial.
porcus de
1
Isso definitivamente ajudaria mais, mas se você gostaria de uma solução mais "correta" (suportada?), Você pode substituir as instâncias de c:\Program Filese c:\Program Files (x86)pelas variáveis ​​predefinidas %ProgramFiles%e %ProgramFiles(x86)% tenforums.com/tutorials/… Eles economizam apenas alguns caracteres cada , mas se você está REALMENTE prestes a estourar o PATH, pode ser a diferença. Por falar nisso, irei criar% pf% e% pfx% que resolvem para os caminhos corretos. Obrigado pela ideia! :)
rainabba
O problema de usar variáveis ​​como% pf% e% pfx% é que você tem os mesmos problemas que criar links simbólicos - atualizações de software podem adicionar coisas novamente à variável de caminho. O outro problema com o uso de variáveis ​​como essa é que não é rápido e fácil criar scripts ou navegar até elas a partir do explorer. Usando o método que descrevi, você pode literalmente abrir c: \ PF. O Windows o vê como uma pasta, de modo que você também pode escrever bat ou PowerShell nele.
bmg002
10

Caso alguém esteja interessado ...

Acho que nunca realmente preciso de todos esses caminhos de uma vez, então crio um monte de arquivos em lote de "inicialização" que modificam o caminho de acordo.

Por exemplo, se eu quisesse fazer algum desenvolvimento C ++ no Eclipse, faria:

> initmingw
> initeclipse
> eclipse

Isso também é útil para evitar conflitos entre executáveis ​​com o mesmo nome (como os compiladores C ++ e D, que possuem um make.exe).

Meus arquivos em lote costumam ser assim:

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

Acho essa abordagem relativamente limpa e ainda não tive problemas com ela.

YellPika
fonte
7

Em geral, não preciso me preocupar com isso (não entrei em um limite de tamanho de caminho - nem sei o que é isso nos sistemas Windows modernos), mas aqui está o que posso fazer para evitar colocar o diretório de um programa em o caminho:

  • a maioria dos utilitários de linha de comando são lançados em um c:\utildiretório que está no caminho
  • caso contrário, adicionarei um arquivo cmd / batch simples ao c:\utildiretório que se parece com:

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

que essencialmente cria um alias para o comando. Não é necessariamente perfeito. Alguns programas realmente insistem em estar no caminho (o que é muito raro hoje em dia), e outros programas que tentam invocá-lo podem não encontrá-lo corretamente. Mas para a maioria dos usos funciona bem.

Mas, geralmente, não tenho que me preocupar em evitar adicionar diretórios ao caminho.

Michael Burr
fonte
Ao começar a seguir este "caminho", tome cuidado para que um script em lote não possa chamar outro script em lote sem a sintaxe "CALL [bat]". Então, se você quiser ter certeza de que seu exe encaminhado ou não é chamado de um morcego, use "call php script.php" ao invés de apenas "php script.php" (que funciona nos dois sentidos) Um excelente motivo para usar. bat dispatcher é para evitar conflitos de nomes PATH (versão múltipla do mesmo exe)
131
@ 131: Você se importaria de explicar o que quer dizer com 'este' caminho '? Você quer dizer o caminho de arquivo específico do exemplo? Ou melhor, o método geral sugerido por esta resposta?
OR Mapper de
@ORMapper: quando 131 diz, 'Quando você começa a seguir este "caminho"', ele quer dizer, 'Quando você usa esta técnica'.
Michael Burr de
1
Como você escreveu, "outros programas que tentam invocá-lo podem não encontrá-lo corretamente" - caso em questão: Infelizmente, ele pode lançar chamadas automáticas para aplicativos de linha de comando, por exemplo, por ferramentas de construção como NAnt, fora do curso. Uma solução é invocar o comando com um prefixo cmd /c, mas isso, por sua vez, significa que o script de construção se torna específico do Windows: / Eu perguntei sobre isso em uma pergunta separada .
OR Mapper de
5

Outra ideia: use DIR / X para determinar os nomes abreviados gerados para nomes de arquivo não 8dot3. Em seguida, use-os em seu% PATH%.

Por exemplo, 'C: \ Arquivos de programas' torna-se 'C: \ PROGRA ~ 1'.

Véspera de Android
fonte
1
Opa, acabei de perceber que isso já foi sugerido por @Mitch. Vou dar a ele um +1 por isso. :)
Android Eve
2

Eu escrevi e usei sempre um stream padrão (stdin / stderr / stdout) e um programa de código de saída PROXY (chamado dispatcher https://github.com/131/dispatcher )

Todos os programas CLI que eu uso (node, php, python, git, svn, rsync, plink ...) que estou usando são na verdade o mesmo arquivo exe (cerca de 10kb, que nomeei de forma diferente), que coloquei no mesmo diretório. Um arquivo de texto não criptografado estático fictício faz o "mapeamento do nome do arquivo proxy para exe real".

O despachante usa a API win32 de gerenciamento de processos de baixo nível para ser totalmente transparente.

Usando este software, tenho apenas UM diretório adicional definido em meu PATH para todos os programas que posso usar.

131
fonte
1

Criar uma pasta c: \ bin adicionando ao seu caminho e hardlinking como você disse pode encurtar a string. Talvez adicione uma variável pf a vars do sistema com o valor c: \ Arquivos de programas e então substitua c: \ Arquivos de programas por% pf% no caminho.

Editar:

Crie uma unidade virtual. subst p: "c: \ arquivos de programa"

troynt
fonte
1
Acho que o caminho conteria as variáveis ​​expandidas, caso em que não ficaria mais curto.
Ben Voigt
0

Eu sigo estas etapas para tornar as entradas gerenciáveis:

  1. Criou diferentes usuários para diferentes combinações de uso de pacotes de software. Exemplo: (a) Criei uma web de usuário para disponibilizar todo o software de desenvolvimento web; (b) Criou um banco de dados do usuário para disponibilizar todos os pacotes de software de banco de dados e data warehouse. Lembre-se de que alguns softwares podem criar mais de uma entrada. Ou às vezes eu divido isso em usuários específicos do oracle, do MSSQL e específicos do oracle. Coloquei MySQL / PostgreSQL, tomcat, wamp, xamp na conta do usuário webr.

  2. Se possível, instale pacotes comuns como office, photoshop, .. como sistema específico disponível para todos os usuários e pacotes especiais como específico do usuário. Claro que tive que entrar em diferentes usuários e instalá-los. Nem todo software pode fornecer essa opção. Se a opção "instalar somente para este usuário" não estiver disponível, instale-a para todo o sistema.

  3. Evito instalar programas na pasta Arquivo de programa (x86) ou em Arquivo de programa. Eu sempre instalo no diretório base. Por exemplo, o MySQL de 64 bits vai para "C: \ mysql64" e o MySQL de 32 bits vai para a pasta "C: \ mysql". Eu sempre presumo adicionar um sufixo 64 apenas para software de 64 bits. Se não houver sufixo, é 32 bits. Eu sigo a mesma coisa para Java e outros. Desta forma, meu caminho será mais curto, não incluindo "C: \ Arquivo de Programa (x86)". Para alguns softwares, o arquivo de configuração pode precisar ser editado para mostrar onde exatamente está o arquivo .exe. Somente programas que precisam ser instalados em "C: \ Arquivo de programas (x86)" serão instalados nessa pasta. Sempre me lembro de encurtar os nomes. Eu evito o número da versão como tomcat / release / version-2.5.0.3 tais detalhes. Se eu precisar conhecer a versão, Eu crio um arquivo pela versão do nome e coloco na pasta do tomcat. Em geral, encurte o link o máximo possível.

  4. Inclua qualquer lote para substituir o link abreviado para o caminho, se todas as etapas acima ultrapassarem o limite do Windows.

Em seguida, efetue login no usuário específico de uso (aplicativo móvel ou banco de dados / armazenamento de dados ou desenvolvimento web .. ..) e execute as tarefas relevantes.

Você também pode criar janelas virtuais dentro do Windows. Contanto que você tenha uma cópia licenciada do SO, é possível criar várias janelas virtuais com a mesma chave. Você pode colocar pacotes específicos para uma tarefa particular nessa máquina. Você deve iniciar uma VM separada a cada vez. Alguns pacotes com uso intensivo de memória, como os criadores de filmes de animação 3D, devem ser colocados na máquina principal, não na VM, pois a VM terá apenas uma parte da RAM disponível para uso. No entanto, é difícil inicializar cada VM.

Dr. A. Anukanth
fonte
0

As soluções acima só funcionam se você puder diminuir seu caminho. No meu caso, isso não era realmente uma opção e era um incômodo ter que executar um script sempre que abria um prompt de comando. Então, escrevi um script simples que é executado automaticamente ao abrir o prompt de comando e anexa o conteúdo de um arquivo de texto ao seu caminho.

Existem também alguns contextos em que a execução deste script quebra as coisas (digamos, em um github ou shell cygwin), então também adicionei um arquivo que contém uma lista de caminhos que, se o prompt de comando for iniciado neles, a variável de caminho isn não é alterado por meio do script de inicialização que normalmente atualiza o caminho.

@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 será parecido com

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;

Enquanto Dontsetup.txt será parecido com

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

Para que isso seja executado automaticamente na inicialização, abra o regedit, navegue até HKEY_LOCAL_MACHINE / SOFTWARE / Microsoft / Command Processor, clique com o botão direito à direita e pressione novo -> Valor Multi-String. Nomeie-o como AutoRun. Defina seu valor para

C:\Users\Yams\setUpPath.bat

ou onde mais você armazenou o arquivo em lote acima.

Phylliida
fonte
0

Não tentei, mas dividir PATH em partes funcionará e juntá-las no trabalho de variável final?

Exemplo inicialmente, digamos que você tenha algo como

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

Em vez disso, você cria:

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