Gravando saída de comando no cmd do Windows em um arquivo (com um toque)

9

Então, eu estou tentando executar foo.exe, mas não quero a saída para o terminal, mas para um arquivo. Correr foo.exe > foo.txtdeve fazer isso por mim, mas não é. Quando estou executando o arquivo exe, recebo a saída. O exe está funcionando bem em outras palavras. No entanto, quando tento enviar a saída para um arquivo, a única coisa que recebo é:

'c:/Program' is not recognized as an internal or external command,
operable program or batch file.

Isso aparece quando tento enviá-lo para um arquivo. Pensando que poderia ser o caminho (que é c:\Program Files (x86)\e assim por diante) que é mal interpretado, tentei especificar o arquivo de saída da seguinte forma:, foo.exe > c:\test.txtmas ainda assim não há alegria.

Portanto, além de afirmar que o binário que estou tentando executar está mal escrito, há algo que eu possa fazer para remediar isso? Lembre-se de que eu recebo uma saída válida ao simplesmente executar o exe, ele simplesmente não será impresso em um arquivo. Obviamente, a saída está lá, a questão é se existe alguma maneira de capturá-la.

pzkpfw
fonte
O que acontece se você mover o programa para um diretório simples (C: \ Simple ou mesmo C: \) e tentar essas coisas a partir daí?
Jan Doggen

Respostas:

21

Você não mostrou o comando que está usando que está falhando. Se você o mostrar na sua pergunta, poderá ser mais fácil encontrar uma solução para você.

Espero que seu comando seja algo como isto:

C:\>foo.exe|c:\Program Files (x86)\something\test.txt

O erro que você está recebendo é uma pista:

'c:/Program' is not recognized as an internal or external command, operable program or batch file.

Primeiro:
... is not recognized as an internal or external command, operable program or batch file.

Isso normalmente acontece quando você tenta redirecionar para um arquivo usando um em |vez de um >.

Segundo:
'c:/Program' ...

Ao especificar um nome de arquivo (ou caminho) que contenha espaços, você deve colocá-lo entre aspas duplas ( "..."). Isto porque, quando o sistema operacional é determinar o arquivo para redirecionar para, ele vai parar de olhar para o nome do arquivo quando encontra um espaço sem aspas: "c:/Program".

Tente o seguinte:

foo.exe>"c:\Program Files (x86)\something\test.txt"



Se o acima não funcionar para capturar a saída do foo.exearquivo de texto, existe outra possibilidade ...

Se o programa foo.exeestiver gravando sua saída em STDERRvez de STDOUT, a saída de foo.exenão será capturada usando o redirecionamento simples com um único >. Você teria que fazer assim:

foo.exe>"c:\Program Files (x86)\something\test.txt" 2>&1



Editar:

Aqui está uma explicação do redirecionamento de arquivo e da 2>&1notação.

Quando um programa grava no terminal, ele pode gravar em um dos dois Streams.

  1. Fluxo 1 é referido como STDOUTou Standard-Output . Normalmente, os programas gravam sua saída "Normal" no fluxo 1.

  2. O fluxo 2 é referido como STDERRou erro-padrão . Normalmente, os programas gravam sua saída "Erro" (mensagens de erro e aviso) no fluxo 2.

Se um programa grava uma saída específica STDOUTou STDERRé determinado pelo programador e como ele o escreveu. Alguns programas são gravados para enviar toda a saída (saída normal e erros) para STDOUT.

Quando um programa é executado sem redirecionamento de saída, todas as saídas normais e de erro são enviadas para a tela do terminal sem distinção entre o que é STDOUTsaída ou STDERRsaída.

Quando você faz o redirecionamento "normal" com um único >como este:

foo.exe > "c:\Program Files (x86)\something\test.txt"

você não está especificando qual fluxo está sendo redirecionado para o arquivo, portanto, o fluxo 1 é assumido.

É o mesmo que se você o tivesse digitado assim:

foo.exe 1> "c:\Program Files (x86)\something\test.txt"

Isso informa ao comando intérprete ( cmd.exe) para capturar a saída do programa para STDOUT(Fluxo 1) no nome do arquivo especificado. O 1in 1>refere-se ao fluxo 1.

Nesse caso, todo o programa normal é capturado no arquivo, mas se o programa gravar no STDERR(Fluxo 2), essa saída não será capturada e será mostrada na tela. Geralmente, essa é a maneira "desejada" de fazê-lo, de modo que enquanto estiver capturando a saída normal do programa, você pode ver na tela se ocorrer um erro.

Se você deseja capturar a saída "Normal" em um arquivo e a saída "Erro" em um arquivo diferente, é possível fazer o seguinte:

    foo.exe > "c:\output.txt" 2> "C:\error.txt"
or
    foo.exe 1> "c:\output.txt" 2> "C:\error.txt"

Se você deseja que a saída "Normal" e a saída "Erro" sejam capturadas no mesmo arquivo, você pode especificá-lo assim:

foo.exe > "c:\output.txt" 2>&1

Essa é basicamente uma maneira "abreviada" de especificá-la e significa redirecionar o Fluxo 1 para o arquivo especificado e também redirecionar o Fluxo 2 para o mesmo "local" (arquivo) do Fluxo 1.


Editar:

Pacerier perguntou:

Existe alguma diferença entre foo.exe> ​​"c: \ output.txt" 2> & 1 e foo.exe> ​​"c: \ output.txt" 2> "c: \ output.txt"? Eles são idênticos?

Resposta curta: você pensaria que eles são idênticos, mas não. Eles são diferentes.

Com o redirecionamento usando >"filename.ext", 1>"filename.ext"ou 2>"filename.ext", o >faz com que a saída seja gravada em um novo arquivo chamado "filename.ext". Se o arquivo "filename.ext" já existir, ele será excluído primeiro.

Então, usando:

foo.exe> ​​"c: \ output.txt" 2> "c: \ output.txt"

causa um "conflito" em que ambos os redirecionamentos estão tentando gravar no mesmo arquivo e ambos estão tentando excluir o arquivo, se ele já existir. Isso provavelmente causará comportamento indesejado. Geralmente, uma ou outra, ou ambas, as saídas NÃO serão capturadas total ou previsivelmente.

O resultado real dependerá do sistema operacional e da versão e também poderá depender do comando que está sendo executado. O que provavelmente vai acontecer é:

1 A saída enviada para um dos redirecionamentos será capturada ou parcialmente capturada e a saída enviada para outro redirecionamento será perdida. 2 O sistema operacional irá reclamar do comando e nenhuma das saídas será capturada (totalmente). 3 Comportamento indefinido, indesejado, imprevisível e inesperado.

No Windows 7 e provavelmente no Windows Vista / 8/10, e possivelmente no Windows XP, o sistema operacional irá reclamar do comando e o comando será cancelado.

Por exemplo (Windows 7): tenho uma pasta chamada: "C:\Temp\emptyfolder"e um arquivo chamado "nonexistantfile" não existe lá.

C:\>cd "\Temp\emptyfolder"

C:\Temp\emptyfolder>dir nonexistantfile>output.txt
File Not Found

C:\Temp\emptyfolder>type output.txt
 Volume in drive F is FFFFx1tb
 Volume Serial Number is 4011-A5C6

 Directory of C:\Temp\emptyfolder

C:\Temp\emptyfolder>

Nesse caso, usando um redirecionamento ( >output.txt), a saída do dircomando é capturada no arquivo:, output.txte a mensagem de erro File Not Foundé exibida na tela ... esse é o comportamento esperado.

Agora, usando os dois redirecionamentos ("> arquivo" AND "2> arquivo"):

C:\Temp\emptyfolder>dir nonexistantfile>output.txt 2>output.txt
The process cannot access the file because it is being used by another process.
C:\Temp\emptyfolder>type output.txt

C:\Temp\emptyfolder>

Nesse caso, o sistema operacional reclamou que o arquivo (saída) já está em uso. E o arquivo "output.txt" acaba vazio (0 bytes), e a saída para os dois redirecionamentos foi perdida.

Agora, finalmente, usando os dois redirecionamentos ("> arquivo" AND "2> & 1"):

C:\Temp\emptyfolder>dir nonexistantfile>output.txt 2>&1

C:\Temp\emptyfolder>type output.txt
 Volume in drive C is CCCCCCCC
 Volume Serial Number is 1234-ABCD

 Directory of C:\Temp\emptyfolder

File Not Found

C:\Temp\emptyfolder>

Nesse caso, "> arquivo" faz com que a saída do "fluxo 1" ("saída padrão") seja capturada no arquivo. E "2> & 1" faz com que a saída do "fluxo 2" ("saída de erro") seja enviada pelo "fluxo 1" já redirecionado e também seja capturada no (mesmo) arquivo.

Também é importante notar que a ordem é importante. Invertendo a ordem desta forma:

dir nonexistant 2>&1 >output.txt

não é o mesmo e provavelmente não fornecerá o resultado desejado.

Nesse caso, "2> & 1", que é visto e pré-processado primeiro, faz com que a saída do "fluxo 2" ("saída de erro") seja redirecionada para o local para o qual o "fluxo 1" está direcionado atualmente, que nesse momento momento, é (por padrão) a tela. E "> arquivo" faz com que a saída do "fluxo 1" ("saída padrão") seja capturada no arquivo. O resultado final é que a saída do comando ("fluxo 1") será capturada no arquivo, mas a saída de erro ("fluxo 2") ainda será exibida na tela (não no arquivo).

Kevin Fegan
fonte
Acontece que foo.exe>"c:\test.txt"realmente funcionou, mas ocorreu um erro de que o programa travou (a saída ainda estava lá). No entanto, sua sugestão tornou ainda melhor quando a 2>&1reclamação de falha desapareceu. Quer elaborar o que faz? Obrigado novamente por uma ótima resposta.
Pzkpfw
@ bigbadonk420 - Atualizei minha resposta para incluir informações sobre o uso de 2>&1. Se você examinar seu arquivo "c: \ test.txt", provavelmente verá que a "reclamação de falha" foi gravada no arquivo. 2>&1não deve causar ou impedir que o programa falhe, apenas faz com que as mensagens de erro sejam capturadas em vez de exibidas.
Kevin Fegan
1
Bem, por algum motivo, sim.
Pzkpfw
1
@ bigbadonk420 - 'for some reason it does'de que maneira isso é afetado pelo redirecionamento? Você está dizendo que quando você redireciona 2>&1, inclusive , que o erro não ocorre? Que mensagem de erro você está vendo quando o erro ocorre?
Kevin Fegan
1
Quando 2>&1não está incluído, o programa falha e eu recebo o diálogo padrão do Windows "este programa parou de responder". Quando eu o incluo, isso não acontece. Não faço ideia do porquê. A saída é gerada em ambos os casos.
Pzkpfw