问题 是否可以在Linux中将数据写入自己的stdin


我想从IDE调试我的cgi脚本(C ++),所以我想创建一个“调试模式”:从磁盘读取文件,将其推送到自己的stdin,设置一些环境变量,对应这个文件并运行其余的Web服务器调用的脚本。它是否可能,如果是,那我该怎么办呢?


9448
2018-06-20 20:48


起源



答案:


你不能“推送自己的stdin”,但你可以将文件重定向到你自己的标准输入。

freopen("myfile.txt","r",stdin);

12
2018-06-20 20:50



好吧,假设stdio,那就是 fungetc。但这并不能保证超过一个字节的推回。 - ephemient
错误。您可以 :)
好。 fungetc 只需1个字节。它不能像操作中那样用于cgi输入。 - J-16 SDiZ
非常优雅的一段代码! - agurodriguez


答案:


你不能“推送自己的stdin”,但你可以将文件重定向到你自己的标准输入。

freopen("myfile.txt","r",stdin);

12
2018-06-20 20:50



好吧,假设stdio,那就是 fungetc。但这并不能保证超过一个字节的推回。 - ephemient
错误。您可以 :)
好。 fungetc 只需1个字节。它不能像操作中那样用于cgi输入。 - J-16 SDiZ
非常优雅的一段代码! - agurodriguez


大家都知道标准输入是一个定义为的文件描述符 STDIN_FILENO。虽然它的价值不能保证 0,我从未见过任何其他东西。无论如何,没有什么可以阻止你写入该文件描述符。为了举例,这里有一个小程序,它将10条消息写入自己的标准输入:

#include <unistd.h>
#include <string>
#include <sstream>
#include <iostream>
#include <thread>

int main()
{
    std::thread mess_with_stdin([] () {
            for (int i = 0; i < 10; ++i) {
                std::stringstream msg;
                msg << "Self-message #" << i
                    << ": Hello! How do you like that!?\n";
                auto s = msg.str();
                write(STDIN_FILENO, s.c_str(), s.size());
                usleep(1000);
            }
        });

    std::string str;
    while (getline(std::cin, str))
        std::cout << "String: " << str << std::endl;

    mess_with_stdin.join();
}

把它保存到 test.cpp,编译和运行:

$ g++ -std=c++0x -Wall -o test ./test.cpp -lpthread
$ ./test 
Self-message #0: Hello! How do you like that!?
Self-message #1: Hello! How do you like that!?
Self-message #2: Hello! How do you like that!?
Self-message #3: Hello! How do you like that!?
Self-message #4: Hello! How do you like that!?
Self-message #5: Hello! How do you like that!?
Self-message #6: Hello! How do you like that!?
Self-message #7: Hello! How do you like that!?
Self-message #8: Hello! How do you like that!?
Self-message #9: Hello! How do you like that!?
hello?
String: hello?
$ 

“你好?”部分是我在发送所有10条消息后输入的内容。然后你按 按Ctrl+d 表示输入和程序退出的结束。


2
2018-06-20 21:01



这看起来有点工作,因为你在一个终端,文件描述符0,1和2都绑定到pty。你没有写任何程序本身可以回读的东西。看到 stackoverflow.com/q/1441251 对这个主题的一些阐述。 - ephemient
真正。如果您与tty分离,您的输入fd也可以关闭。我想一个确切的解决方案取决于上下文。很可能做管道/ dup2等。如果你重新打开 stdin, 怎么样 std::cin 等等?让我想起一部电影,一个机器人经常说“需要更多的输入”> ;-))