c++ - 通过管道将自定义 stdin 传输到 C++ 中的系统调用

标签 c++ file unix pipe stdin

我正在尝试使用自定义输入从 C++ 调用 shell 脚本。我能做的是:

void dostuff(string s) {
    system("echo " + s + " | myscript.sh");
    ...
}

当然,转义 s 是相当困难的。有没有办法可以使用 s 作为 myscript.sh 的标准输入?即,像这样:

void dostuff(string s) {
    FILE *out = stringToFile(s);
    system("myscript.sh", out);
}

最佳答案

重新分配标准输入并在系统调用后恢复它的简单测试:

#include <cstdlib>     // system
#include <cstdio>      // perror
#include <unistd.h>    // dup2
#include <sys/types.h> // rest for open/close
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

#include <iostream>

int redirect_input(const char* fname)
{
    int save_stdin = dup(0);

    int input = open(fname, O_RDONLY);

    if (!errno) dup2(input, 0);
    if (!errno) close(input);

    return save_stdin;
}

void restore_input(int saved_fd)
{
    close(0);
    if (!errno) dup2(saved_fd, 0);
    if (!errno) close(saved_fd);
}

int main()
{
    int save_stdin = redirect_input("test.cpp");

    if (errno)
    {
        perror("redirect_input");
    } else
    {
        system("./dummy.sh");
        restore_input(save_stdin);

        if (errno) perror("system/restore_input");
    }

    // proof that we can still copy original stdin to stdout now
    std::cout << std::cin.rdbuf() << std::flush;
}

效果很好。我用一个简单的 dummy.sh 脚本对其进行了测试,如下所示:

#!/bin/sh
/usr/bin/tail -n 3 | /usr/bin/rev

注意最后一行将标准输入转储到标准输出,因此您可以像这样测试它

./test <<< "hello world"

并期望以下输出:

won tuodts ot nidts lanigiro ypoc llits nac ew taht foorp //    
;hsulf::dts << )(fubdr.nic::dts << tuoc::dts    
}
hello world

关于c++ - 通过管道将自定义 stdin 传输到 C++ 中的系统调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12764550/

相关文章:

c++ - cmath header 混淆

r - 使 R 项目自动打开特定脚本

Java在我的文本文件中放入随机符号而不是整数

unix - 我如何查看哪些文件在 unix 中占用的空间最多?

c++ - 通过编写包装器将 RogueWave 替换为标准库

c++ - 创建 BMP 文件

python - 在 SVN 目录中搜索具有特定文件扩展名的文件并复制到另一个文件夹?

linux - 如何在各种单独的文件中分隔与特定模式匹配的文件名和内容

linux - 在 winSCP 中切换用户

c++ - 有没有办法将表示为字符串的数字转换为其二进制等价物?