如何在内核编程中执行shell命令?

17

我想在我的C代码中使用stdlib.h库的system()函数。实际上,我正在进行内核编程。

每当我想要在其中使用system()时,它会提示stdlib.h文件不存在的错误。


6
从内核调用用户空间命令通常是一个非常不好的想法 :) - favoretti
4
在内核中使用system()是一个不好的主意。但这并不是打负评的好理由。你可以解释为什么要避免使用它,以及有哪些替代方案。这只是我的观点。 - masoud
我想在我的C代码中使用stdlib.h的system()函数。我实际上正在进行内核编程。这是一个非常糟糕的想法!!即使你惊讶地让它工作了,而且你的系统还没有崩溃...你是想回显任何调试消息吗?如果是这种情况,请使用printk()和dmesg! - Barath Ravikumar
通常仅仅抱怨事情不好,并没有说明原因是没有太大帮助的。内核向用户空间发送事件要灵活得多。例如,可以使用[netlink](http://en.wikipedia.org/wiki/Netlink)向用户空间任务发送一条消息,从而启动所需的用户空间任务。这样做会使如何处理事件等方面变得更加灵活,因为它将一些关于事件发生时发生什么的策略从内核转移到了用户空间。然后管理员可以决定该怎么做。虽然在嵌入式系统中并不那么重要,但也应该考虑到。 - artless noise
较新的内核在sysfs和/或procfs条目上提供了inotify。这也可以用作用户空间通知机制。您的用户空间任务可以运行您熟悉的system() - artless noise
4个回答

21

很简单!

#include <linux/kmod.h>

char * envp[] = { "HOME=/", NULL };
char * argv[] = { "/bin/ls", NULL };

call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC);

1
太棒了!我已经寻找这个好一段时间了! - AbiusX
5
以这种方式调用的命令是否可以获得输出? - AlexSee

6
你可能需要的是执行用户空间函数。该SE答案包含了一个链接,指向一个IBM文章,其中包括一个从内核调用的示例用户空间进程。你应该使用的搜索词是"usermodehelper"和"usermode helper"。
在内核中,请参阅:
yba@tavas:~/linux-2.6/linux-2.6$ find . -type f | xargs grep "usermode.helper"
./kernel/cgroup.c:      /* Drop the lock while we invoke the usermode helper,
./kernel/kmod.c:    /* CLONE_VFORK: wait until the usermode helper has execve'd
./kernel/kmod.c: * call_usermodehelper_setup - prepare to call a usermode helper
./drivers/block/drbd/drbd_int.h:extern char usermode_helper[];
./drivers/block/drbd/drbd_nl.c: char *argv[] = {usermode_helper, cmd, mb, NULL };
./drivers/block/drbd/drbd_nl.c: dev_info(DEV, "helper command: %s %s %s\n", usermode_helper, cmd, mb);
./drivers/block/drbd/drbd_nl.c: ret = call_usermodehelper(usermode_helper, argv, envp, UMH_WAIT_PROC);
./drivers/block/drbd/drbd_nl.c:             usermode_helper, cmd, mb,
./drivers/block/drbd/drbd_nl.c:             usermode_helper, cmd, mb,
./drivers/block/drbd/drbd_nl.c: char *argv[] = {usermode_helper, cmd, tconn->name, NULL };
./drivers/block/drbd/drbd_nl.c: conn_info(tconn, "helper command: %s %s %s\n", usermode_helper, cmd, tconn->name);
./drivers/block/drbd/drbd_nl.c: ret = call_usermodehelper(usermode_helper, argv, envp, UMH_WAIT_PROC);
./drivers/block/drbd/drbd_nl.c:           usermode_helper, cmd, tconn->name,
./drivers/block/drbd/drbd_nl.c:           usermode_helper, cmd, tconn->name,
./drivers/block/drbd/drbd_main.c:char usermode_helper[80] = "/sbin/drbdadm";
./drivers/block/drbd/drbd_main.c:module_param_string(usermode_helper, usermode_helper, sizeof(usermode_helper), 0644);
./drivers/block/drbd/drbd_main.c:        * currently blocked waiting for that usermode helper to
./security/keys/request_key.c: * Initialise a usermode helper that is going to have a specific session
./security/keys/request_key.c: * Clean up a usermode helper with session keyring.
./security/keys/request_key.c: * Call a usermode helper with a specific session keyring.

0

没有简单的方法,因为system()是一个用户级C库函数,涉及许多系统调用,包括:

 sys_fork()
 sys_execve()

您可以使用以下方式来实现system()效果(我猜测):

 create a kernel thread.

 let the kernel thread execute sys_execve( your command name)

不确定这是否可行,但你可以尝试一下。


-5

在内核中不能使用system()。就这样。在内核空间没有应用级别的代码可以执行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接