execve("/bin/sh",0,0);在管道中 [英] execve("/bin/sh", 0, 0); in a pipe

查看:373
本文介绍了execve("/bin/sh",0,0);在管道中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下示例程序:

#include <stdio.h>

int
main(int argc, char ** argv){
    char buf[100];

    printf("Please enter your name: ");
    fflush(stdout);
    gets(buf);
    printf("Hello \"%s\"\n", buf);

    execve("/bin/sh", 0, 0);
}

我并且在没有任何管道的情况下运行时,它应能正常工作并返回sh promt:

I and when I run without any pipe it works as it should and returns a sh promt:

bash$ ./a.out
Please enter your name: warning: this program uses gets() which is unsafe.
testName
Hello "testName"
$ exit
bash$

但是这在管道中不起作用,我想我知道为什么会这样,但是我无法找到解决方案.下面是运行示例.

But this does not work in a pipe, i think I know why that is, but I cannot figure out a solution. Example run bellow.

bash$ echo -e "testName\npwd" | ./a.out
Please enter your name: warning: this program uses gets() which is unsafe.
Hello "testName"
bash$

我认为这与以下事实有关:gets清空stdin的方式是/bin/sh收到EOF并迅速退出而没有错误消息.

I figure this has something to do with the fact that gets empties stdin in such a way that /bin/sh receives a EOF and promtly quits without an error message.

但是如何解决这个问题(如果可能的话,不修改程序,并且不删除gets),即使我通过管道提供输入,我也会得到提示?

But how do I get around this (without modifying the program, if possible, and not removing gets, if not) so that I get a promt even though I supply input through a pipe?

P.S.我正在FreeBSD(4.8)计算机D.S上运行此程序.

P.S. I am running this on a FreeBSD (4.8) machine D.S.

推荐答案

您可以运行程序,而无需进行如下修改:

You can run your program without any modifications like this:

(echo -e 'testName\n'; cat ) | ./a.out

这样,您可以确保程序的标准输入不会在echo输出之后结束.而是,cat继续为程序提供输入.后续输入的来源是您的终端,因为这是cat的读取位置.

This way you ensure that your program's standard input doesn't end after what echo outputs. Instead, cat continues to supply input to your program. The source of that subsequent input is your terminal since this is where cat reads from.

这是一个示例会话:

bash-3.2$ cc stdin_shell.c 
bash-3.2$ (echo -e 'testName\n'; cat ) | ./a.out 
Please enter your name: warning: this program uses gets(), which is unsafe.
Hello "testName"
pwd
/home/user/stackoverflow/stdin_shell_question
ls -l
total 32
-rwxr-xr-x  1 user  group  9024 Dec 14 18:53 a.out
-rw-r--r--  1 user  group   216 Dec 14 18:52 stdin_shell.c
ps -p $$
  PID TTY           TIME CMD
93759 ttys000    0:00.01 (sh)
exit

bash-3.2$

请注意,由于shell的标准输入未连接到终端,因此sh认为它不是交互式执行的,因此不会显示提示.不过,您可以正常键入命令.

Note that because shell's standard input is not connected to a terminal, sh thinks it is not executed interactively and hence does not display the prompt. You can type your commands normally, though.

这篇关于execve("/bin/sh",0,0);在管道中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆