我知道dup,dup2,dup3" 创建文件描述符oldfd的副本 "(来自手册页).但是我无法消化它.
据我所知文件描述符只是数字来跟踪文件的位置和它们的方向(输入/输出).是不是更容易
fd=fd2;
Run Code Online (Sandbox Code Playgroud)
每当我们想复制文件描述符?
还有别的......
dup()使用编号最小的未使用描述符作为新描述符.
这是否意味着它还可以作为值stdin,stdout或stderr,如果我们假设我们有close() -其中一个?
我正在用C++(主要是C)在模拟文件系统上实现管道.它需要在主机shell中运行命令,但在模拟文件系统上执行管道本身.
我可以与实现这一目标pipe(),fork()和system()系统调用,但我宁愿使用popen()(它处理创建一条管道,把一个进程,并通过一个命令外壳).这可能是不可能的,因为(我认为)我需要能够从管道的父进程写入,在子进程结束时读取,从子进程写回输出,最后从父进程读取该输出.popen()我的系统上的手册页说明了双向管道,但是我的代码需要在一个只支持单向管道的旧版本的系统上运行.
通过上面的单独调用,我可以打开/关闭管道来实现这一目标.这有可能popen()吗?
对于一个简单的例子,要运行ls -l | grep .txt | grep cmds我需要:
ls -l在主机上运行进程; 读回它的输出ls -l传回我的模拟器grep .txt在管道输出上的主机上运行ls -lgrep cmds在管道输出上的主机上运行grep .txt男人popen
从Mac OS X:
该
popen()函数通过创建双向管道,分叉和调用shell来"打开"一个过程.由popen()父进程中先前调用打开的任何流都将在新的子进程中关闭.历史上,popen()使用单向管道实施; 因此,许多实现popen()只允许mode参数指定读或写,而不是两者.因为popen()现在使用双向管道实现,mode参数可以请求双向数据流.mode参数是一个指向以null结尾的字符串的指针,该字符串必须为'r'表示读取,'w'表示写入,或'r +'表示读写.
此手册页的dup2系统调用说:
EBUSY(仅适用于Linux)这可以通过DUP2开放(2)和DUP()的竞争条件时返回()或DUP3().
它谈什么竞争条件有关,我应该怎样做,如果dup2给出了EBUSY错误?我应该像我一样重试EINTR吗?
我有一项工作,我正在努力完成它.想法是编写一个执行一个程序的程序if.c,如果成功,则执行第二个程序.我应该抑制第一个程序的标准输出,并取消第二个程序的标准输出.我在多次测试中收到错误消息.例如:"./ if echo no then echo yes"返回"echo:write error:Bad file descriptor".我试过找到我在网上做错了但没有运气.
这是我的代码:
#include <fcntl.h>
#include <sys/wait.h>
#include <stdio.h>
#include "tlpi_hdr.h"
int main(int argc, char *argv[])
{
if(argc < 4){
fprintf(stderr,"Incorrect number of arguments.\n");
exit(EXIT_FAILURE);
}
int thenArg = 0;
char then[4];
strcpy(then,"then");
for(int x=1; x<argc; x++){
if(strncmp(argv[x], then, 4) == 0) thenArg = x;
}
if(thenArg == 0){
fprintf(stderr,"No 'then' argument found.\n");
exit(EXIT_FAILURE);
}
int save_out = dup(STDOUT_FILENO);
if(save_out == -1){
fprintf(stderr,"Error in dup(STDOUT_FILENO)\n");
exit(EXIT_FAILURE);
}
int devNull = open("/dev/null",0);
if(devNull …Run Code Online (Sandbox Code Playgroud) 这是我的代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <wait.h>
#include <readline/readline.h>
#define NUMPIPES 2
int main(int argc, char *argv[]) {
char *bBuffer, *sPtr, *aPtr = NULL, *pipeComms[NUMPIPES], *cmdArgs[10];
int fdPipe[2], pCount, aCount, i, status, lPids[NUMPIPES];
pid_t pid;
pipe(fdPipe);
while(1) {
bBuffer = readline("Shell> ");
if(!strcasecmp(bBuffer, "exit")) {
return 0;
}
sPtr = bBuffer;
pCount = -1;
do {
aPtr = strsep(&sPtr, "|");
pipeComms[++pCount] = aPtr;
} while(aPtr);
for(i = 0; i < pCount; i++) {
aCount = -1;
do { …Run Code Online (Sandbox Code Playgroud) 从python模块我调用一个Hello World可执行文件,只是打印Hello World到stdout.我有兴趣将该输出重定向到python StringIO并遇到这个答案,这几乎让我一直到解决方案.
这个答案的关键部分是这段代码:
1. def redirect_stdout():
2. print "Redirecting stdout"
3. sys.stdout.flush() # <--- important when redirecting to files
4. newstdout = os.dup(1)
5. devnull = os.open('/dev/null', os.O_WRONLY)
6. os.dup2(devnull, 1)
7. os.close(devnull)
8. sys.stdout = os.fdopen(newstdout, 'w')
Run Code Online (Sandbox Code Playgroud)
此外,我想恢复重定向之前的stdout.
dup和dup2做什么?/dev/null?sys.stdout = os.fdopen(newstdout, 'w'))StringIO对象中?我很确定,一旦我得到了问题1的答案,问题2和3的答案就很容易了.无论如何我决定发布它们可能会将问题1的答案推到我想去的方向.
我正在学习操作系统课程,当你有叉子时,我很难用dup2重定向输入.我写了这个小程序,试图对它有所了解但是我没有成功地把一个大孩子的输出传给一个孩子.我试图模仿unix命令:ps -A | wc -l.我是Unix的新手,但我相信这应该算上我得到的正在运行的进程列表的行.所以我的输出应该是一个数字.
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <iostream>
using namespace std;
int main( int argc, char *argv[] ) {
char *searchArg = argv[ 1 ];
pid_t pid;
if ( ( pid = fork() ) > 0 ) {
wait( NULL );
cout << "Inside parent" << endl;
}
else if ( pid == 0 ) {
int fd1[ 2 ];
pipe( fd1 );
cout << "Inside child" << endl;
if ( pid = fork() > …Run Code Online (Sandbox Code Playgroud) 我尝试使用管道、叉子和 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) 我需要主程序从用户那里获取两个字符串和另一个程序的参数,调用 fork() ,然后在子进程中我需要将字符串写入管道并将它们发送到另一个程序,该程序返回一个 int ,我想要传递给父级,所以我尝试使用另一个管道,但每次它在插入字符串后立即停止。
所以主程序:(编辑)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/wait.h>
#define LINELEN (80)
char *mygets(char *buf, int len);
int mygeti();
int main(int argc, char *argv[])
{
char *cmpstr[] = {"lexcmp", "lencmp"};
int veclen = sizeof(cmpstr)/sizeof(char *);
char str1[LINELEN + 1];
char str2[LINELEN + 1];
int index;
int pid[2];
int pfd[4][2];
for(int i = 0; i < 4; i++)
{
if(pipe(pfd[i]) < 0)
{
perror("pipe");
return -2;
}
}
pid[0] = fork();
if(pid[0] …Run Code Online (Sandbox Code Playgroud)