如何获取子进程的输出

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何获取子进程的输出相关的知识,希望对你有一定的参考价值。

参考技术A

  经常看到论坛中有人问到当用Process组件启动新的进程后 如何获取它的输出的问题 采取将子进程的输出定向到一个临时文件中 当然也可以解决问题 但是这样每次父进程从临时文件中获取信息后 还要删除该临时文件 毕竟比较麻烦 其实 Process提供了几个属性可以获取输出 框架sdk的帮助文档里面就有这方面的例子 但是对于如何同时获取错误输出和标准输出方面没有给出具体代码 本文将给出实例并对管道的特性作一些说明

   一 获取子进程标准输出和错误输出的的方法

  我们写一个小程序p cs 用它来产生标准输出和错误输出 //p cs代码如下 using System;class class  public static void Main()   int i = ;  string s = String Format( out: i);  System Console Out WriteLine(s );  string s = String Format( err: ************************************************** i);  System Console Error WriteLine(s );     编译成p exe

  获取子进程的标准输出和错误输出的源程序//p cs Process p = new Process( p exe );p StartInfo UseShellExecute = false;  //指定不使用系统的外壳程序 而是直接启动被调用程序本身p StartInfo RedirectStandardOutput = true;  //只有将此属性设为true 才能通过管道获取子进程输出p StartInfo RedirectStandardError = true;

  p Start();  //启动子进程string output = p StandardOutput ReadToEnd(); //读取标准输出string error = p StandardError ReadToEnd(); //读取错误输出p WaitForExit(); //等待子进程执行完毕   上例中 父进程启动子进程后 就等待着从管道中取走标准输出 取走全部标准输出后取走错误输出 我们运行起来没有任何错误 但是一旦我门增加p exe中的标准输出和错误输出的字节数 for(i= ;i< ;i++) System Console Out WriteLine(s );for(i= ;i< ;i++) System Console Error WriteLine(s );编译后 再运行 就会发现父进程和子进程出现了死锁 只有强行关闭才能终止进程

   二 管道         Process 组件通过管道与子进程进行通讯 如果同时重定向标准输出和标准错误 然后试图读取它们 当管道被填满时候就会出现问题 上例中 父进程只有读完了所有的标准输出才能读错误输出 而子进程的标准输出每当把管道填满时候 父进程都会取走 子进程接着向管道输出后续的标准输出 这都运行的很好 可是当子进程执行到输出错误输出的时候 由于子进程还没有运行结束 它的标准输出流就不会处于结束状态(虽然在我们的例子中它的 次循环的标准输出已经执行完毕) 这就导致父进程中的ReadToEnd()方法不会执行完毕 所以父进程中的p StandardError ReadToEnd()无法执行 从而管道中的错误输出无法被读取 子进程的后续错误输出无法写入管道 最终子进程和父进程彼此无限等待 出现了阻塞情况

  子进程通过检查管道中最后一个字节是否被取走 来决定是否输出后续内容 也就是说 如果管道缓冲区中最后一个字节之前的所有内容都被取走 子进程仍然会处于等待中 如果前面所有字节都没有取走 但最后一个字节内容被取走 子进程会继续向管道里输出后续内容 当然这样只能输出一字节到管道中最后位置

  我们如果把p cs中的string output = p StandardOutput ReadToEnd()改为  for(int i= ;i< * ;i++)  Console Write((char) p StandardOutput Read());

  就不会出现死锁情况 因为当获取标准输出的循环执行完后 会接着执行获取错误输出的语句 而不需等待标准输出流的结束 但是这种方法毫无实际意义 因为实际中 我们并不可能像本例中知道标准输出会有多少字节

   三 用多线程分别获取标准输出和错误输出

  对于这种情况框架文档中建议这样解决 创建两个线程 以便应用程序可以在单独的线程上读取每个流的输出 下面给出例子:

lishixinzhi/Article/program/net/201311/11610

如何在nodejs里调用执行系统命令

NodeJS 子进程提供了与系统交互的重要接口,其主要 API 有:
标准输入、标准输出及标准错误输出的接口
child.stdin 获取标准输入
child.stdout 获取标准输出
child.stderr 获取标准错误输出
获取子进程的PID:child.pid
提供生成子进程的方法:child_process.spawn(cmd, args=[], [options])
提供直接执行系统命令的方法:child_process.exec(cmd, [options], callback)
提供调用脚本文件的方法:child_process.execFile(file, [args], [options], [callback])
提供杀死进程的方法:child.kill(signal='SIGTERM')
参考技术A NodeJS 子进程提供了与系统交互的重要接口,其主要 API 有:
标准输入、标准输出及标准错误输出的接口
child.stdin 获取标准输入
child.stdout 获取标准输出
child.stderr 获取标准错误输出
获取子进程的PID:child.pid
提供生成子进程的方法:child_process.spawn(cmd, args=[], [options])
提供直接执行系统命令的方法:child_process.exec(cmd, [options], callback)
提供调用脚本文件的方法:child_process.execFile(file, [args], [options], [callback])
提供杀死进程的方法:child.kill(signal='SIGTERM')

以上是关于如何获取子进程的输出的主要内容,如果未能解决你的问题,请参考以下文章

从提升的子进程获取错误和标准输出

如何在nodejs里调用执行系统命令

如何在python脚本中获取exe的输出?

获取 node.js 中所有嵌套子进程的标准输出

如何在nodejs里调用执行系统命令

linux获取后台进程的控制台数据