嵌入式學習筆記總結Day23----minshell項目總結

今天進行了linux系統高級編程io階段學習的結尾,完成了一個minshell的小項目。

一、項目介紹

利用Linux中IO接口實現MiniShell,實現常用的shell指令的實現。
項目想要實現需要思考的地方有:
1.如何打印終端命令
2.如何接受終端命令
3.實現對應的命令
要求:采用多文件編程,并實現按時間將輸入的指令記錄到日志文件中。

二、項目實現

初步思考整個項目的大致流程圖如下:
在這里插入圖片描述
接下來介紹項目實現中的一些關鍵部分:

2.1 打印終端提示符

在這里插入圖片描述

要實現如上圖的終端命令提示符,我們可以發現該提示符主要分為兩部分:
1.前面的linux@ubuntu是固定不變的,直接printf輸出即可,后面的路徑則是一直改變的,這時我們可以通過getcwd函數來實現獲取當前的絕對路徑:
int Terminal(void)
{char buf[1024] = {0};char *p = NULL;getcwd(buf,sizeof(buf));p = buf;while(*p != '\0')   //主要打印當前的一級路徑即可,則可以通過指針分割出我們想要的路徑{p++;}while(*p != '/'){p--;}p++;printf("\033[1;31m");   //這里主要采用vt100打印出想要的字符顏色printf("linux@Ubuntu:");printf("\033[0m");printf("\033[1;35m");printf("%s",p);printf("\033[0m");printf("$ ");return 0;
}

實現效果如下:
在這里插入圖片描述

2.2用戶指令的獲取

這里采用fgets獲取用戶鍵盤輸入的指令

int Gets(char *tmbuff,int maxlen)
{fgets(tmbuff,maxlen,stdin);tmbuff[strlen(tmbuff)-1] = '\0';  //將fgets獲取到的字符串末尾的換行符刪掉return 0;
}

2.3用戶指令的分割

我們在輸入shell指令時有些指令并不是一個單獨的指令,另外還包括了參數以及操作對象等,用上面的方法獲取的字符串往往是一整串,每個指令之間還包括了空格,這時我們就需要去分割出來每個部分。
有兩種實現方法:

第一種直接采用strtok函數對字符串進行分割。
以下是strtok函數的功能介紹:

char *strtok(char *str, const char *delim);
將字符串分解為一個由零個或多個非空記號組成的序列。在第一次調用strtok()
時,要解析的字符串應該在str中指定。在每個應該解析相同字符串的后續調用中,
str必須為NULL。
以下是實現代碼:
#include <string.h>
#include <stdio.h>int main(void)
{char cmdbuf[1024] = {0};char *pret = NULL;char *parg[10] = {NULL};int cnt = 0;//ln -s file.txt a.txtgets(cmdbuf);parg[cnt] = strtok(cmdbuf, " ");//以空格進行分割cnt++;while (1){parg[cnt] = strtok(NULL, " "); //后續分割第一個參數傳入NULLif (NULL == parg[cnt]){break;}cnt++;}int i = 0;for (i = 0; i < cnt; i++){printf("parg[%d] = %s\n", i, parg[i]);}return 0;
}

第二種是編寫函數,采用一個可移動指針去移動到空格出,并置‘\0’,從而實現對字符串的分割:

int SplitCommand(char *pcmdbuf, char **parg, int maxlen)
{char *ptmp = NULL;int cnt = 0;ptmp = pcmdbuf;while (1){parg[cnt] = ptmp;cnt++;while (*ptmp != '\0' && *ptmp != ' '){ptmp++;}if ('\0' == *ptmp){break;}*ptmp = '\0';ptmp++;while (*ptmp == ' '){ptmp++;}}return cnt;
}

2.4 日志文件的創建

這里直接用標準io的相關接口函數進行即可

#include "record.h"
#include <stdio.h>
#include <time.h>FILE *fp = NULL;/*********************************************************函數名:InitRecord*參  數:*		缺省 void *返回值:*		成功返回0 *		失敗返回-1 *******************************************************/
int InitRecord(void)
{fp = fopen(RECORD_PATH, "a");if (NULL == fp){return -1;}return 0;
}/*********************************************************函數名:RecordCommand*參  數:*		pcmdbuf 命令字符串首地址		*返回值:*		成功返回0 *		失敗返回-1 *******************************************************/
int RecordCommand(char *pcmdbuf)
{time_t t;struct tm *ptm = NULL;time(&t);ptm = localtime(&t);fprintf(fp, "[%04d-%02d-%02d %02d:%02d:%02d]%s\n", ptm->tm_year + 1900, ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, pcmdbuf);fflush(fp);return 0;
}/*********************************************************函數名:DeInitRecord*參  數:*		缺省 void *返回值:*		成功返回0 *		失敗返回-1 *******************************************************/
int DeInitRecord(void)
{if (fp != NULL){fclose(fp);fp = NULL;}return 0;
}

項目主函數代碼展示:

#include <stdio.h>
#include <string.h>
#include "terminal.h"
#include "record.h"int main(void)
{char command[1024] = {0};char *parg[10] = {NULL};int curcmdlen = 0;InitRecord();while (1){ShowTerminal();GetCommand(command, 1024);if (!strcmp(command, "exit")){DeInitRecord();break;}RecordCommand(command);curcmdlen = SplitCommand(command, parg, 10);ExecCommand(parg, curcmdlen);}return 0;
}

三、項目總結

通過本次項目進一步加深了對文件io以及標準io相關函數的了解,進一步加強了在遇到問題時,解決問題的能力,項目過程中令我影響最深刻的就是在獲取用戶輸入的指令時,一開始在另外一個文件中定義了一個數組用來存放獲取的指令,導致之后運行時,指令數據莫名消失,通過排查才發現,對于這種程序一直都會到處使用的數據應該注意其的存在時間,因為如果將指令存放在一個函數中,就會導致這樣一個局部變量在函數運行結束后這個數據就會消失,所以應該將其定義在主函數中或者定義為全局變量。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/697908.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/697908.shtml
英文地址,請注明出處:http://en.pswp.cn/news/697908.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Sora - 探索AI視頻模型的無限可能-官方報告解讀與思考

一、引言 最近SORA火爆刷屏&#xff0c;我也忍不住找來官方報告分析了一下&#xff0c;本文將深入探討OpenAI最新發布的Sora模型。Sora模型不僅僅是一個視頻生成器&#xff0c;它代表了一種全新的數據驅動物理引擎&#xff0c;能夠在虛擬世界中模擬現實世界的復雜現象。本文將重…

[力扣 Hot100]Day33 排序鏈表

題目描述 給你鏈表的頭結點 head &#xff0c;請將其按 升序 排列并返回 排序后的鏈表 。 出處 思路 歸并排序即可。 代碼 class Solution { public:ListNode* merge(ListNode *h1,ListNode *h2) {ListNode *head nullptr;if(h1->val<h2->val){head h1;h1h1-…

2024.2.22 C++QT 作業

思維導圖 練習題 1>完善對話框&#xff0c;點擊登錄對話框&#xff0c;如果賬號和密碼匹配&#xff0c;則彈出信息對話框&#xff0c;給出提示”登錄成功“&#xff0c;提供一個Ok按鈕&#xff0c;用戶點擊Ok后&#xff0c;關閉登錄界面&#xff0c;跳轉到其他界面。如果賬…

Stream、Collections、Collectors用法

當涉及Java編程中的集合處理時&#xff0c;Stream、Collections和Collectors是三個常用的工具。以下是它們各自的主要功能和使用的一些方法的概要&#xff1a; Stream&#xff1a; 概要&#xff1a;Stream 是 Java 8 引入的一個強大工具&#xff0c;用于處理集合數據的流式操作…

Vue響應式狀態ref()與reactive()

1. ref()聲明響應式狀態 <template><!--在DOM元素調用變量時,不需要指定輸出變量的value,因為Vue會幫你輸出.value但是注意,這個幫助只會幫助頂級的ref屬性才會被解包--><div>{{ count }}</div><div>{{ object }}</div><div>{{ arr…

git切換倉庫地址

已有git倉庫&#xff0c;要切換提交的倉庫地址&#xff0c;用以下命令 git remote set-url origin 自己的倉庫地址 用以下命令&#xff0c;查看當前倉庫地址&#xff1a; git remote show origin 切換倉庫后&#xff0c;用以下命令初始化提交倉庫&#xff1a; git push -u o…

數據庫增刪改查

DDL: 數據定義語言&#xff0c;用來定義數據庫對象&#xff08;數據庫、表、字段&#xff09;DML: 數據操作語言&#xff0c;用來對數據庫表中的數據進行增刪改DQL: 數據查詢語言&#xff0c;用來查詢數據庫中表的記錄DCL: 數據控制語言&#xff0c;用來創建數據庫用戶、控制數…

c++11:可調用對象

文章目錄 引言1.普通函數2.函數指針3.函數對象(仿函數)4.Lambda表達式(匿名函數)5.function6.bind 引言 可調用對象是C11引入的新概念&#xff0c;可以像函數調用方式的觸發調用的對象就是可調用對象。 c98可調用對象(普通函數&#xff0c;函數指針&#xff0c;仿函數) c11可調…

Java設計模式【代理模式】

一、前言 1.1 背景 在不改變原有代碼的基礎上&#xff0c;對方法進行功能性的增強&#xff1b; 1.2 簡介 代理模式是一種結構型模式&#xff0c;為其他對象提供一種代理以控制對這個對象的訪問。在某些情況下&#xff0c;一個對象不想或者不能直接引用另一個對象&#xff0…

axure9.0 工具使用思考

原型設計軟件【AxureRP】快速原型設計工具原型設計軟件【AxureRP】快速原型設計工具原型設計軟件【AxureRP】快速原型設計工具原型設計軟件【AxureRP】快速原型設計工具原型設計軟件【AxureRP】快速原型設計工具原型設計軟件【AxureRP】快速原型設計工具原型設計軟件【AxureRP】…

CentOS使用Docker搭建Halo網站并實現無公網ip遠程訪問

&#x1f525;博客主頁&#xff1a; 小羊失眠啦. &#x1f3a5;系列專欄&#xff1a;《C語言》 《數據結構》 《C》 《Linux》 《Cpolar》 ??感謝大家點贊&#x1f44d;收藏?評論?? 前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&…

【華為OD機試真題 C++語言】483、中文分詞模擬器 | 機試真題+思路參考+代碼解析(C卷)

文章目錄 一、題目??題目描述??輸入輸出??樣例1??樣例2??樣例3二、思路參考三、代碼參考作者:KJ.JK??個人博客首頁: KJ.JK ??專欄介紹: 華為OD機試真題匯總,定期更新華為OD各個時間階段的機試真題,每日定時更新,本專欄將使用C++語言進行更新解答,包含真…

創紀錄:英偉達市值一日增 2770 億美元;Xiaomi 14 Ultra 正式發布丨 RTE 開發者日報 Vol.150

開發者朋友們大家好&#xff1a; 這里是 「RTE 開發者日報」 &#xff0c;每天和大家一起看新聞、聊八卦。我們的社區編輯團隊會整理分享 RTE &#xff08;Real Time Engagement&#xff09; 領域內「有話題的 新聞 」、「有態度的 觀點 」、「有意思的 數據 」、「有思考的 文…

mysql 用戶權限管理

mysql使用系統庫mysql的user表來存儲用戶信息。mysql.user表詳細的記錄了用戶名&#xff0c;對應的允許連接的主機信息還有各種全局權限標識位。 用戶管理 創建用戶 CREATE USER 用戶名host主機 IDENTIFIED BY 密碼;上面是創建用的基本命令&#xff0c;指定了用戶名&#xf…

Selenium基礎知識

一、環境搭建&#xff08;以java為例&#xff09; 1.下載chrome瀏覽器 https://www.google.cn/intl/zh-CN/chrome/ 2.查看chrome瀏覽器版本 設置關于chrome 3.下載chrome瀏覽器驅動 下載瀏覽器對應版本的 ChromeDriver - WebDriver for Chrome - Downloads 120以上版本&…

WordPress使用

WordPress功能菜單 儀表盤 可以查看網站基本信息和內容。 文章 用來管理文章內容&#xff0c;分類以及標簽。編輯文章以及設置分類標簽&#xff0c;分類和標簽可以被添加到 外觀-菜單 中。 分類名稱自定義&#xff1b;別名為網頁url鏈接中的一部分&#xff0c;最好別設置為中文…

概率密度函數(PDF)與神經網絡中的激活函數

原創:項道德(daode3056,daode1212) 在量子力學中&#xff0c;許多現象都是統計的結果&#xff0c;基本上用的是正態分布&#xff0c;然而&#xff0c;從本質上思考&#xff0c;應該還存在低階的分布&#xff0c;標準的正態分布是它的極限&#xff0c;這樣一來&#xff0c;或許在…

python中多線程使用

前言 記錄下Python中多線程使用 標題 前言簡介使用demo 簡介 Python 中的多線程主要通過 threading 模塊來實現。多線程是一種并發編程的方式&#xff0c;允許程序在同一時間執行多個線程&#xff0c;每個線程執行不同的任務。然而需要注意的是&#xff0c;在 Python 中由于 …

【前端素材】推薦優質后臺管理系統Spica Admin平臺模板(附源碼)

一、需求分析 后臺管理系統是一種用于管理網站、應用程序或系統的工具&#xff0c;它通常作為一個獨立的后臺界面存在&#xff0c;供管理員或特定用戶使用。下面詳細分析后臺管理系統的定義和功能&#xff1a; 1. 定義 后臺管理系統是一個用于管理和控制網站、應用程序或系統…

【安全】大模型安全綜述

大模型相關非安全綜述 LLM演化和分類法 A survey on evaluation of large language models,” arXiv preprint arXiv:2307.03109, 2023.“A survey of large language models,” arXiv preprint arXiv:2303.18223, 2023.“A survey on llm-gernerated text detection: Necess…