首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

Linux C語言實作 ls 命令完整教學

     編輯:更多程式設計知識

前言

在 Linux 系統程式設計中,ls 是最基礎也最常用的指令之一。本文將帶領你從零開始,使用 C 語言實作一個支援 -l、-a、-i、-R、-t、-r 等常見參數的 ls 指令模擬程式。透過這個專案,你將深入理解目錄讀取、檔案屬性獲取、位元旗標處理、遞迴遍歷以及終端機輸出格式化等核心系統程式設計技巧。

核心資料結構與旗標設計

程式使用位元遮罩來管理各參數狀態,定義於標頭檔區塊:

#define LL (1<<0)  /* -l 參數:長格式顯示 */
#define IL (1<<1)  /* -i 參數:顯示 inode 號 */
#define RU (1<<2)  /* -R 參數:遞迴列出子目錄 */
#define TL (1<<16) /* -t 參數:依修改時間排序 */
#define AL (1<<17) /* -a 參數:顯示隱藏檔 */
#define RL (1<<18) /* -r 參數:反向排序 */
#define LENGTH 500
#define MAX_FILE_COUNT 500

mode 變數的低 16 位控制輸出格式,高 16 位控制排序與篩選行為,擴充性極佳。

主流程解析

  1. 參數解析:逐一檢查 argv,遇到 - 開頭者逐字元對應旗標,否則視為目標路徑。
  2. 路徑處理:支援相對與絕對路徑,若未指定則預設為當前工作目錄。
  3. 檔案列表建立:file_list() 使用 opendir/readdir 讀取目錄,配合 stat 取得檔案詳細資訊,並依旗標決定是否略過隱藏檔、按字母/時間排序、反向排序。
  4. 多型顯示分派:display() 依 mode 低 3 位(共 8 種組合)呼叫對應的顯示函式,若含 -R 則進入遞迴顯示流程。

關鍵函式實作細節

目錄讀取與排序 (file_list)

  • 使用 chdir 切換工作目錄,簡化後續 stat 呼叫。
  • 插入式排序:讀取時即按字母序插入陣列,時間複雜度 O(n²),但檔案數通常較小(<500),可接受。
  • 時間排序(-t):採選擇排序依 st_mtime 遞減排列。
  • 反向排序(-r):直接對陣列首尾交換。

格式化輸出家族

函式對應參數說明
display_simply無多欄對齊顯示檔名,自動偵測終端機寬度 (ioctl TIOCGWINSZ)
display_LL-l完整長格式:權限、連結數、擁有者/群組、大小、修改時間、檔名
display_IL-iinode 號 + 檔名,多欄對齊
display_LL_IL-li長格式前加 inode 號
display_RU*-R 系列遞迴列印:先印當前目錄名,再遞迴處理子目錄,略過 . 與 ..

權限字串產生

採位元測試逐字元輸出,雖程式碼重複,但邏輯清晰,易於維護:

if (S_ISDIR(mode)) printf("d"); else printf("-");
if (mode & (1<<8)) printf("r"); else printf("-");
/* ... 依序處理 user/group/other rwx */

錯誤處理策略

統一使用 error() 函式:記錄行號、輸出 perror 訊息、以 EXIT_FAILURE 結束程式,確保任何系統呼叫失敗皆能即時回報。

編譯與測試

gcc -o myls myls.c
./myls -laiR /tmp

即可看到與系統 ls 高度相容的輸出結果。

擴充建議

  • 新增 -h(人類可讀大小)、-S(依大小排序)等參數,只需擴充旗標與排序邏輯。
  • 將排序演算法改為 qsort,提升大量檔案時效能。
  • 支援多路徑參數(目前僅支援單一路徑)。

總結

此專案展示了 Linux 系統程式設計的經典範式:目錄操作、檔案屬性、位元旗標、遞迴遍歷、終端機互動。完整程式碼約 300 行,結構清晰,是學習系統程式設計的優良教材。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved