代码之家  ›  专栏  ›  技术社区  ›  Serge

如何在启动另一个使用它的进程之前完全关闭文件写入?

  •  3
  • Serge  · 技术社区  · 7 年前

    我的程序创建一个linux shell文件,然后调用'popen'来执行它。令我惊讶的是,我不时收到以下信息: /bin/bash: bad interpreter: Text file busy

    以下是我所做工作的基本代码:

    FILE *f = fopen(shFile, "w");
    fprintf(f, ...);
    ...
    fclose(f);
    
    FILE *job = popen(shFile, "r");
    ...
    

    看起来像 sync() 有效(尽管很难说)。然而,它大大减慢了一切。

    1 回复  |  直到 7 年前
        1
  •  0
  •   Nominal Animal    7 年前

    shebang ,内核必须像对二进制文件一样对脚本文件采取类似的“锁定”。(这是一个内核内部“锁”,您只能 观察 从用户空间。如果文件被任何人打开以供写入,则锁定失败 ETXTBUSY .)

    在OP的情况下,它意味着执行 bash %s %s 替换为 shFile . 这也意味着 shFile文件 不需要是可执行的;只是可读的。

    如果我们假设 shFile文件 不包含任何 ' 字符,那么在Linux中使用它就足够了

    char *jobcmd = NULL;
    FILE *job;
    
    if (asprintf(&jobcmd, "bash '%s'", shFile) == -1) {
        /* Typically an out of memory error. */
        fprintf(stderr, "%s.\n", strerror(errno));
        exit(EXIT_FAILURE);
    }
    
    errno = ENOMEM;
    job = popen(jobcmd, "r");
    if (!job) {
        fprintf(stderr, "Cannot execute %s: %s.\n", shFile, strerror(errno));
        exit(EXIT_FAILURE);
    }
    
    free(jobcmd);
    jobcmd = NULL;
    

    '"'"'


    如果脚本只执行一次,则 popen() / getline() fread() fgetc() / pclose() bash -s ),同时还将脚本的输出检索到单个数组、每行(可能使用回调函数?)或逐字符。这种方法的好处是脚本从不存储在任何文件系统上。


    一般来说,安装脚本作为二进制文件的一部分,并通过命令行参数(例如, bash /usr/share/yourapp/somescript.bash 'arg1' 'arg2' ).

    /usr/lib/yourapp/ /usr/share/yourapp/ .