Qual é a diferença entre% e %% em um arquivo cmd?

87

Recentemente, incluí uma linha semelhante a esta em um arquivo .cmd:

for /f %%f in ('dir /b .\directory\*.sql') DO sqlcmd -b -o ".\directory\output\%%f.txt" -i ".\directory\%%f"

Originalmente, eu tinha usado apenas% f e funcionaria bem quando executado na linha de comando, mas não quando executado através do arquivo. Quando mudei para %% f, funcionou no arquivo. Apenas me perguntando qual é a diferença.

Tyler
fonte

Respostas:

136

(A explicação em mais detalhes pode ser encontrada em um artigo arquivado do Microsoft KB .)

Três coisas a saber:

  1. O sinal de porcentagem é usado em arquivos em lote para representar parâmetros de linha de comando: %1, %2, ...
  2. Sinais de dois por cento com quaisquer caracteres entre eles são interpretados como uma variável:

    echo %myvar%

  3. Sinais de dois por cento sem nada no meio (em um arquivo de lote) são tratados como um único sinal de porcentagem em um comando (não um arquivo de lote):%%f

Por que isso?

Por exemplo, se executarmos sua linha de comando (simplificada)

FOR /f %f in ('dir /b .') DO somecommand %f

em um arquivo em lote, a regra 2 tentaria interpretar

%f in ('dir /b .') DO somecommand %

como uma variável. Para evitar isso, você deve aplicar a regra 3 e escapar %com um segundo %:

FOR /f %%f in ('dir /b .') DO somecommand %%f
marapet
fonte
21
Existe uma explicação de por que posso usar apenas um sinal de um por cento em um loop FOR, quando executado diretamente de um prompt de comando, e não de um arquivo em lote? Eu sei sobre o património DOS, mas pode usar variáveis de uma linha de comando agora.
Alec Mev
6
Além disso, certifique-se de que a variável seja um único caractere.
jiggunjer
1
E se eu quiser emitir um comando que contém%, por exemplo: para / f %% i in ('git log -1 --pretty = format: "%% H"') defina GIT_COMMIT = %% i
Wakan Tanka
15

No DOS, você não podia usar variáveis ​​de ambiente na linha de comando, apenas em arquivos em lote, onde eles usavam o %sinal como um delimitador. Se você quisesse um %sinal literal em um arquivo em lote, por exemplo, em uma echodeclaração, você precisava dobrá-lo.

Isso foi transportado para o Windows NT, que permitia variáveis ​​de ambiente na linha de comando; no entanto, para compatibilidade com versões anteriores, você ainda precisa dobrar seus %sinais em um arquivo .cmd.

Neil
fonte