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

C語言在Linux下執行Shell命令完整指南:從原理到實戰

     編輯:關於C

前言

Linux作業系統因其開源、穩定等優勢,已成為通信軟體開發的主流平台。在C語言開發中,時常需要呼叫Shell命令來完成檔案操作、系統管理等任務。本文將通過一個完整的刪除檔案案例,詳細講解如何在C程式中安全、高效地執行Shell命令。

一、程式執行流程概覽

本範例在Linux環境下實現一個簡單的檔案刪除功能,程式透過Makefile編譯,執行流程如下圖所示:

程式執行流程圖

圖1 程式執行流程

執行結果可通過檢查目標目錄下檔案是否存在來驗證。

二、專案目錄結構

原始碼檔案為 TestShellCommand.c,編譯產物輸出至 release 目錄。同級目錄下有一個 TestFile 資料夾,存放待刪除的測試檔案。結構如下:

目錄結構1 目錄結構2

圖2 專案目錄結構

三、核心C程式碼深度解析

/**********************************************************************
* 版權所有 (C)2014, Zhou Zhaoxiong。
* 檔案名稱: TestShellCommand.c
* 內容摘要:測試在C語言中執行shell命令
* 當前版本: V1.0
* 作 者: Zhou Zhaoxiong
* 完成日期: 20140521
**********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>

// 重新定義資料型別,提高可移植性
typedef unsigned char UINT8;
typedef int INT32;
typedef unsigned int UINT32;

/**********************************************************************
* 功能描述:主函數
* 返回值: 0-執行成功 其它-執行失敗
***********************************************************************/
INT32 main()
{
    UINT8 szFileIndex[100] = {0};      // 儲存使用者輸入的檔案索引
    UINT8 szFileDirectory[100] = {0};  // 儲存檔案目錄路徑
    UINT8 szDeleteCommand[100] = {0};  // 儲存組裝好的刪除命令
    UINT8 *pIndexExt = NULL;           // 用於判斷副檔名是否存在
    UINT32 iRetVal = 0;                // system() 呼叫返回值

    printf("Input the index of source file: ");
    scanf("%s", szFileIndex);          // 讀取輸入,支援帶/不帶副檔名兩種模式

    // 設定檔案所在目錄
    strncpy(szFileDirectory, "TestFile", strlen("TestFile"));

    // 判斷輸入是否包含副檔名(含'.'字元)
    pIndexExt = strrchr(szFileIndex, '.');
    if (pIndexExt == NULL) {
        // 無副檔名:使用萬用字元刪除所有同名檔案
        snprintf(szDeleteCommand, sizeof(szDeleteCommand) - 1,
                 "rm -rf %s/%s.*", szFileDirectory, szFileIndex);
    } else {
        // 有副檔名:精確刪除指定檔案
        snprintf(szDeleteCommand, sizeof(szDeleteCommand) - 1,
                 "rm -rf %s/%s", szFileDirectory, szFileIndex);
    }

    printf("The delete command is: %s\n", szDeleteCommand);

    // 呼叫 system() 執行Shell命令
    iRetVal = system(szDeleteCommand);
    if (-1 == iRetVal) {
        // 錯誤處理:errno為0或10視為成功(視系統而定),其它記錄日誌
        if (errno != 0 && errno != 10) {
            printf("Exec %s failed!\n", szDeleteCommand);
            return -1;
        }
    }

    return 0;
}

關鍵技術點說明

  1. system() 函數:原型為 int system(const char *string),啟動一個Shell進程執行命令。返回值需結合 errno 判斷,本例中將 errno == 0 || errno == 10 視為成功。
  2. 命令組裝策略:使用 strrchr 檢測副檔名,動態生成 rm -rf 命令。無副檔名時加 .* 萬用字元,確保同名不同副檔名檔案一併刪除。
  3. 安全考量:執行前列印命令內容,便於除錯;刪除操作不可逆,生產環境務必加入二次確認機制。

四、Makefile 編寫

TestShellCommand : TestShellCommand.c
	gcc -c -g TestShellCommand.c
	gcc -g -o release/TestShellCommand TestShellCommand.o
	rm *.o

編譯產生的可執行檔 TestShellCommand 位於 release 目錄,與 TestFile 同級。

五、實際運行演示

在 TestFile 目錄下放置測試檔案 123456.r,執行 make 編譯後,進入 release 目錄運行程式:

zhou@linux:~/zhouzx/TestShellCommand/release> ./TestShellCommand
Input the index of source file: 123456
The delete command is: rm -rf TestFile/123456.*

zhou@linux:~/zhouzx/TestShellCommand/release> ./TestShellCommand
Input the index of source file: 123456.r
The delete command is: rm -rf TestFile/123456.r

無論輸入帶不帶副檔名,目標檔案均被成功刪除。建議實際專案中增加更多測試用例驗證健壯性。

六、總結與最佳實踐

  • 命令正確性:執行前務必列印完整命令字串,便於追蹤與除錯。
  • 防誤刪機制:關鍵刪除操作前應加入路徑檢查、權限驗證或使用者確認提示。
  • 錯誤處理:完整檢查 system() 返回值與 errno,記錄詳細日誌。
  • 跨平台注意:Windows 平台下 Shell 命令語法不同,若需跨平台建議封裝抽象層。

掌握在C語言中執行Shell命令,能大幅擴展程式處理系統級任務的能力,是Linux下C/C++開發者的必備技能。

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