
Acabei de perceber que estou executando um arquivo bat no início desta chave de registro, que tinha echo running abc
e algumas outras coisas irrelevantes
HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\AutoRun
Então aqui eu modifiquei aquele arquivo bat. É apenas uma linha, nada irrelevante nele.
você vê o conteúdo do arquivo bat.
Aqui está uma saída do prompt do cmd mostrando a situação agora, que é o mesmo problema fundamental, mas você deve conseguir reproduzir o problema
A questão agora é:
- Por que diz echo sss e não echo sss ttt?
- Como posso suprimir a execução do cmd ou do arquivo bat de inicialização com o FOR? A instrução FOR deve exibir apenas "echo g", não "echo sss" ou "echo sss ttt".
Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
sss ttt
C:\Documents and Settings\Administrator>cd\
C:\>type \blah\startfile.bat <ENTER>
@echo sss ttt
C:\>
C:\>for /f %f in ('echo g ^| findstr "g"') do echo %f <ENTER>
C:\>echo sss
sss
C:\>echo g
g
C:\>
Responder1
Por que diz echo sss e não echo sss ttt?
Porque a linha sss ttt
contém um caractere de espaço. O for
comando tokeniza e armazena a primeira metade e sss
a %f
segunda metade ttt
na %g
variável.
Como posso suprimir a execução do cmd ou do arquivo bat de inicialização com o FOR? A instrução FOR deve exibir apenas "echo g", não "echo sss" ou "echo sss ttt".
Parece que para avaliar echo g ^| findstr "g"
um novo interpretador de comandos é inicializado e o seu \blah\startfile.bat
é executado automaticamente. Faça seu lote não produzir nada.
Responder2
Se for usar %f
em um arquivo em lote, você precisa escapar dele com outro %
:
for /f %%f in ('echo g ^| findstr "g"') do echo %%f
Coloque isso em seu arquivo em lote e você deverá obter os resultados que procura.
Responder3
Só para expandir um pouco a resposta de Vlastimil...
Quando oFOR
comando executa o"echo g"
e canaliza a saída parafindstr
,PARAtem que primeiro iniciar um novo processador de comando que faz com que\blah\startfile.bat
para ser executado.
\blá\startfile.batgera uma linha contendosss ttt
. Essa linha é processada porPARAe éNÃOpassado paraencontrarstr.
De acordo com a ajuda paraPARA:
O processamento consiste em ..., dividi-lo em linhas individuais de texto e, em seguida, analisar cada linha em zero ou mais tokens. O corpo do loop for é então chamado com os valores das variáveis definidos para a(s) string(s) do token encontrado(s). Por padrão, /F passa o primeiro token separado em branco de cada linha...
Os delimitadores padrão paraPARAsão:",;"(espaço, vírgula e ponto e vírgula).
A primeira linha quePARAprocessos contém a string:sss ttt. Essa string contém um" "
(espaço), que é um delimitador padrão paraPARA, que analisa a linha e atribui a primeira string de token:"sss"para"%f". Então o"eco %f"gera uma linha com apenas:"sss". Essa é a primeira linha que você vê impressa. O"ttt"é simplesmente descartado porque o"PARA... eco %f"O comando não especificou incluir nada além do primeiro token.
Se oPARAcomando foi escrito de forma diferente, você teria visto a linha completa"sss ttt"ecoou.
Aqui estão três maneiras pelas quaisPARAcomando poderia ter sido escrito para fazer isso.
A primeira maneira, usando o"delims="
opção, define o delimitador paraPARApara "vazio", entãoPARAretorna a linha inteira como 1 token. Os tokens ainda são analisados e todos os delimitadores (",;") são removidos, então todos os tokens são combinados novamente com um espaço entre cada token. Este valor combinado é retornado na variável"%f"
C:\>for /f "delims=" %f in ('echo sss ttt') do echo %f
C:\>echo sss ttt
sss ttt
C:\>for /f "delims=" %f in ('echo mm;nn,oo, ;ss ,, tt') do echo %f
C:\>echo mm nn oo ss tt
mm nn oo ss tt
A próxima maneira, usando o"tokens=*"
opção, dizPARApara colocar todos os tokens encontrados no valor da variável especificada ("%f"). Os tokens ainda são analisados e todos os delimitadores são removidos e, em seguida, todos os tokens são combinados novamente com um espaço entre cada token.
C:\>for /f "tokens=*" %f in ('echo sss ttt') do echo %f
C:\>echo sss ttt
sss ttt
C:\>for /f "tokens=*" %f in ('echo mm;nn,oo, ;ss ,, tt') do echo %f
C:\Users\1-kevin>echo mm nn oo ss tt
mm nn oo ss tt
Esta terceira forma, usando o"tokens=1,*"
opção, dizPARApara colocar o primeiro (1) token encontrado no valor da variável especificada ("%f"). E, os tokens restantes são analisados e todos os delimitadores são removidos, então todos os tokens restantes são combinados novamente com um espaço entre cada token, e esse valor combinado é retornado na variável nomeada com a letra que segue o nome da variável especificada (então neste caso, variável"%g").
C:\>for /f "tokens=1,*" %f in ('echo sss ttt') do echo %f %g
C:\>echo sss ttt
sss ttt
C:\>for /f "tokens=1,*" %f in ('echo mm;nn,oo, ;ss ,, tt') do echo "%f" "%g"
C:\>echo "mm" "nn oo ss tt"
"mm" "nn oo ss tt"
Observe que o seguinte não funcionará porque não há "tokens=" definidos para variáveis além da variável especificada de"%f":
C:\>for /f %f in ('echo sss ttt') do echo %f %g
C:\>echo sss %g
sss %g
Então, no seu exemplo, se você adicionou o"delims="
opção, você veria isto:
C:\>for /f "delims=" %f in ('echo g ^| findstr "g"') do echo %f
C:\>echo sss ttt
sss ttt
C:\>echo g
g
C:\>