[英]Applications of system() function in launching and waiting for a new process
我目前正在學習系統編程,並在流程管理一章中遇到了int system(const char* command)
的用法。 他們說,如果一個進程正在產生一個孩子,只是為了立即等待它的終止,最好使用system(const char* command).
一句“命令參數后綴為arguments /bin/sh -c ”是什么意思
fork()、exec()、waitpid() 系統調用如何與此相關聯?
請參閱這些調用的手冊頁:
來自man 2 fork
: https://man7.org/linux/man-pages/man2/fork.2.html
fork() 通過復制調用進程來創建一個新進程。 新進程稱為子進程。 調用進程稱為父進程。
從man 3 exec
: https://man7.org/linux/man-pages/man3/exec.3.html
exec() 系列函數用新的進程映像替換當前進程映像。
來自man 3 system
: https://man7.org/linux/man-pages/man3/system.3.html
system() 庫 function 使用 fork(2) 創建執行 shell 命令的子進程,該命令在使用 execl(3) 的命令中指定,如下所示:
execl("/bin/sh", "sh", "-c", command, (char *) NULL);
system() 在命令完成后返回。
所以system()
是在 shell 上運行命令的快速方法,它本身將使用fork()
和exec()
來執行給定的命令。
only applies to programming effort.其中僅適用於編程工作。 直接使用fork()
和exec()
在運行時要快得多。
“命令參數后綴為arguments /bin/sh -c”這句話是什么意思
That means that the entire string used with system() will be passed to and executed by /bin/sh
which really can be anything but in majority of cases it's some variant of POSIX-compliant shell such as Dash on Ubuntu, Bash on Slackware,嵌入式 Linux 發行版上的 busybox ash 或 FreeBSD 上的 tcsh。 由於命令由 shell 執行,因此您可以在 $PATH、shell 內置命令和 shell 構造中使用命令,例如|
, &&
, 循環, 重定向, 命令替換等等。 例如,您可以這樣做:
system("echo Date now: $(date) > /tmp/NOW");
就像您在終端模擬器中所做的一樣。 請注意,system() 會啟動非交互式 shell,因此您不能使用僅在交互式 shell 中工作的別名和其他功能,例如 Bash 歷史擴展。 另請注意,您必須正確引用,因為傳遞給 system() 的字符串將首先由 C 編譯器解析,然后由 shell 解析。
fork()、exec()、waitpid() 系統調用如何與此相關聯?
system() 可以被認為是對 fork()、exec() 和 waitpid() 的易於使用的包裝器。 可以編寫一個簡單的 main.c 程序:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
system("echo Date now: $(date) > /tmp/NOW");
return EXIT_SUCCESS;
}
編譯它:
gcc main.c -o main -Wall -Wextra -pedantic
並在 strace 下運行:
strace -f ./main
你會看到 ./main firsts 使用 clone() 系統調用 fork 新進程(你不會在這里找到fork() ):
clone(child_stack=0x7f7ed4a58ff0, flags=CLONE_VM|CLONE_VFORK|SIGCHLDstrace: Process 31782 attached
然后使用指定的 arguments 執行 /bin/sh:
[pid 31782] execve("/bin/sh", ["sh", "-c", "echo Date now: $(date) > /tmp/NO"...], 0x7ffd91f10418 /* 61 vars */ <unfinished ...>
然后等待它:
[pid 31781] wait4(31782, <unfinished ...>
如果您對 C 感到流利,您可以閱讀 libc 源代碼以查看諸如 system() 之類的包裝器是如何實現的,但是您最有可能在 Linux 發行版上使用的 Glibc 可能很難閱讀和理解,因此通常最好閱讀 musl libc source https://git.musl-libc.org/cgit/musl/tree/src/process/system.c (of course implementation between Glibc and other C libraries can differ but reading musl source code should give a generic understanding about how給定的系統可以在 Glibc 中實現)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.