0
To interact with a program that expects to be able to manipulate a terminal, you should use a pseudo tty. This will avoid the failed tty get
error.
要与期望能够操作终端的程序进行交互,您应该使用伪tty。这将避免失败的tty get错误。
/*...*/
#include
void do_child () {
if (execlp("top", "top", (const char *)0) <0) {
perror("exec top");
exit(EXIT_FAILURE);
}
/* NOTREACHED */
}
void do_parent (int fd, pid_t p) {
sleep(5);
char r;
write(fd, "q", 1);
while (read(fd, &r, 1) > 0) { write(1, &r, 1); }
waitpid(p, 0, 0);
close(fd);
}
int main () {
int fd;
pid_t p = forkpty(&fd, 0, 0, 0);
switch (p) {
case 0: do_child();
/* NOTREACHED */
case -1: perror("forkpty");
exit(EXIT_FAILURE);
default: break;
}
do_parent(fd, p);
return 0;
}
Note that forkpty
is not POSIX, but an interface that is available on BSD and Linux flavors of UNIX.
请注意,forkpty不是POSIX,而是在BSD和UNIX版本的UNIX上可用的接口。
You can execute top
in a batch mode, but you can't use a command to quit. You have to kill it.
您可以在批处理模式下执行top,但不能使用命令退出。你必须杀了它。
void do_child () {
if (execlp("top", "top", "-b", (const char *)0) <0) {
perror("exec top");
exit(EXIT_FAILURE);
}
/* NOT REACHED */
}
void do_parent (pid_t p) {
sleep(5);
if (kill(p, SIGINT) <0) {
perror("kill");
exit(EXIT_FAILURE);
}
waitpid(p, 0, 0);
}
int main () {
pid_t p;
switch ((p = fork())) {
case 0: do_child();
case -1: perror("fork"); exit(EXIT_FAILURE);
default: break;
}
do_parent(p);
return 0;
}
Although running in batch mode would allow you to open the process with a simpler call (such as popen
as mux suggests), unless that call returns the process id of the child, you won't be able to kill it (without executing a pkill
, or dig through the process table to find the right child process to kill).
虽然以批处理模式运行会允许您通过更简单的调用打开进程(例如popen作为mux建议),除非该调用返回子进程的进程ID,否则您将无法杀死它(不执行pkill) ,或通过进程表挖掘找到正确的子进程来杀死)。
I think you have some confusion about how to use dup2
. The manual page uses the terms oldfd
and newfd
, and it means that oldfd
will become newfd
. To illustrate, here is a simple program that redirects stdout and stderr to a log file, calls a function, and then restores stdout and stderr afterward.
我认为你对如何使用dup2有些困惑。手册页使用术语oldfd和newfd,这意味着oldfd将成为newfd。为了说明,这是一个简单的程序,它将stdout和stderr重定向到一个日志文件,调用一个函数,然后恢复stdout和stderr。
void do_something () {
fputs("Error message\n", stderr);
puts("This is regular output.");
fputs("Error message\n", stderr);
puts("This is regular output.");
}
int main () {
int fd = creat("/tmp/output.log", 0664);
int outfd = dup(fileno(stdout));
int errfd = dup(fileno(stderr));
fflush(stdout);
fflush(stderr);
dup2(fd, fileno(stdout));
dup2(fd, fileno(stderr));
setlinebuf(stdout);
do_something();
fflush(stdout);
fflush(stderr);
dup2(outfd, fileno(stdout));
dup2(errfd, fileno(stderr));
close(outfd);
close(errfd);
fputs("Error to the screen\n", stderr);
puts("Regular output to screen");
fputs("Error to the screen\n", stderr);
puts("Regular output to screen");
return 0;
}
As mux pointed out, your program is writing to the wrong end of the pipe. The pipe
command returns a unidirectional pair of file descriptors, where what ever is written to fd_pipe[1]
can be read from fd_pipe[0]
.
正如mux指出的那样,你的程序正在写入错误的管道末端。 pipe命令返回一对单向文件描述符,其中写入fd_pipe [1]的内容可以从fd_pipe [0]中读取。