【问题标题】:Quine create and execute fileQuine 创建并执行文件
【发布时间】:2025-02-11 15:55:02
【问题描述】:

我正在 C 中创建一个Quine,我需要在其中创建一个新的 c 文件,然后编译并执行它。

我做了一个简单的 sn-p 来了解它为什么不起作用。

我的猜测是execv 在 fprintf 完成写入之前启动命令,但我进入睡眠状态并且它也没有工作。

(我为这个最丑陋的代码道歉,但这不是目标)

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>

int main()
{
    char *cmd[100]= {"sh", "-c", "\"gcc tmp.c && ./a.out\""};

    fprintf(fopen("tmp.c", "w"), "#include <stdio.h>\nint main(){puts(\"Hello World\");}");
    execv("/bin/sh", cmd);
    return (0);
}

输出

sh: gcc tmp.c && ./a.out: No such file or directory

有什么想法吗?

【问题讨论】:

标签: c printf execv quine


【解决方案1】:

您的参数数组 cmd 没有以 NULL 指针终止。此外,它还有报价问题。

您还应该在调用execv() 之前关闭该文件。您在文件中看不到任何内容的原因是 fprintf() 缓冲。虽然所有打开的文件都在进程退出时关闭,但您在此之前正在执行。

int main(void)
{

   char *cmd[]= {"sh", "-c", "gcc tmp.c && ./a.out", (char*)0};

    FILE *fp = fopen("tmp.c", "w");
    if (!fp) {
       perror("fopen");
       exit(1);
    }

    fprintf(fp, "#include <stdio.h>\nint main(){puts(\"Hello World\");}");
    fclose(fp);
    execv("/bin/sh", cmd);
    perror("execv");
    return (0);
}

【讨论】:

    【解决方案2】:

    当你在普通 shell 中调用你的 shell 时:

    sh -c "gcc tmp.c && ./a.out"
    

    sh -c gcc tmp.c &amp;&amp; ./a.out 在我的 shell 中工作,但在你的 cmet 中不能工作)

    因此,这意味着您必须将不被引用的参数传递给execv,否则它们会被解释为单个参数,就像您这样做:

    sh -c \""gcc tmp.c && ./a.out\""
    

    建议修复:

    char *cmd[100]= {"sh", "-c", "gcc tmp.c && ./a.out", NULL};
    

    顺便说一句:不要忘记fclose 您的文件或tmp.c 可能为零。 BTW2:感谢 usr,NULL 丢失了:已编辑。

    完全固定的代码提案:

    #include <stdio.h>
    #include <unistd.h>
    #include <fcntl.h>
    int main()
    {
        char *cmd[100]= {"sh", "-c", "gcc tmp.c && ./a.out", NULL};
        FILE *outfile = fopen("tmp.c", "w");
        if (!outfile) {printf("cannot open output file\n");exit(1);}
    
        fprintf(outfile, "#include <stdio.h>\nint main(){puts(\"Hello World\");}");
        fclose(outfile);  // required else file remains open
        execv("/bin/sh", cmd);
        return (0);
    }
    

    【讨论】:

    • sh -c gcc tmp.c &amp;&amp; ./a.out 在我的 shell 中不工作
    • 我只是觉得我应该使用system()
    • 是的,system 也不错。但是引用的东西会起作用。查看并测试我的编辑。引用地狱!!!
    • 根据您的选择,文件未填充
    • @Jean-FrançoisFabre 数组cmd 也必须以空指针结尾。
    最近更新 更多