与管道C程序excecute"的ps aux |用grep火狐|三通processes.txt" [英] c program with pipes to excecute "ps aux | grep firefox | tee processes.txt"
本文介绍了与管道C程序excecute"的ps aux |用grep火狐|三通processes.txt"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
这是我的第一个问题。但愿它不会dumm。林有问题编写生产的ps aux | grep的火狐|三通processes.txt的程序。我成功了1管像的ps aux | grep按火狐,但是当我试图概括我有问题。我的目的是使用管道去了解他们。我知道这是可能的开放。任何暗示将是巨大的!
This is my first question. Hopefully it will not be dumm. Im having problems to write a program that produce "ps aux | grep firefox | tee processes.txt". I succeeded with 1 pipe like "ps aux | grep firefox ", but when I tried to generalize I have problems. My intention is to use pipes to understand them. I know that is possible with open. Any hint would be great!
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <sys/types.h>
int main(void)
{
char *** args = NULL;
pid_t fork_id = -1;
int ** pipes = NULL;
int status = 0;
int i = 0, k = 0;
int check = 0;
args = calloc(3, sizeof(char **));
args [0] = calloc(3, sizeof(char *));
args [1] = calloc(3, sizeof(char *));
args [2] = calloc(3, sizeof(char *));
args[0][0]= "ps";
args[0][1]="aux";
args[0][2]= NULL;
args[1][0]= "grep";
args[1][1]= "firefox";
args[1][2]= NULL;
args[2][0]= "tee";
args[2][1]= "processes.txt";
args[2][2]= NULL;
pipes=calloc(2,sizeof(int *));
for(i=0;i<2;++i){
pipes[i]=calloc(2,sizeof(int));
}
for(i=0;i<2;++i){
pipes[i]=calloc(2,sizeof(int));
check=pipe(pipes[i]);
if(check<0){
perror("pipe");
exit(EXIT_FAILURE);
}
}
for(i=0;i<3;++i){
if ((fork_id = fork()) < 0) {
perror("fork()");
exit(1);
}
if ((i ==0)&& (fork_id == 0)){
close(pipes[i][0]);
close(1);
dup(pipes[i][1]);
close(pipes[i][1]);
execvp(args[i][0], args[0]);
} else if ((i!= 0)&&(i != 2) && (fork_id == 0)){
close(0);
dup(pipes[i][0]);
close(pipes[i][0]);
close(1);
dup(pipes[i][1]);
close(pipes[i][1]);
execvp(args[i][0], args[i]);
} else if ((i==2)&&(fork_id != 0)){
close(pipes[i-1][1]);
close(0);
dup(pipes[i-1][0]);
close(pipes[i-1][0]);
execvp(args[i][0], args[i]);
}
wait(&status);
}
for(i=0;i<2;++i){
for(k=0;k<2;++k){
check=close(pipes[i][k]);
if(check<0){
perror("close pipe");
exit(EXIT_FAILURE);
}
}
}
return(0);
}
THX !!
thx!!
推荐答案
接受的解决方案,以 SO 13636252 是平凡适应这条管道:
The accepted solution to SO 13636252 is trivially adaptable to this pipeline:
/*
** How to create a pipeline of N processes?
** SO 18582446: ps aux | grep firefox | tee processes.txt
** Adaptation of accepted answer to:
** SO 13636252 C Minishell adding pipelines
*/
/* stderr.h */
#ifndef STDERR_H_INCLUDED
#define STDERR_H_INCLUDED
static void err_setarg0(const char *argv0);
static void err_sysexit(char const *fmt, ...);
static void err_syswarn(char const *fmt, ...);
#endif /* STDERR_H_INCLUDED */
/* pipeline.c */
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>
/*#include "stderr.h"*/
typedef int Pipe[2];
/* Now: ps aux | grep firefox | tee processes.txt */
/* Was: who | awk '{print $1}' | sort | uniq -c | sort -n */
static char *cmd0[] = { "ps", "aux", 0 };
static char *cmd1[] = { "grep", "firefox", 0 };
static char *cmd2[] = { "tee", "processes.txt", 0 };
static char **cmds[] = { cmd0, cmd1, cmd2, };
static int ncmds = sizeof(cmds) / sizeof(cmds[0]);
/* exec_nth_command() and exec_pipe_command() are mutually recursive */
static void exec_pipe_command(int ncmds, char ***cmds, Pipe output);
/* With the standard output plumbing sorted, execute Nth command */
static void exec_nth_command(int ncmds, char ***cmds)
{
assert(ncmds >= 1);
if (ncmds > 1)
{
pid_t pid;
Pipe input;
if (pipe(input) != 0)
err_sysexit("Failed to create pipe");
if ((pid = fork()) < 0)
err_sysexit("Failed to fork");
if (pid == 0)
{
/* Child */
exec_pipe_command(ncmds-1, cmds, input);
}
/* Fix standard input to read end of pipe */
dup2(input[0], 0);
close(input[0]);
close(input[1]);
}
execvp(cmds[ncmds-1][0], cmds[ncmds-1]);
err_sysexit("Failed to exec %s", cmds[ncmds-1][0]);
/*NOTREACHED*/
}
/* Given pipe, plumb it to standard output, then execute Nth command */
static void exec_pipe_command(int ncmds, char ***cmds, Pipe output)
{
assert(ncmds >= 1);
/* Fix stdout to write end of pipe */
dup2(output[1], 1);
close(output[0]);
close(output[1]);
exec_nth_command(ncmds, cmds);
}
/* Execute the N commands in the pipeline */
static void exec_pipeline(int ncmds, char ***cmds)
{
assert(ncmds >= 1);
pid_t pid;
if ((pid = fork()) < 0)
err_syswarn("Failed to fork");
if (pid != 0)
return;
exec_nth_command(ncmds, cmds);
}
/* Collect dead children until there are none left */
static void corpse_collector(void)
{
pid_t parent = getpid();
pid_t corpse;
int status;
while ((corpse = waitpid(0, &status, 0)) != -1)
{
fprintf(stderr, "%d: child %d status 0x%.4X\n",
(int)parent, (int)corpse, status);
}
}
static void exec_arguments(int argc, char **argv)
{
/* Split the command line into sequences of arguments */
/* Break at pipe symbols as arguments on their own */
char **cmdv[argc/2]; // Way too many
char *args[argc+1];
int cmdn = 0;
int argn = 0;
cmdv[cmdn++] = &args[argn];
for (int i = 1; i < argc; i++)
{
char *arg = argv[i];
if (strcmp(arg, "|") == 0)
{
if (i == 1)
err_sysexit("Syntax error: pipe before any command");
if (args[argn-1] == 0)
err_sysexit("Syntax error: two pipes with no command between");
arg = 0;
}
args[argn++] = arg;
if (arg == 0)
cmdv[cmdn++] = &args[argn];
}
if (args[argn-1] == 0)
err_sysexit("Syntax error: pipe with no command following");
args[argn] = 0;
exec_pipeline(cmdn, cmdv);
}
#include <signal.h>
typedef void (*SigHandler)(int signum);
static void sigchld_status(void)
{
const char *handling = "Handler";
SigHandler sigchld = signal(SIGCHLD, SIG_IGN);
signal(SIGCHLD, sigchld);
if (sigchld == SIG_IGN)
handling = "Ignored";
else if (sigchld == SIG_DFL)
handling = "Default";
printf("SIGCHLD set to %s\n", handling);
}
int main(int argc, char **argv)
{
err_setarg0(argv[0]);
sigchld_status();
if (argc == 1)
{
/* Run the built in pipe-line */
exec_pipeline(ncmds, cmds);
}
else
{
/* Run command line specified by user */
exec_arguments(argc, argv);
}
corpse_collector();
return(0);
}
/* stderr.c */
/*#include "stderr.h"*/
#include <stdio.h>
#include <stdarg.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
static const char *arg0 = "<undefined>";
static void err_setarg0(const char *argv0)
{
arg0 = argv0;
}
static void err_vsyswarn(char const *fmt, va_list args)
{
int errnum = errno;
fprintf(stderr, "%s:%d: ", arg0, (int)getpid());
vfprintf(stderr, fmt, args);
if (errnum != 0)
fprintf(stderr, " (%d: %s)", errnum, strerror(errnum));
putc('\n', stderr);
}
static void err_syswarn(char const *fmt, ...)
{
va_list args;
va_start(args, fmt);
err_vsyswarn(fmt, args);
va_end(args);
}
static void err_sysexit(char const *fmt, ...)
{
va_list args;
va_start(args, fmt);
err_vsyswarn(fmt, args);
va_end(args);
exit(1);
}
这篇关于与管道C程序excecute&QUOT;的ps aux |用grep火狐|三通processes.txt&QUOT;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文