我尝试使用管道、叉子和 dup 在我的程序中执行 md5sume 命令。我发现总和代码运行成功,但我无法理解某些代码行。这是我的代码:
int infp, outfp;
char buf[128];
if (popen2("md5sum", &infp, &outfp) <= 0)
{
printf("Unable to exec sort\n");
exit(1);
}
write(infp, "hello\n", 2);
close(infp);
*buf = '\0';
read(outfp, buf, 128);
printf("buf = '%s'\n", buf);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
int p_stdin[2], p_stdout[2];
pid_t pid;
if (pipe(p_stdin) != 0 || pipe(p_stdout) != 0)
return -1;
pid = fork();
if (pid < 0)
return pid;
if (pid == 0)
{
close(p_stdin[WRITE]);
dup2(p_stdin[READ], READ);
close(p_stdout[READ]);
dup2(p_stdout[WRITE], WRITE);
execl("/bin/sh", "sh", "-c", command, NULL); …Run Code Online (Sandbox Code Playgroud) 我在手册页中查了一下,但我仍然没有得到它......
让我们说你有dup2(f1,0).是否用stdin切换filedesc.1然后锁定stdin?
这是代码:
int main()
{
std::cout << "In stdout" << std::endl;
int stdoutBack = dup(1);
close(1);
int output = open("buffer.txt", O_RDWR|O_CREAT|O_APPEND, 0777);
dup2(output, 1);
std::cout << "In buffer" << std::endl;
dup2(output, stdoutBack);
close(output);
std::cout << "In stdout" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
我想要发生的是"在标准输出"打印到标准输出,"在缓冲区"打印到buffer.txt,然后"在标准输出"再次打印到标准输出.
在上面的代码中实际发生的是"在stdout中"打印到stdout,"在缓冲区"打印到buffer.txt",但最后一个"输入stdout"消息无处可寻.
我必须编写一个可以运行管道的shell.例如ls -l | wc -l".我已成功解析用户给出的命令,如下所示:
"ls"= firstcmd
"-l"= frsarg
"wc"= scmd
"-l"= secarg
现在我必须使用两个叉子,因为命令是两个和一个管道.我写的执行命令的代码块如下:
pid_t pid;
int fd[2];
pipe(fd);
pid = fork();
if(pid==0)
{
dup2(fd[WRITE_END], STDOUT_FILENO);
close(fd[READ_END]);
execlp(firstcmd, firstcmd, frsarg, (char*) NULL);
}
else
{
pid=fork();
if(pid==0)
{
dup2(fd[READ_END], STDIN_FILENO);
close(fd[WRITE_END]);
execlp(scmd, scmd, secarg, (char*) NULL);
}
}
Run Code Online (Sandbox Code Playgroud)
因此,当我运行我的shell并输入命令时ls -l | wc -l(例如),execs的结果没有显示,但是shell保持正常运行.
奇怪的是,只有当我用"exit"或"^ C"终止我的shell时,命令的结果才会显示.
输出有什么问题?输入命令后为什么不显示?
我试图用另一个管道替换stdin,然后将原始stdin放回到fd#0.
例如
dup2(p, 0); // p is a pre-existing fd of a pipe
exec(/* some commands */);
//what will be here in order to have the original stdin back?
scanf(...) //continue processing with original stdin.
Run Code Online (Sandbox Code Playgroud) 这是从一个跟进的问题在这里.
我希望能够暂时将stdout重定向到临时文件,而python仍然可以打印到stdout.这将涉及以下步骤:
new)的副本tmp)tmpnewstdouttmp到"真正的"标准输出tmp我尝试通过以下方式实现上述方法:
import os
import subprocess
import sys
#A function that calls an external process to print to stdout as well as
#a python print to pythons stdout.
def Func(s, p = False):
subprocess.call('echo "{0}"'.format(s), shell = True)
if p:
print "print"
sil = list() # <-- Some list to store the content of the temp files
print …Run Code Online (Sandbox Code Playgroud) 前段时间我使用 pthread 为 Dining Philosophers Problem 编写了一个 C 程序,现在我正在尝试将其更改为使用 fork() 代替。这是我已经通过的讲座的练习。但是一个朋友向我求助,我似乎无法自己弄清楚,这让我发疯!
如果我做一个“ps”,进程就在那里。但是标准输出没有任何输出,所以我认为我的管道有问题。
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#define N 5
#define LEFT (i+4)%N
#define RIGHT (i+1)%N
#define THINKING 0
#define HUNGRY 1
#define EATING 2
sem_t spoon;
sem_t phil[N];
int state[N];
int phil_num[N]={0,1,2,3,4};
int fd[N][2]; // file descriptors for pipes
pid_t pid, pids[N]; // process ids
int i;
int num;
void philosopher(int i);
void test(int i);
void take_spoon(int i); …Run Code Online (Sandbox Code Playgroud) 我可以用dup2(或fcntl)做一些魔法,所以我将stdout重定向到一个文件(即,写入描述符1的任何东西都会转到文件中),但是如果我使用了其他一些机制,它会转到终端输出?如此松散:
int original_stdout;
// some magic to save the original stdout
int fd;
open(fd, ...);
dup2(fd, 1);
write(1, ...); // goes to the file open on fd
write(original_stdout, ...); // still goes to the terminal
Run Code Online (Sandbox Code Playgroud) 我这辈子都无法完全清醒过来dup2()。
int fd = open("data", O_RDONLY);
/* open the disk file */
int newfd = dup2(fd,0);
/* close 0, dup fd to 0 */
if( newfd != 0)
{
fprintf(stderr,"Could not duplicate fd to 0\n");
exit(1);
}
close(fd);
Run Code Online (Sandbox Code Playgroud)
所以我知道dup2()在这种情况下将关闭 0 (标准输入的标准键盘输入),然后它将使标准输入从文件数据中读取,但为什么要这样做呢close(fd)?我以为 fd 是 stdin 现在正在读取的内容?
运行此程序时,"stdr"行显示在"stdout"行之前.为什么?我认为dup2会使stderr和stdout使用相同的文件描述符,所以缓冲应该没有问题.我在Solaris 10上使用gcc 3.4.6.
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
int fd[2];
int pid;
char buf[256];
int n;
if(pipe(fd) < 0) {
perror("pipe");
return 1;
}
if((pid = fork()) < 0) {
perror("fork");
return 1;
}
else if(pid > 0) { // parent
close(fd[1]);
if((n = read(fd[0], buf, sizeof(buf))) > 0) {
buf[n] = 0;
printf("%s", buf);
}
}
else {
dup2(fd[1], fileno(stdout));
dup2(fd[1], fileno(stderr));
close(fd[1]);
fprintf(stdout,"stdout\n");
fprintf(stderr,"stderr\n");
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)