在Linux中调用system()的问题

时间:2010-06-16 18:03:33

标签: c++ linux gentoo

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

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

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


编辑:所以我弄清楚导致我的错误的原因。我不知道为什么会导致错误,但我找到了它。

为了允许热插拔,我需要将/sbin/mdev写入/proc/sys/kernel/hotplug ...但是我最终切换了参数(在我自己写的一个函数上),所以我正在编写{ {1}}至/proc/sys/kernel/hotplug

我不清楚为什么会导致这个问题,但确实如此。

3 个答案:

答案 0 :(得分:6)

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

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

答案 1 :(得分:6)

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

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

相反,请使用标准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;
    }
}

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

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

答案 2 :(得分:1)

你在initramfs中有什么?您可以执行以下操作:

int main() {
   return system("echo hello world");

}

然后将其插入这样的脚本中:

strace -o myprog.log myprog

系统启动后查看日志