C 程式設計/stdlib.h/system
在 C 標準庫中,system 是一個用於執行子程序和命令的函式。它在 stdlib.h 標頭檔案中定義。它與 exec/spawn 函式系列的不同之處在於,它不是將引數傳遞給執行的物件,而是將單個字串傳遞給系統 shell,通常是 POSIX shell,/bin/sh -c。
int system (const char *command);
system 函式是阻塞的;也就是說,呼叫將等待直到子程序終止並返回其退出值。在此期間,SIGCHLD 將被阻塞,因為 system 等待子程序死亡;此外,SIGINT 和 SIGQUIT 被忽略,因此為了確保響應性,程式設計師應該檢查返回值以檢視使用者是否試圖終止程序。發生錯誤時,system 在 fork 之前或期間(例如,程序計數限制已達到)失敗時將返回 -1,但在 fork 之後(例如,無法執行 sh)失敗時將返回 127;這與命令以狀態 127 退出無法區分。
在 POSIX 中,system 使用兩個引數: “-c” 和 command 分叉並執行 /bin/sh。雖然 sh 的行為在其他地方有規定,但需要注意的是 command 不必是單個命令;它實際上可以是一個管道,甚至是一系列管道。例如,考慮一個希望顯示螢幕截圖的程式
system ("pngtopnm \"My Screenshot.png\" | pnmtoxwd > out.xwd && xwud out.xwd");
這行展示了一個重要的考慮因素:由於 command 將被解析為 shell 命令列,因此圍繞例如檔名引號必須轉義。然而,這會引發安全問題,因為如果 command 是從使用者提供的 資料構建的,攻擊者可能能夠跳出任何引號並在父級上下文中執行任意命令;事實上,這幾乎是規範的程式碼注入漏洞。因此,建議僅對預先確定的命令字串使用 system,使用其他函式(spawn 等)在 argv 中傳遞使用者提供的資料,或透過管道或臨時檔案傳遞此類資料。
由 system 生成的子程序繼承其父程序的標準流;因此,子程序可以接收鍵盤輸入並寫入終端。請注意,這意味著父程序不會接收子程序的輸出,除非使用重定向或 tee。
- : 執行一個 shell 命令 – Linux 庫函式 手冊
- C++ 參考資料
std::system