目录
在 Linux 操作系统中,stdout
(标准输出)的数据存储位置并不是一个物理文件,而是一个由内核管理的文件描述符。具体来说,stdout
是文件描述符 1,它指向了进程的标准输出流。这个标准输出流可以重定向到其他文件、设备或管道中。
下面将介绍 linux 下对于 shell 命令执行 stdout 的使用,并详细介绍在 Java 与 C 语言环境下的处理流程。
一、Linux Shell
当一个用户进程被创建时,系统会自动为该进程创建三个数据流,即 stdin
(标准输入)、stdout
(标准输出 1)和 stderr
(标准错误输出 2)。这些数据流默认是表现在用户终端上的,也就是说,当你在终端上执行一个命令时,该命令的输出会显示在终端屏幕上。
我们可以通过重定向操作或管道将数据流进行重定向。
# 查看当前所有进程,将 stdout 接入匿名管道,输出到 grep 工具中进行字符过滤
ps -eaf | grep mongod
# 读取备份数据,并重定向到 ontape 工具进行数据库恢复操作
ontape -r -t STDIO < data.bak
# 也可以通过重定向操作 2>&1 将 stderr 输出到 stdout 里面
script.sh > output.txt 2>&1
二、Java 语言
在 Java中,当通过Runtime.getRuntime().exec(cmd)
执行shell命令时,该命令的标准输出(stdout
)默认被重定向到一个新的Process
对象中。这意味着,所有通过stdout
打印的内容都会被暂存在这个Process
对象的缓冲区中。如果不及时读取这个缓冲区,那么随着缓冲区的填满,子进程(即正在执行的shell命令)将会被阻塞,因为它无法继续向stdout写入数据。这会导致整个程序暂停执行,直到有空间可以写入更多的输出。
// 命令执行类
public class Exec extends Task {
private String os;
private String out;
private File dir;
private String command;
// CheckStyle:VisibilityModifier OFF - bc
protected PrintWriter fos = null;
// CheckStyle:VisibilityModifier ON
private boolean failOnError = false;
/**
* Constructor for Exec.
* Prints a warning message to std error.
*/
public Exec() {
System.err.println("As of Ant 1.2 released in October 2000, "
+ "the Exec class");
System.err.println("is considered to be dead code by the Ant "
+ "developers and is unmaintained.");
System.err.println("Don\'t use it!");
}
/**
* Execute the task.
* @throws BuildException on error
*/
public void execute() throws BuildException {
run(command);
}
/**
* Execute the command.
* @param command the command to exec
* @return the exit value of the command
* @throws BuildException on error
*/
protected int run(String command) throws BuildException {
int err = -1; // as