Suponha que eu tenha dois programas chamados ProgramA
e ProgramB
. Quero executá-los simultaneamente no interpretador de cmd do Windows. Mas eu quero o StdOut
de ProgramA
gancho para o StdIn
de ProgramB
e o StdOut
de ProgramB
gancho para o StdIn
de ProgramA
.
Algo assim
________________ ________________ | | | | | StdIn (== ← === ← == (StdOut | | Programa A | Programa B | | | | | StdOut) == → === → ==) StdIn | | ________________ | | ________________ |
Existe algum comando para fazer isso - alguma maneira de obter essa funcionalidade do cmd?
windows
batch-file
redirection
stdout
stdin
DarthRubik
fonte
fonte
Respostas:
Não apenas isso pode ser feito, mas apenas com um arquivo em lotes! :-)
O problema pode ser resolvido usando um arquivo temporário como um "pipe". A comunicação bidirecional requer dois arquivos "pipe".
Processo A lê stdin de "pipe1" e grava stdout em "pipe2"
Processo B lê stdin de "pipe2" e grava stdout em "pipe1"
É importante que os dois arquivos existam antes do início de qualquer processo. Os arquivos devem estar vazios no início.
Se um arquivo em lotes tentar ler um arquivo que está no final atual, ele simplesmente não retornará nada e o arquivo permanecerá aberto. Portanto, minha rotina readLine lê continuamente até obter um valor não vazio.
Quero poder ler e escrever uma sequência vazia, portanto, minha rotina writeLine acrescenta um caractere extra que a readLine retira.
Meu processo A controla o fluxo. Ele inicia as coisas escrevendo 1 (mensagem para B) e entra em um loop com 10 iterações, onde lê um valor (mensagem de B), adiciona 1 e depois grava o resultado (mensagem para B). Por fim, aguarda a última mensagem de B e, em seguida, grava uma mensagem "encerrar" em B e sai.
Meu processo B está em um loop condicionalmente interminável que lê um valor (mensagem de A), adiciona 10 e depois grava o resultado (mensagem em A). Se B alguma vez ler uma mensagem "encerrar", ela será encerrada imediatamente.
Queria demonstrar que a comunicação é totalmente síncrona, por isso introduzo um atraso nos loops do processo A e B.
Observe que o procedimento readLine está em um loop restrito que abusa continuamente a CPU e o sistema de arquivos enquanto aguarda a entrada. Um atraso PING pode ser adicionado ao loop, mas os processos não serão tão responsivos.
Eu uso um verdadeiro pipe como uma conveniência para iniciar os processos A e B. Mas o tubo não é funcional, pois nenhuma comunicação passa por ele. Toda a comunicação é feita através dos meus arquivos "pipe" temporários.
Eu poderia ter usado o START / B para iniciar os processos, mas preciso detectar quando os dois terminam, para saber quando excluir os arquivos "pipe" temporários. É muito mais simples usar o tubo.
Eu escolhi colocar todo o código em um único arquivo - o script mestre que inicia A e B, bem como o código para A e B. Eu poderia ter usado um arquivo de script separado para cada processo.
test.bat
--RESULTADO--
A vida é um pouco mais fácil com uma linguagem de nível superior. Abaixo está um exemplo que usa VBScript para os processos A e B. Eu ainda uso o lote para iniciar os processos. Eu uso um método muito interessante descrito em É possível incorporar e executar o VBScript em um arquivo em lotes sem usar um arquivo temporário? para incorporar vários scripts VBS em um único script em lote.
Com um idioma mais alto como o VBS, podemos usar um canal normal para passar informações de A para B. Precisamos apenas de um único arquivo "canal" temporário para passar informações de B de volta para A. Como agora temos um canal em funcionamento, o A O processo não precisa enviar uma mensagem "encerrar" para B. O processo B simplesmente faz um loop até atingir o final do arquivo.
É bom ter acesso a uma função de suspensão adequada no VBS. Isso me permite introduzir facilmente um pequeno atraso na função readLine para dar uma pausa na CPU.
No entanto, há uma ruga no readLIne. No começo, eu estava recebendo falhas intermitentes até perceber que, às vezes, o readLine detectava informações disponíveis no stdin e tentava imediatamente ler a linha antes que B tivesse a chance de terminar de escrever a linha. Resolvi o problema introduzindo um pequeno atraso entre o teste de fim de arquivo e a leitura. Um atraso de 5 ms parecia fazer o truque para mim, mas eu dobrei para 10 ms apenas por segurança. É muito interessante que o lote não sofra esse problema. Discutimos isso brevemente (5 postagens curtas) em http://www.dostips.com/forum/viewtopic.php?f=3&t=7078#p47432 .
A saída é a mesma da solução em lote puro, exceto que as linhas finais "encerradas" não estão lá.
fonte
Nota- Em retrospecto, lendo a pergunta novamente, isso não faz o que é solicitado. Como, apesar de vincular dois processos, (de uma maneira interessante que funcionaria em uma rede!), Ele não vincula os dois lados.
Espero que você obtenha algumas respostas para isso.
Aqui está a minha resposta, mas não a aceite, aguarde outras respostas, estou interessado em ver algumas outras respostas.
Isso foi feito a partir do cygwin. E usando o comando 'nc' (o mais inteligente). O 'wc -l' conta apenas as linhas. Então, eu estou ligando quaisquer dois comandos, neste caso, echo e wc, usando nc.
O comando à esquerda foi feito primeiro.
nc é um comando capaz de: a) criar um servidor ou b) conectar-se como o comando telnet no modo bruto, a um servidor. Estou usando o uso 'a' no comando esquerdo e o uso 'b' no comando direito.
Então nc ficou lá, ouvindo, esperando por uma entrada, e depois canalizou essa entrada
wc -l
e contou as linhas e emitiu o número de linhas inseridas.Em seguida, corri a linha para repetir algum texto e enviá-lo para 127.0.0.1:123, que é o servidor mencionado.
Você pode copiar o comando nc.exe do cygwin e tentar usar esse arquivo e o arquivo cygwin1.dll que ele precisa no mesmo diretório. Ou você pode fazê-lo do próprio cygwin como eu. Não vejo o nc.exe no gnuwin32. Eles têm uma pesquisa http://gnuwin32.sourceforge.net/ e nc ou netcat não aparece. Mas você pode obter o cygwin https://cygwin.com/install.html
fonte
netstat -aon | find ":123"
para ver que o comando à esquerda criou o servidorwc
traseira aoecho
comando).nc -lp9999 | prog1 | prog2 | nc 127.0.0.1 9999
passos podem precisar de ser tomadas para garantir buffers são liberados em tempo hábilUm truque (eu preferiria não fazer isso, mas é com isso que eu vou por enquanto) é escrever um aplicativo C # para fazer isso por você. Eu não implementei alguns recursos importantes neste programa (como realmente usar os argumentos que me foram dados), mas aqui está:
Eventualmente, quando este programa estiver totalmente funcional e o código de depuração for removido, você usaria algo como isto:
fonte