在撰寫跨平台或系統層級的 C 程式時,常需要取得程式執行時的當前工作目錄(Current Working Directory, CWD)。Linux 終端機提供 `pwd` 指令,但在 C 程式內部該如何取得?本文介紹兩種常見做法:系統呼叫 `execlp()` 執行外部指令,以及 POSIX 標準 API `getcwd()` 直接取得路徑。
int execlp(const char *file, const char *arg, ... /*, (char *)0 */);
file:要執行的指令名稱(會搜尋 PATH 環境變數)。arg:傳遞給指令的參數列表,以 NULL 結尾。#include#include #include int main(int argc, char *argv[]) { if (argc > 1 && strcmp(argv[1], "pwd") == 0) { // 執行 pwd 指令並輸出到 stdout execlp("pwd", "pwd", (char *)NULL); perror("execlp failed"); return 1; } // 其他邏輯... return 0; }
缺點:建立子行程開銷大、依賴外部指令存在、難以捕獲輸出供程式進一步處理。
char *getcwd(char *buf, size_t size);
buf:緩衝區指標,用於儲存路徑字串。size:緩衝區大小(位元組)。#include#include #include #include // PATH_MAX int main() { char cwd[PATH_MAX]; if (getcwd(cwd, sizeof(cwd)) != NULL) { printf("Current directory is: %s\n", cwd); } else { perror("getcwd failed"); return 1; } return 0; }
優點:無建立行程開銷、直接取得字串供後續處理、符合 POSIX 標準、跨平台可移植(Windows 使用 `_getcwd`)。
以下完整程式示範:無參數時用 `getcwd` 印出路徑;有參數時嘗試用 `execlp` 執行該指令。
#include#include #include #include #include int main(int argc, char *argv[]) { if (argc == 1) { // 模式 1:直接取得 CWD char cwd[PATH_MAX]; if (getcwd(cwd, sizeof(cwd))) printf("Current directory is: %s\n", cwd); else perror("getcwd"); } else { // 模式 2:執行使用者指定指令 execvp(argv[1], &argv[1]); // 自動搜尋 PATH perror("execvp failed"); // 若執行失敗會跑到這裡 return 1; } return 0; }
$ ./cwd_demo Current directory is: /home/user/project $ ./cwd_demo pwd /home/user/project $ ./cwd_demo ls -l total 24 -rwxr-xr-x 1 user user 16384 Jan 1 10:00 cwd_demo -rw-r--r-- 1 user user 512 Jan 1 09:55 cwd_demo.c $ ./cwd_demo nonexistent_cmd execvp failed: No such file or directory
在 C 語言中取得當前工作目錄,**強烈建議使用 `getcwd()`**。它效能高、可攜性好、且能直接取得字串供程式邏輯使用。`execlp()` 適合需要實際執行外部指令並將輸出直接導向終端機的場合,而非單純取得路徑字串。