首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

如何在不更改stdin上的缓冲的情况下执行fork-then-execve?

在不更改stdin上的缓冲的情况下执行fork-then-execve的方法是使用文件描述符重定向。具体步骤如下:

  1. 首先,使用pipe()函数创建一个管道,得到两个文件描述符,一个用于读取,一个用于写入。
  2. 然后,使用fork()函数创建一个子进程。
  3. 在子进程中,关闭写入端的文件描述符,并将读取端的文件描述符复制到stdin(文件描述符0)。
  4. 在子进程中,使用execve()函数执行需要的命令。
  5. 在父进程中,关闭读取端的文件描述符,并将需要执行的命令写入写入端的文件描述符。

下面是一个示例代码:

代码语言:txt
复制
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main() {
    int pipefd[2];
    pid_t pid;

    // 创建管道
    if (pipe(pipefd) == -1) {
        perror("pipe");
        return 1;
    }

    // 创建子进程
    pid = fork();
    if (pid == -1) {
        perror("fork");
        return 1;
    }

    if (pid == 0) {
        // 子进程中
        close(pipefd[1]);  // 关闭写入端的文件描述符
        dup2(pipefd[0], 0);  // 将读取端的文件描述符复制到stdin
        close(pipefd[0]);  // 关闭读取端的文件描述符

        // 执行命令
        char *args[] = {"/bin/sh", "-c", "command", NULL};
        execve(args[0], args, NULL);
        perror("execve");
        return 1;
    } else {
        // 父进程中
        close(pipefd[0]);  // 关闭读取端的文件描述符

        // 写入命令
        char *command = "command\n";
        write(pipefd[1], command, strlen(command));
        close(pipefd[1]);  // 关闭写入端的文件描述符

        // 等待子进程结束
        wait(NULL);
    }

    return 0;
}

这样,就可以在不更改stdin上的缓冲的情况下执行fork-then-execve。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

C++:cstdio 头文件详解

这个库使用流来操作物理设备键盘,打印机,终端或者系统支持任何其他类型文件。 流是一种以统一方式与这些交互抽象; 所有流都具有相似的属性,与它们所关联物理介质各个特征无关。...在使用库时候会自动创建三个标准流:stdin, stdout and stderr; 流属性 Streams有一些属性可以定义可以在它们使用哪些函数以及它们如何通过它们处理数据输入或输出。...它值可以通过ftell和fgetpos函数获得,并且可以使用rewinding,fseek和fsetpos重新定位函数来更改。...将格式化数据写入流 fscanf 从流中读取格式化数据 printf 将格式化数据打印到stdout scanf 从stdin读取格式化数据 snprintf 将格式化输出写入一定大小缓冲区 sprintf...本站仅提供信息存储空间服务,拥有所有权,承担相关法律责任。发现本站有涉嫌侵权/违法违规内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

2.1K10
  • 使用python执行shell脚本 并动态传参 及subprocess使用详解

    在UNIX,与shell=False(默认):在这种情况下,POPEN 类使用os.execvp()来执行子程序。 args通常应该是一个序列。...一个字符串将被视为一个字符串作为唯一项目(要执行程序)序列。 在UNIX,使用shell = True:如果args是一个字符串,则它指定要通过shell执行命令字符串。...如果写shell=True,默认为shell=False,需要在args第一个参数指定执行器路径 ?...负bufsize意味着使用系统默认值,通常意味着完全缓冲。bufsize默认值是0(无缓冲)。 stdin,stdout和stderr分别指定执行程序标准输入,标准输出和标准错误文件句柄。...如果cwd不是None,那么在执行子代之前,当前目录将更改为cwd。 如果env不是None,它将为新进程定义环境变量。

    5.4K30

    Linux基础IO全面介绍

    目标文件不存在,需要 open 创建,则第三个参数表示创建文件默认权限, 否则,使用两个参数 open。...只要拿着文件描述符,就可以找到对应文件 补充: 标准输入、标准输出、标准错误在对应文件描述符为 0,1,2,对应 C 语言层stdin、stdout、stderr 所有文件,如果要被使用时,...inode 节点 总结: 基本,一个文件一个 inode(包括文件) inode 是一个文件所有的属性集合(包含文件名)(空文件也是占据空间,所有的属性也是数据也要占据空间) 真正表示文件不是文件名...将内核缓冲区数据缓冲到磁盘数据区中 3.记录分配情况——文件内容按顺序存放(数据块)。内核在 inode 磁盘分布区记录了上述块列表。 4.添加文件名到目录——内核将入口添加到目录文件。...之后内容,剩下就是库名字 生成可执行程序方式有两种:动态链接、静态链接 注: ldd 可以列出一个程序所需要得动态链接库;file 命令用于辨识文件类型 Linux 中,默认情况下形成执行程序是动态链接

    39240

    python中subprocess

    程序通常执行序列或字符串第一项,但可以通过使用明确参数进行设置。 在UNIX,shell = False(默认):在这种情况下,Popen类使用os.execvp()来执行程序子进程。...字符串将被视为只有一个字符串序列(程序执行)。 在UNIX,shell= True:如果参数是一个字符串,它指定了通过shell执行命令字符串。...一个负bufsize意味着使用这个系统默认情况下,这通常意味着完全缓冲。默认值为bufsize是0(无缓冲)。 stdin、stdout和stderr分别指定执行程序标准输入,标准输出和标准错误。...os.popen2, os.popen3 与 os.popen4 同样可以在没有shell介入情况下直接传递给程序 以序列形式执行命令行 这种方法可以用下面的方法替换: (child_stdin...=True) (child_stdout, child_stdin) = (p.stdout, p.stdin) 在 Unix系统中, popen2 也可以在没有shell介入情况下直接传递给程序以序列形式执行命令行

    1.6K30

    标准 IO 库那些事儿

    对于三个预定义标准 IO 流 (stdin/stdout/stderr) 缓冲类型,ISO C 有以下要求: 当且仅当 stdin/stdout 涉及交互式设备时,它们才是全缓冲 stderr...,流缓冲类型在确定后仍可以更改。.../stdout/stderr 缓冲初始状态、第一次执行 IO 后状态 为了验证 stdin 第一次执行 IO 操作后状态,加了一个 scanf 操作 对于 stdout 因 tell_buf...可以看出: stdin/stderr 初始时是没有分配缓冲执行第一次 IO 后,stdin/stdout 变为行缓冲类型,stderr 变为无缓冲,都分配了独立缓冲区空间 (地址不同)。...最后,虽然流缓冲区可以更改,但是建议这样做,从上面的例子可以看出,大多数类型变更会引发缓冲区重新分配,其中数据就会随之丢失,导致信息读取、写入不全问题。

    1.4K20

    python模块之subprocess类与常量

    如果是序列,则args中第一个元素是要执行程序;如果是字符串,解释执行与平台有关,在POSIX系统args将被解释为要执行程序名称或路径(前提是传递任何参数给程序)。...唯一需要指定shell=True场景是要执行指令是shell内置dir, copy。...0:始用缓冲 1:使用行缓冲 其他正整数:缓冲大小 负整数(默认):使用系统默认值 executable:使用shell=True场景很少。...stdin/stdout/stderr:分别指定程序执行标准输入,标准输出,标准错误。可选值包括PIPE,DEVNULL,已存在文件描述符(正整数),已存在文件对象,None。...Windows系统kill()是terminate()别名 属性 args:传入Popen构造器第一个参数,list或string类型 stdin:如果传递给Popenstdin参数是PIPE,

    2.4K10

    1(UNIX基础)

    有些信号表示硬件异常,例如除以0或者访问地址空间以外单元,这些异常产生后果不确定,所以推荐 2.按系统默认方式处理。...我们需要提供自编函数来处理它 10 系统调用与库函数 系统调用实际就是指最底层一个调用,在linux程序设计里面就是底层调用意思。面向是硬件。...实际,由于库函数对文件操作最终是通过系统调用实现,因此,每打开一个文件所获得FILE结构指针都有一个内核空间文件描述符fd与之对应。...使用库函数也有系统调用开销,为什么直接使用系统调用呢?...在用户空间和内核空间,对文件操作都使用了缓冲区,例如用fwrite写文件,都是先将内容写到用户空间缓冲区,当用户空间缓冲区满或者写操作结束时,才将用户缓冲内容写到内核缓冲区,同样道理,当内核缓冲区满或写结束时才将内核缓冲区内容写到文件对应硬件媒介

    84730

    5(标准IO)

    不幸是,标准I/O库最令人迷惑也是他缓冲。 标准I/O提供了三种类型缓冲: 1、全缓冲。这种情况下,在填满标准I/O缓冲区后才进行实际I/O操作。...对于驻留在磁盘上文件通常是由标准I/O库实施全缓冲。一个流上执行第一次I/O操作时,相关标准I/O函数通常调用malloc获得需使用缓冲区。 术语冲洗说明I/O缓冲写操作。...在终端驱动程序方面flush表示丢弃已存储在缓冲区中数据。 2、行缓冲。在这种情况下,当在输入和输出中遇到换行符时,标准I/O库执行I/O操作。...此函数一般用于将一个指定文件代开为一个预定义流:stdout,stdin,stderr。...此函数一直读到下一个换行符为止,但是超过n-1个字符,缓冲区以null字符结尾。gets推荐,因为没有指定缓冲区大小,可能导致溢出。

    68240

    python 标准类库-并行执行之subprocess-子进程管理

    如果传递是单一字符串,shell参数值必须为True,如果不提供其它任何参数,传递单一字符串情况下,该字符串必须是需要执行程序名。...类似在Unix使用os.execvp(),Windows使用CreateProcess()函数。 args 参数值为字符串、序列。默认,如果args是个序列,程序会执行args中第一项。...如果sell为True,则推荐传递字符串参数给args Unix操作系统,shell=True,shell默认为/bin/sh。如果args为字符串,则字符串指明了需要通过shell执行命令。...任意负数 - 使用缓冲缓冲大小等于系统自带o.DEFAULT_BUFFER_SIZE Executable executable参数指定了用于执行替代程序。很少用到。...stdin, stdout 和stderr 分别指定被执行程序标准输入,标准输出,标准错误文件句柄。

    4.1K20

    很“迷”字符与字符串

    具体,首先保持符号位不变,将0101010- 1,得0101001,然后得到结果按位取反得1010110,即十进制86,将符号位可知其对应数字就是 -86。...其次为了避免出现上述问题,必须要在读取输入前,清空缓冲残留数据,可以用以下方法解决: (1) 使用fflush(stdin)函数。...某些编译器(VC6)支持用 fflush(stdin) 来清空输入缓冲,但是并非所有编译器都要支持这个功能(linux 下gcc),因为标准中根本没有定义 fflush(stdin),所以这种方法移植性不是很好不建议使用...其次在程序中我们清除了输入缓冲区中残留,否则 getchar()会先读取缓冲区残留回车,然后在读入键盘输入部分;fflush(stdin)在 ubuntu 下不可用,所以注释掉了。...这里有两点需要注意,首先 gets() 在 ubuntu 下事会报错,所以在这里使用 fgets() 替代,其次由于 scanf不会清除最后回车符号,所以这里我们还是手动清除缓冲区残留,执行结果如下所示

    1.2K20

    标准IO库(ISO C标准IO库)

    缓冲 在这种情况下,在填满标准I/O缓冲区以后,才进行I/O操作。在第一次执行I/O操作时候,标准I/O会使用malloc来获取所需要缓冲区。...行缓冲缓冲就是当输入和输出中遇到换行符时,标准I/O执行实际I/O操作。当我们使用scanf和printf时候,实际就是行缓冲在起作用。...那么就会强制冲洗所有行缓冲输出流。 缓冲 标准I/O对字符不进行缓冲。通常标准出错是不带缓冲,这样就能使出错信息及时打印出来。...ISO C规则 当且仅当标准输入和标准输出指向交互式设备时候,它们才是全缓冲。 标准错误一定不会是全缓冲。 规则就是如此简单粗暴。它只说了什么时候全缓冲和不全缓冲。在Linux下。...通常是这样。 标准错误是不带缓冲。 标准输入和标准输出,如果指向设备是终端,那么使用行缓冲,否则使用全缓冲更改缓冲方式 我们可以使用下面的库函数来更改缓冲方式。 ?

    1.2K20

    python之系统命令

    用于执行复杂系统命令 参数: args:shell命令,可以是字符串或者序列类型(:list,元组) bufsize:指定缓冲。...0 无缓冲,1 行缓冲,其他 缓冲区大小,负值 系统缓冲 stdin, stdout, stderr:分别表示程序标准输入、输出、错误句柄 preexec_fn:只在Unix平台下有效,用于指定一个可执行对象...所以不能将close_fds设置为True同时重定向子进程标准输入、输出与错误(stdin, stdout, stderr)。...()函数,用于设置子进程一些属性,:主窗口外观,进程优先级等等 import subprocess ret1 = subprocess.Popen(["mkdir","t1"]) ret2 =...subprocess.Popen("mkdir t2", shell=True) 终端输入命令分为两种: 输入即可得到输出,:ifconfig 输入进行某环境,依赖再输入,:python import

    1.1K40

    pyinstaller打包成无控制台程序时运行出错(与popen冲突解决方法)

    有时候我们需要在程序里执行一些cmd命令,使用os或者其它模块中popen方法去执行 这个问题一般是程序内有输入导致,这个输入可以是input(),也可以是其它一些stdin操作(os.popen...实际上会造成输入请求) 本质就是:使用-w参数(无控制台)打包时程序里不要请求输入 或者,你也可以不用-w参数,手动隐藏控制台!...经过研究,结论: os.popen 会打开一个管道执行命令,而管道是有输入(stdin)、输出(stdout) !...os.popen 实际是一个简单封装,我们先来看他原型:subprocess.popen subprocess.Popen( args, bufsize=0, executable=None...bufsize 作用就跟python函数open()buffering参数一样:0表示缓冲,1表示行缓冲,其他正数表示近似的缓冲区字节数,负数表示使用系统默认值。默认是0。

    3.7K30

    Linux文件IO操作

    ,那些用户和组群可以访问文件以及可以执行什么操作 查看文件权限 查看文件权限 文件类型后面紧跟着就是文件权限 简单介绍下文件权限,如下图所示: 因为Linux是一个多用户登录操作系统,所以文件权限跟用户相关...可读 可写 可执行 字符表示 r w x 数字表示 4 2 1 所有者权限为rw-,对应着4+2+0,也就是最终权限6,以此类推,用户组权限为6,其他用户权限为4....更改umask值,可以通过命令umask mode方式来更改umask值,比如我要把umask值改为000,则使用命令 umask 000 即可。.../main readLen:4,data:text $ cat test.txt text 对比fwrite等标准C库函数,write是没有缓冲,不需要fflush或者close将缓冲数据写入到磁盘中...~咳咳,扯远了,实际stdout是块设备,stderr不是。对于块设备,只有当下面几种情况下才会被输入:遇到回车;缓冲区满;flush被调用。而stderr因为没有缓冲所以直接输出。

    2.7K30

    关于stdin流以及缓冲区浅谈

    就是以终端(计算机)为对象;即从键盘输入数据,运行结果到显示器屏幕(就叫标准输入输出);再来解释下流概念(流这个概念也解释不通,各种说法都有,反正我就暂理解为数据传输字节序列吧)实际,在内存中为每个数据流开辟一个内存缓冲区...: 1)全缓冲     在这种情况下,当填满标准I/O缓存后才进行实际I/O操作,全缓冲典型代表是对磁盘文件读写。...2)行缓冲     在这种情况下,当在输入和输出中遇到换行符时,执行真正I/O操作。这时,我们输入字符先存放在缓冲区,等按下回车键时才进行实际I/O操作。...(这和计算机分页机制有关,因为进程在计算机中分配内存使用就是分页与分段机制,并且每个页大小是4096个字节,因此通常情况下缓冲大小为4096个字节。)...还有rewind():这个是把文件指针恢复到文件开头地方,用在stdin就是清除了键盘缓冲区了,还有在当手动输入ctrl+z(就是EOF)时候会出现问题,rewind(stdin)也是用来清除EOF

    1.3K20

    python中执行DOS命令3种方法小

    使用os.system("cmd") 特点是执行时候程序会打出cmd在Linux执行信息。 import os os.system("ls")   2....使用Popen模块产生新process 现在大部分人都喜欢使用Popen。Popen方法不会打印出cmd在linux执行信息。的确,Popen非常强大,支持多种参数和模式。...参数executable用于指定可执行程序。一般情况下我们通过args参数来设置所要运行程序。如果将参数shell设为 True,executable将指定程序使用shell。...我们不能将close_fds设置为True同时重定向子进程标准输入、输出与错误(stdin, stdout, stderr)。 如果参数shell设为true,程序将通过shell来执行。...使用commands.getstatusoutput方法 这个方法也不会打印出cmd在linux执行信息。这个方法唯一优点是,它不是一个阻塞方法。即没有Popen函数阻塞问题。

    2.1K20

    Linux之模拟shell命令行解释器

    一、输出提示符 1.实际 2.模拟 printf("用户名@主机名 当前路径#"); fflush(std); 此处没有“\n”,会有缓冲问题,因此要用fflush(std);来刷新缓冲区 二、输入指令...为啥要用子进程去执行命令? 答:如果创建子进程,而是让bash直接去执行进程,会将我们bash直接替换为其他程序,shell就不能继续正常执行其他指令了(就回不到输入界面了)。...答:因为我们自己写shell,执行很多命令都要用fork创建子进程,让子进程去执行。当子进程执行cd命令时,更改时子进程工作目录而与父进程无关,因此父进程路径并不会发生修改。...因此,对于cd命令我们应该用内建命令:该命令不需要子进程执行,而是让bash自己执行。要修改程序工作目录需要用chdir系统调用。 什么是当前路径? 当前路径就是cwd。...cwd -> 当前进程所在工作目录(默认是文件存储在磁盘路径); exe -> 当前运行是磁盘路径下哪个进程。 更改当前进程工作目录:chdir。

    24120

    getchar使用

    ,以后getchar()再执行时就会直接从缓冲区中读 取了。...实际是 输入设备->内存缓冲区->程序getchar 你按键是放进缓冲区了,然后供程序getchar 你有没有试过按住很多键然后等一会儿会滴滴滴滴响,就是缓冲区满了,你后头按键没有存进缓冲区...4、缓冲类型   缓冲区 分为三种类型:全缓冲、行缓冲和不带缓冲。   1、全缓冲   在这种情况下,当填满标准I/O缓存后才进行实际I/O操作。全缓冲典型代表是对磁盘文件读写。   ...2、行缓冲   在这种情况下,当在输入和输出中遇到换行符时,执行真正I/O操作。这时,我们输入字符先存放在缓冲区,等按下回车键换行时才进行实际I/O操作。典型代表是键盘输入数据。   ...5、缓冲刷新 缓冲区会在以下三种情况下被刷新: 1、缓冲区满 2、执行flush刷新缓冲语句 3、程序正常结束。

    73450
    领券