Espaços e parênteses na variável PATH do Windows estraga os arquivos em lote

14

Assim, minha variável de caminho (Sistema > Configurações avançadas > Env Vars > Sistema > PATH) está definida como:

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;

Embora, obviamente, sem as novas linhas.

Observe as linhas contendo PathWithSpaces - a primeira não tem espaços, a segunda tem um espaço e a terceira tem um espaço seguido por um parêntese.

Agora, observe a saída desse arquivo em lote:

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

ou especificamente a linha:

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

Então, o que é essa besteira?

Especificamente:

  • Diretório no caminho que está corretamente escapou com aspas, mas sem espaços = bem
  • Diretório no caminho que é devidamente escapado com aspas e tem espaços, mas nenhum parêntese = fine
  • Diretório no caminho que está corretamente escapou com aspas e tem espaços e tem um parêntese = ERRO

O que está acontecendo aqui? Como posso consertar isso? Eu provavelmente vou recorrer a um ponto de junção para deixar minhas ferramentas ainda funcionarem como solução alternativa, mas se você tiver alguma ideia, por favor me avise:)

    
por Hennes 14.03.2010 / 00:06

8 respostas

12

Isso pode acontecer se houver parênteses sem escape em uma linha dentro de um "bloco" (que também usa parênteses para delimitar).

Geralmente, você pode corrigi-lo ativando a expansão atrasada e usar variáveis com !var! em vez de %var% . Não há muito mais conselhos que eu possa dar sem ver o código.

    
por 14.03.2010 / 01:20
17

Nota para usuários do Windows em sistemas de 64 bits

Progra ~ 1 = 'Arquivos de Programas' Progra ~ 2 = 'Arquivos de Programas (x86)'

link

    
por 11.06.2013 / 03:43
12

Deve (a) não ser quaisquer aspas no caminho do MS-Windows variável ambiental (comando PATH) ou (b) deve haver aspas em torno da expressão inteira seguindo o (comando SET) . Infelizmente, isso não é muito bem documentado pelo MS, embora eles declarem que, se forem usadas aspas, elas serão incluídas no valor da variável (Referência de linha de comando do Windows XP) .

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

Isso pode causar problemas inconsistentes e, portanto, difíceis de diagnosticar. Por exemplo, se o seu caminho incluir "C: \ Python27", sua máquina dirá que "'python' não é reconhecido como um comando interno ou externo, um programa operacional ou um arquivo em lote". quando você tenta executar python. No entanto, algumas bibliotecas podem ainda estarem disponíveis.

Você não precisa "escapar" de espaços ou parênteses. Se você precisar escapar de caracteres especiais, coloque aspas em toda a expressão, incluindo o nome da variável.

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

ou você pode usar parênteses também.

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

Note que as aspas duplas devem vir em pares.

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

No entanto, provavelmente não existem caracteres que sejam nomes de caminho válidos, o que causaria um problema com o comando SET.

    
por 23.07.2012 / 09:17
2

A Microsoft documenta o problema em " Erro ao executar scripts shell de comando que incluem parênteses ".

A solução que eles sugerem é usar a expansão atrasada.

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

Para definir um caminho em um bloco if, em vez de usar SET PATH= , provavelmente você deve usar o comando PATH .

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

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

Para outras variáveis, outra solução pode ser usar citações, mas em torno de toda a coisa:

SET "MyVar=C:\Program Files (x86)\Whatever"
    
por 09.07.2016 / 12:16
1

Joey em sua resposta diz

This can happen if there are unescaped parentheses in a line inside a "block" (which also uses parentheses for delimiting).

e isso é verdade. Se houver parênteses sem escape, deve-se escapar deles. Isso é o que eu fiz; Eu substituí

set PATH=some_path;%PATH%

com

set PATH="some_path;%PATH%"

e isso resolveu o problema.

    
por 15.10.2011 / 20:14
1

Eu experimentei algo semelhante. A Microsoft explica o problema aqui: link

Basicamente, em vez de alterar a variável Path via System- > Adv Settings- > Env Vars > System > PATH, tente

My Computer->Manage->Computer Management (local)-> Properties-> Advanced-> Environment variables-> Settings
    
por 07.01.2013 / 16:27
1

No Windows 8, encontrei muito pouco sucesso com qualquer um desses métodos. Parênteses não funcionam, aspas funcionam, mas o "caminho" que você modifica dessa forma não é o caminho que é usado para localizar executáveis, em vez disso, cmd ainda parece estar usando o caminho do sistema que herdou quando você abriu a janela. / p>

exemplo: depois de determinar a arquitetura do processador, quero adicionar alguns caminhos à variável de ambiente PATH. Na verdade, até mesmo adicioná-los temporariamente funcionaria, pois só preciso deles enquanto um arquivo de lote está em execução. Mas isso nem funciona.

echo %path% exibe o PATH do sistema no momento em que o cmd foi lançado.

set path="%path%;%programfiles(x86)%\company\program\subdir" funciona, mas agora %path% contém tudo entre aspas, e se eu tentar executar um programa em subdir de algum outro lugar, ele falhará. Usar parênteses em torno da coisa toda em vez de aspas não funciona .

Outra coisa que notei é que o mesmo comando funcionará se inserido interativamente em cmd , mas não se encontrado em um arquivo em lotes. Isso é assustador Outra peculiaridade é a perda intermitente do último caractere do valor de uma variável de ambiente! Outra inconsistência é com programas de terceiros: alguns podem manipular um %var% como parâmetro, outros não.

    
por 10.01.2013 / 23:52
1

Eu tive um grande problema para fazer o seguinte trabalho no Win8 até que eu adicionei aspas duplas no valor que eu estava definindo para a variável fromFile. Sem isso, quando fromFile continha um nome de arquivo com parênteses, a próxima linha que estava tentando fazer uma substituição de string para gerar a variável toFile estava falhando. Note que eu uso uma expansão atrasada para avaliar a variável no tempo de execução em vez de no tempo de análise (da respectiva instância 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
    
por 14.06.2014 / 14:52