在Linux中调用system()的问题

Tho*_*mas 1 c++ linux gentoo

我正在init为C++ for Linux中的initramfs 工作.此脚本用于解锁DM-Crypt w/LUKS加密驱动器,并将LVM驱动器设置为可用.

因为我不想重新实现的功能cryptsetupgpg我使用的系统调用来调用可执行文件.使用系统调用来调用gpg工作正常,如果我已经完全启动了系统(我已经有一个基于bash脚本的initramfs可以很好地启动它,我使用grub编辑命令行来使用它来启动它旧的initramfs).但是,在initramfs中,它甚至都不会被调用.甚至命令都system("echo BLAH"); 失败了.

那么,有没有人有任何意见?


编辑:所以我想出了导致我的错误的原因.我不知道为什么它会导致错误,但我找到了它.

为了让热插拔,我需要写/sbin/mdev/proc/sys/kernel/hotplug......不过,我结束了周围的参数开关(上的功能我写我自己不会少),所以我写/proc/sys/kernel/hotplug/sbin/mdev.

我不知道为什么会导致这个问题,但是确实如此.

Ama*_*9MF 6

我相信system()函数在shell中执行你的命令.在启动过程的早期,shell可执行文件是否已安装且可用?您可能希望研究使用fork()和execve().

编辑:确保您的加密工具也在已安装的卷上.


War*_*ung 6

Amardeep是对的,system()在POSIX类型系统上运行命令/bin/sh.

我怀疑你实际上有合法的需要通过Bourne shell调用你所说的这些程序.一个很好的理由是,如果你需要它们拥有默认的环境变量集,但由于/etc/profile在启动过程中可能也很早,因此我不知道这是怎么回事.

相反,使用标准fork()/exec()模式:

int system_alternative(const char* pgm, char *const argv[])
{
    pid_t pid = fork();
    if (pid > 0) {
        // We're the parent, so wait for child to finish
        int status;
        waitpid(pid, &status, 0);
        return status;
    }
    else if (pid == 0) {
        // We're the child, so run the specified program.  Our exit status will
        // be that of the child program unless the execv() syscall fails.
        return execv(pgm, argv);
    }
    else {
        // Something horrible happened, like system out of memory
        return -1;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您需要从被调用的进程读取stdout或将数据发送到它的stdin,您需要通过pipe()dup2()在那里进行一些标准的句柄重定向.

你可以在任何优秀的Unix编程书中学到所有这些东西.我推荐W. Richard Stevens 在UNIX环境中进行高级编程.由Rago合着的第二版增加了自Stevens编写第一版以来出现的平台的材料,如Linux和OS X,但这样的基础知识自原版以来没有改变.