You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C程序execve启动sh shell时管道传输入致shell无法启动问题

问题根因
  • 直接运行./myexec时,进程标准输入默认绑定当前控制终端,execve拉起的/bin/sh会继承该输入描述符,可正常从终端读取交互指令,因此能正常进入shell交互流程。
  • 执行python -c 'print "someinput"' | ./myexec这类管道命令时,myexec的标准输入绑定的是管道读端,而非终端。管道内仅包含Python输出的someinput字符串和末尾换行符,scanf("%s", buff)读完这段内容后,管道就已经到达EOF(输入结束状态)。
  • 后续execve拉起的sh会继承这个已处于EOF状态的标准输入,sh启动后尝试读取输入指令时直接读到EOF,会按默认逻辑立刻退出,既不会进入交互界面,也不会长期驻留。你用ps查询时进程已经执行完毕退出,自然查不到对应的sh进程。
  • 未查询到errno报错属于正常现象:execve系统调用本身执行成功,没有触发任何错误,问题出在sh继承的输入流状态上,和myexec本身的系统调用异常无关。
验证方式

执行以下命令即可验证sh实际是正常启动过,只是启动后立刻退出:

python -c 'print "echo verify_sh_start"' | ./myexec

执行后终端会输出verify_sh_start,说明sh成功启动、读取了管道内的echo命令并执行,执行完成后因无后续输入直接退出。

修复方案

如果需要通过管道传入scanf读取的内容后,仍然让sh正常进入终端交互,可以在调用execve前将标准输入重新绑定到当前控制终端,核心修改点如下:

printf("\n Enter the password : \n");
scanf("%s",buff);

// 将标准输入重新指向当前进程的控制终端
freopen("/dev/tty", "r", stdin);

execve("/bin/sh", args, NULL);

另外补充代码的一个疏漏:你调用了printf、scanf标准库函数,但代码中未包含<stdio.h>头文件,部分编译环境下会触发隐式声明警告,建议补充该头文件引用。

内容的提问来源于stack exchange,提问作者Ilie Tudor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 10:18:31