como executar comandos via processo filho do nodejs?
<p>estou tentando executar comandos no windows via processos filho do nodejs:</p><pre><code>var terminal = require('child\_process').spawn('cmd'); terminal.stdout.on('data', function (data) { console.log('stdout: ' + data); }); terminal.stderr.on('data', function (data) { console.log('stderr: ' + data); }); terminal.on('exit', function (code) { console.log('child process exited with code ' + code); }); settimeout(function() { terminal.stdin.write('echo %path%'); }, 2000); </code></pre><p>quando chama <code>ti.stdin.write</code>, ele grava no descritor <code>stdin</code>, mas como faço para que <code>cmd</code> reaja nesse momento? como envio o sinal da tecla "enter" que você faz quando realmente está digitando no prompt de comando? atualmente, não recebo resposta de <code>cmd</code>.</p>
<p>enviar uma nova linha <code>\n</code> executará o comando. <code>.end()</code> sairá do shell.</p><p>modifiquei o exemplo para trabalhar com o bash enquanto estou no osx.</p><pre><code>var terminal = require('child\_process').spawn('bash'); terminal.stdout.on('data', function (data) { console.log('stdout: ' + data); }); terminal.on('exit', function (code) { console.log('child process exited with code ' + code); }); settimeout(function() { console.log('sending stdin to terminal'); terminal.stdin.write('echo "hello $user. your machine runs since:"\n'); terminal.stdin.write('uptime\n'); console.log('ending terminal session'); terminal.stdin.end(); }, 1000); </code></pre><p>a saída será:</p><pre><code>sending stdin to terminal ending terminal session stdout: hello root. your machine runs since: stdout: 9:47 up 50 mins, 2 users, load averages: 1.75 1.58 1.42 child process exited with code 0 </code></pre>
<p>se bem entendi, você deseja enviar dados para um programa em execução dentro de uma sessão de tela. você pode fazer isso com o comando <code>stuff</code> da tela. use a tela <code>-x</code> opção para executar um comando em uma sessão de tela sem anexar a ela.</p><pre><code>screen -s sessionname -p windowname -x stuff 'command1 command2 ' </code></pre><p>se você quiser ver a saída do programa, consulte os comandos <code>hardcopy</code>, <code>log</code> e <code>logfile</code>.</p> <p>adicione esta linha ao seu .vimrc:</p><pre><code>command r !./% </code></pre><p>e então você pode simplesmente digitar ": r" enquanto no vim para executar o script ( <a href="http://www.calebmadrigal.com/vim-run-current-file/">vim-run-current-file</a> )</p> acabei de descobrir um utilitário bem poderoso de controle de processos no terminal o nome dele é htop e com ele é possível fazer o que você quer mas vai ter que configurar ele para fazer isso no próprio utilitário

edit: [[htop]](https://plus.diolinux.com.br/uploads/default/original/2x/b/bf9b441cc78eb9fabbadaa634f575feeca2b97d8.png "htop.png")

eu consegui configurar e ordenar ele para uso de leitura e escrita do … <p>vamos primeiro ver o que acontece se um programa for iniciado a partir de um shell interativo (conectado a um terminal) sem <code>&amp;</code> (e sem nenhum redirecionamento). então, vamos supor que você acabou de digitar <code>foo</code>:</p><ul> <li>o processo executando <code>foo</code> é criado.</li> <li>o processo herda stdin, stdout e stderr do shell. portanto, também está conectado ao mesmo terminal.</li> <li>se o shell receber um <code>sighup</code>, ele também envia um <code>sighup</code> para o processo (o que normalmente causa o término do processo).</li> <li>caso contrário, o shell aguarda (está bloqueado) até o processo terminar.</li> </ul><p>agora, vejamos o que acontece se você colocar o processo em segundo plano, ou seja, digite <code>foo &amp;</code>:</p><ul> <li>o processo executando <code>foo</code> é criado.</li> <li>o processo herda stdout/stderr do shell (portanto, ele ainda grava no terminal).</li> <li>o processo em princípio também herda stdin, mas assim que tenta ler a partir de stdin, ele é interrompido.</li> <li>ele é colocado na lista de trabalhos em segundo plano que a shell gerencia, o que significa especialmente: <ul> <li>ele está listado com <code>jobs</code> e pode ser acessado usando <code>%n</code> (onde <code>n</code> é o número do trabalho).</li> <li>ele pode ser transformado em um trabalho em primeiro plano usando <code>fg</code>, caso em que continua como se você não tivesse usado <code>&amp;</code> (e se foi interrompido devido à tentativa de leitura da entrada padrão, agora pode prosseguir com a leitura do terminal).</li> <li>se o shell recebeu um <code>sighup</code>, ele também envia um <code>sighup</code> para o processo. dependendo do shell e possivelmente das opções definidas para o shell, ao finalizar o shell, ele também enviará um <code>sighup</code> para o processo.</li> </ul> </li> </ul><p>agora <code>disown</code> remove o trabalho da lista de trabalhos do shell, para que todos os subpontos acima não se apliquem mais (incluindo o processo que está sendo enviado um <code>sighup</code> pelo shell). no entanto, observe que <em> ainda </em> está conectado ao terminal, portanto, se o terminal for destruído (o que pode acontecer se for um pty, como os criados por <code>xterm</code> ou <code>ssh</code>, e o programa de controle é finalizado, fechando o xterm ou finalizando a <a href="http://en.wikipedia.org/wiki/secure\_shell"> ssh </a> conexão), o programa falhará assim que tentar ler da entrada padrão ou gravar na saída padrão.</p><p>o que <code>nohup</code> faz, por outro lado, é separar efetivamente o processo do terminal:</p><ul> <li>ele fecha a entrada padrão (o programa <em> não </em> consegue ler qualquer entrada, mesmo que seja executada em primeiro plano. não é interrompido, mas será receba um código de erro ou <code>eof</code>).</li> <li>ele redireciona a saída padrão e o erro padrão para o arquivo <code>nohup.out</code>, para que o programa não falhe ao gravar na saída padrão se o terminal falhar, portanto, o que o processo gravar não será perdido.</li> <li>impede que o processo receba um <code>sighup</code> (portanto, o nome).</li> </ul><p>observe que <code>nohup</code> <em> não remove </em> o processo do controle de tarefas do shell e também não o coloca em segundo plano (mas desde que um primeiro plano <code>nohup</code> trabalho é mais ou menos inútil, você geralmente o coloca em segundo plano usando <code>&amp;</code>). por exemplo, diferentemente de <code>disown</code>, o shell ainda informa quando o trabalho nohup foi concluído (a menos que o shell seja encerrado antes, é claro).</p><p>então, para resumir:</p><ul> <li><code>&amp;</code> coloca o trabalho em segundo plano, ou seja, impede a tentativa de ler as entradas e faz com que o shell não espere sua conclusão.</li> <li><code>disown</code> remove o processo do controle de trabalho do shell, mas ainda o deixa conectado ao terminal. um dos resultados é que o shell não enviará um <code>sighup</code>. obviamente, ele só pode ser aplicado a trabalhos em segundo plano, porque você não pode inseri-lo quando um trabalho em primeiro plano está em execução.</li> <li><code>nohup</code> desconecta o processo do terminal, redireciona sua saída para <code>nohup.out</code> e o protege de <code>sighup</code>. um dos efeitos (o de nomeação) é que o processo não receberá nenhum <code>sighup</code> enviado. é completamente independente do controle do trabalho e pode, em princípio, ser usado também para trabalhos em primeiro plano (embora isso não seja muito útil).</li> </ul> <p>na página do manual <code>ps</code>:</p><blockquote> <p>-e selecione todos os processos. idêntico a -a.</p> </blockquote><p>portanto, <code>ps -e</code> exibirá todos os processos. as opções comuns para "me dê tudo" são <code>ps -ely</code> ou <code>ps aux</code>, o último é o estilo bsd. frequentemente, as pessoas canalizam essa saída para <code>grep</code> para procurar um processo, como na resposta do xenoterracide. para evitar também ver <code>grep</code> na saída, você verá frequentemente algo como:</p><pre><code> ps -ef | grep [f]oo </code></pre><p>onde foo é o nome do processo que você está procurando.</p><p>no entanto, se você estiver procurando por um processo específico, recomendo usar o comando <code>pgrep</code> se estiver disponível. acredito que esteja disponível no ubuntu server. usar <code>pgrep</code> significa evitar a condição de corrida mencionada acima. ele também fornece alguns outros recursos que exigiriam truques <code>grep</code> cada vez mais complicados para serem replicados. a sintaxe é simples:</p><pre><code>pgrep foo </code></pre><p>onde foo é o processo pelo qual você está procurando. por padrão, ele simplesmente emitirá o id do processo (pid) do processo, se encontrar um. vejo <code>man pgrep</code> para outras opções de saída. achei a seguinte página muito útil:</p><p> <a href="http://mywiki.wooledge.org/processmanagement">http://mywiki.wooledge.org/processmanagement</a> </p> <p>para executar um serviço <em>sem ou antes</em> efetuando login no sistema (ou seja, "na inicialização"), você precisará criar um script de inicialização e adicioná-lo à sequência de inicialização.<br> há três partes em um script de serviço: iniciar, parar e reiniciar.<br> a estrutura básica de um script de serviço é:</p><pre><code>#!/bin/bash # retval=0; start() { echo “starting &lt;service&gt;” } stop() { echo “stopping &lt;service&gt;” } restart() { stop start } case “$1″ in start) start ;; stop) stop ;; restart) restart ;; *) echo $”usage: $0 {start|stop|restart}” exit 1 esac exit $retval </code></pre><p>depois de ajustar o script ao seu gosto, basta colocá-lo em /etc/init.d/<br> e adicione-o ao processo de inicialização do serviço do sistema (no fedora, eu não sou um usuário do ubuntu,&gt; d):</p><pre><code>chkconfig -add &lt;servicename&gt; </code></pre><p>o serviço será adicionado ao processo de inicialização do sistema e você não precisará iniciá-lo manualmente novamente.</p><p>felicidades!</p> <p>boa noite, meu xará! como vai?</p>
<p>o correto é <code>npm start</code> e não <code>node start</code>. faça essa correção no comando executado e veja se as coisas funcionam da forma como vc esperava.</p>
<p>qualquer coisa é só falar!</p>
<p>grande abraço e bons estudos, meu aluno!</p> <p>a maneira mais fácil de fazer isso é iniciar o powershell com tokens de administração. para fazer isso, clique com o botão direito do mouse em powershell (ou um atalho para ele) e clique em "executar como administrador". como alternativa, você pode usar <a href="http://4sysops.com/archives/script-elevation-powertoys-how-to-elevate-on-the-command-prompt-and-launch-powershell-from-a-windows-explorer-context-menu-in-vista/">elevate.cmd</a> .</p> <p>então o que eu fiz é isso:</p><p>eu criei um arquivo de texto simples e escrevi o seguinte script bash para um programa de tradução em latim que eu uso, chamado <a href="http://archives.nd.edu/whitaker/words.htm">words</a> :</p><pre><code>#! /bin/bash cd ~/latin/latin.words/ ./words </code></pre><p>depois de salvá-lo na minha pasta pessoal, tornei-o executável, o que pode ser feito de duas maneiras. cliquei com o botão direito, escolha <strong>properties-&gt; permissions</strong>, e marque a caixa <strong>"execute"</strong> para seu nome de usuário. ou eu poderia ter usado a linha de comando e inserido <code>chmod +x file.name</code>.</p><p>então eu cliquei com o botão direito no painel e selecionei <strong>add to panel</strong>, selecione <strong>custom application launcher.</strong> eu digitei o nome, neste caso <strong>words</strong>, e o caminho para o script que acabei de escrever no campo <strong>command</strong>. como <code>words</code> é um programa de linha de comando, selecionei <strong>program in terminal</strong> no menu suspenso. então, cliquei no ícone e selecionei um apropriado, e com isso terminei de adicioná-lo ao painel.</p><p>em seguida, cliquei em <strong>system-&gt; preferences-&gt; main</strong> menu, selecionei a pasta na qual queria colocar o iniciador de menu e, em seguida, cliquei em <strong>add item.</strong> eu então repeti o processo i acabado de executar, acima.</p><p>e agora eu tenho um lançador personalizado que funciona para um programa que deve ser executado a partir de seu próprio diretório, tanto no meu painel quanto no menu!</p> <p>adicione o seguinte a ~/.bashrc</p><pre><code># avoid duplicates histcontrol=ignoredups:erasedups # when the shell exits, append to the history file instead of overwriting it shopt -s histappend # after each command, append to the history file and reread it prompt\_command="${prompt\_command:+$prompt\_command$'\n'}history -a; history -c; history -r" </code></pre>