中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

視頻網(wǎng)站做cpa搜索關鍵詞的工具

視頻網(wǎng)站做cpa,搜索關鍵詞的工具,門戶網(wǎng)站建設招標公告,萬戶網(wǎng)絡做網(wǎng)站很垃圾送給大家一句話: 不管前方的路有多苦,只要走的方向正確,不管多么崎嶇不平,都比站在原地更接近幸福。 —— 宮崎駿《千與千尋》 自主shell命令編寫 1 前言2 項目實現(xiàn)2.1 創(chuàng)建命令行2.2 獲取命令2.3 分割命令2.4 運行命令 3 源代碼…

在這里插入圖片描述
送給大家一句話:

不管前方的路有多苦,只要走的方向正確,不管多么崎嶇不平,都比站在原地更接近幸福。 —— 宮崎駿《千與千尋》

自主shell命令編寫

  • 1 前言
  • 2 項目實現(xiàn)
    • 2.1 創(chuàng)建命令行
    • 2.2 獲取命令
    • 2.3 分割命令
    • 2.4 運行命令
  • 3 源代碼
  • Thanks?(・ω・)ノ謝謝閱讀!!!
  • 下一篇文章見!!!

1 前言

前幾篇文章,我們學習進程的相關知識:進程概念,進程替換,進程控制。熟悉了進程到底是個什么事情,接下來我們來做一個實踐,來運用我們所學的相關知識。這個項目就是手搓一個shell模塊,模擬實現(xiàn)Xshell中的命令行輸入。

用下圖的時間軸來表示事件的發(fā)生次序。其中時間從左向右。shell由標識為sh的方塊代表,它隨著時間的流逝從左向右移動。shell從用戶讀入字符串"ls"。shell建立一個新的進程,然后在那個進程中運行l(wèi)s程序并等待那個進程結(jié)束:
在這里插入圖片描述
然后shell讀取新的一行輸入,建立一個新的進程,在這個進程中運行程序 并等待這個進程結(jié)束。
所以要寫一個shell,需要循環(huán)以下過程:

  1. 獲取命令行
  2. 解析命令行
  3. 建立一個子進程(fork),防止打擾主程序的運行
  4. 替換子進程(execvp),來執(zhí)行對應功能。
  5. 父進程等待子進程退出(wait)

根據(jù)這些思路,和我們前面的學的技術,就可以自己來實現(xiàn)一個shell了

2 項目實現(xiàn)

為了保證項目文件的優(yōu)雅美觀,我們按照功能來書寫不同函數(shù):

  1. 創(chuàng)建自己的命令行
  2. 獲取命令
  3. 分割命令
  4. 創(chuàng)建進程執(zhí)行命令

2.1 創(chuàng)建命令行

該模塊我們需要實現(xiàn)類似:
在這里插入圖片描述
獲取這些信息大家應該都知道吧!通過對環(huán)境變量我們就可以獲取到這些信息。使用getenv()函數(shù)就可以完成操作。

#include<stdio.h>2 #include<sys/types.h>3 #include<sys/wait.h>4 #include<stdlib.h>5 #include<unistd.h>6 #include<string.h>7 //大小宏8 #define SIZE 2569 //獲取用戶名10 const char* GetUsername() 11 {12   const char* name = getenv("USER");13   if(name == NULL) return "NONE";14   return name; 15 }16 //獲取機器信息17 const char* GetHostName()18 {19   const char* hostname = getenv("HOSTNAME");20   return hostname; 21 }22 //獲取當前目錄23 const char* GetCwd()24 {25   const char* cwd = getenv("PWD");26   if(cwd == NULL) return "NONE";27   return cwd;28 }29 30 void MakeCommandLineAndPrint()31 { //設置命令行字符串32   char line[SIZE];33   const char* username = GetUsername();34   const char* hostname = GetHostName();35   const char* cwd = GetCwd();//將獲取的三個數(shù)據(jù)寫入命令行中 36   sprintf(line,"[%s@%s %s]> ",username,hostname,cwd);                                                                                                                         37   printf("%s",line);38   fflush(stdout);//為了將命令行刷新出來39 }40 41 int main()42 {43   //創(chuàng)建我們自己的命令行44   MakeCommandLineAndPrint();45   int a = 0; scanf("%d",&a); //阻斷一下方便查看46   return 0;47 }

這里使用的sprintf()函數(shù)是向流中寫入格式化信息的好工具。這一段函數(shù)大家都可以看明白,就是獲取三個變量,然后通過Line數(shù)組進行中轉(zhuǎn),然后打印出來。來看效果:
在這里插入圖片描述
這時候發(fā)現(xiàn),我們的所在目錄全部都別打印出來了,我們可以進行一下優(yōu)化:

#define SkipPath(p) do{ p += strlen(p)-1 ;while(*p != '/') p--; p++; }while(0);     

通過這個宏定義就可以只保留最后的目錄。
這里之所以不使用函數(shù),是因為使用函數(shù)會涉及二級指針,會比較復雜!!!
來看效果:
在這里插入圖片描述
這樣就非常完美了!!!

2.2 獲取命令

這個模塊可以說是非常關鍵的一步了,只有正確獲取了對應命令,我們才好打開新進程來執(zhí)行命令。

	  #define ZERO '\0'45 int GetUserCommand(char* command,int n)46 {47   if(command == NULL) return -1;48   fgets(command,n,stdin);49   command[strlen(command) - 1] = ZERO; 50   return strlen(command);51 }

這樣我們就可以獲取命令行輸入的字符串了。

2.3 分割命令

獲取命令之后,我們還需要對輸入的一串命令來進行分割,來保證我們可以正常執(zhí)行命令

   12 #define SEP " "...14 //全局命令 方便操作15 char* gArgv[NUM];...58 void SplitCommand(char command[] , size_t n)59 {60   (void)n;61   gArgv[0] = strtok(command,SEP);62   int index = 1;63   // done, 故意寫成=,表示先賦值,在判斷. 分割之后,strtok會返回NULL,剛好讓gArgv最后一個元素是NULL, 并且while判斷結(jié)束64   while((gArgv[index++] = strtok(NULL,SEP)));65 }    

我們使用來strtok()函數(shù):

char *strtok(char *str, const char *delim)
  • str—要被分解的字符串
  • delim—用作分隔符的字符(可以是一個,也可以是集合)在這里我們使用宏定義SEP( 代表 “ ” )
  1. 第一次調(diào)用strtok(),傳入的參數(shù)str是要被分割的字符串{aaa - bbb -ccc},而成功后返回的是第一個子字符串{aaa};

  2. 第二次調(diào)用strtok的時候,傳入的參數(shù)應該為NULL,這樣使該函數(shù)默認使用上一次未分割完的字符串繼續(xù)分割 ,就從上一次分割的位置作為本次分割的起始位置,直到分割結(jié)束。(strtok內(nèi)部會記錄相應信息)

這樣就成功分割命令,來看效果:
在這里插入圖片描述
我們的準備工作做完了,接下來就可以進行最終的操作:創(chuàng)建新進程來執(zhí)行命令!

2.4 運行命令

運行命令就要使用:

  • 創(chuàng)建子進程
  • 進程替換

這兩個加在一起就有了非常牛批的力量,究極POWER!。

   68 //執(zhí)行命令69 void ExecuteCommand()70 {//創(chuàng)建子進程71   pid_t id = fork();                                                                                                                                                        72   if(id == 0)                                                                                                                 73   { //進程替換                                                                                                                          74     execvp(gArgv[0],gArgv);                                                                                               75     exit(errno);                                                                                                              76   }                                                                                                                           77   else                                                                                                                        78   {                                                                                                                           79     int status = 0;                                                                                                           80     pid_t rid = waitpid(id,&status,0);//進程等待                                                                                        81     if(rid > 0)                                                                                                               82     { //如果錯誤打印錯誤信息                                                                                                                        83       int lastcode = WEXITSTATUS(status);                                                                                     84       if(lastcode != 0) printf("%s:%s:%d\n",gArgv[0],strerror(lastcode),lastcode);                                            85     }                                                                                                                              86   }                                                                                                                                87 }   

前面已經(jīng)做好大部分工作了,執(zhí)行命令這一步就很簡單了。來看效果:
在這里插入圖片描述
這樣就完成了絕大部分的代碼編寫。我們在加上一個while循環(huán),讓命令行一直運行試試:
在這里插入圖片描述

這樣就實現(xiàn)了shell的大部分功能,但是還是有一些功能沒有做到:比如我們運行cd等內(nèi)建命令時,會無法運行,所以我要加上特殊情況來保證內(nèi)建命令可以執(zhí)行!!!

90 char* GetHome()91 {92   char* home = getenv("HOME");93   return home;94 }95 96 char cwd[SIZE];97 98 void cd()99 {
100   const char* path = gArgv[1];
101   if(path == NULL) path = GetHome();
102   chdir(path);
103 
104   char temp[SIZE];
105   getcwd(temp,sizeof(temp));                                                                                                                                                  
106   snprintf(cwd,sizeof(cwd),"PWD=%s",temp);
107   putenv(cwd);
108 }
109 
110 //檢查是否為內(nèi)建命令 并單獨執(zhí)行
111 bool CheckBuildin()
112 {
113   bool yes = false;
114   //if語句判斷即可,內(nèi)建命令是有限的
115   if(strcmp(gArgv[0],"cd") == 0)
116   {
117     cd();
118     yes = true;
119   }
120   return yes;
121 }
123 int main()
124 {
125   int quit = 0;                                                                                                                                                               
126 
127   while(!quit)
128   {
129 
130     //創(chuàng)建我們自己的命令行
131     MakeCommandLineAndPrint();
132     
133     //獲取命令行信息
134     char usercommand[SIZE];
135     int n = GetUserCommand(usercommand,sizeof(usercommand));
136     if(n <= 0) return 1;
137     
138     //分割命令行信息
139     SplitCommand(usercommand, sizeof(usercommand));
140     
141     bool judge = CheckBuildin();
142     if(judge) continue;
143 
144     //執(zhí)行命令
145     ExecuteCommand();
146   }
147 
148 
149   return 0;
150 }

這樣把內(nèi)建命令單獨進行運行就可以了,我這里只寫了一個cd命令。來看效果:
在這里插入圖片描述
這樣就完成了我們的自主shell編寫!!!

3 源代碼

#include<stdio.h>2 #include<sys/types.h>3 #include<sys/wait.h>4 #include<stdlib.h>5 #include<unistd.h>6 #include<string.h>7 #include<errno.h>8 #include<stdbool.h> 9 10 #define SIZE 25611 #define SkipPath(p) do{ p += strlen(p)-1 ;while(*p != '/') p--; }while(0); 12 #define ZERO '\0'13 #define NUM 3214 #define SEP " "15 16 //命令17 char* gArgv[NUM];18 int lastcode = 0;19 char cwd[SIZE];20 21 const char* GetUsername()22 {23   const char* name = getenv("USER");24   if(name == NULL) return "NONE";25   return name; 26 }27 28 const char* GetHostName()29 {30   const char* hostname = getenv("HOSTNAME");31   return hostname; 32 }33 34 const char* GetCwd()35 {36   const char* cwd = getenv("PWD");37   if(cwd == NULL) return "NONE";38   return cwd;39 }40                                                                                                                                                                               41 void MakeCommandLineAndPrint()42 {43   char line[SIZE];44   const char* username = GetUsername();  45   const char* hostname = GetHostName();46   const char* cwd = GetCwd();47   SkipPath(cwd);48   sprintf(line,"[%s@%s %s]> ",username,hostname,strlen(cwd) == 1?"/":cwd + 1);49   printf("%s",line);50   fflush(stdout);51 }                                                                                                                                                                             52 53 int GetUserCommand(char command[] ,size_t n)54 {55   char* s = fgets(command,n,stdin);56   if(s == NULL) return -1;57   command[strlen(command) - 1] = ZERO; 58   return strlen(command);59 }60 61 void SplitCommand(char command[] , size_t n)62 {63   (void)n;64   gArgv[0] = strtok(command,SEP);65   int index = 1;66   // done, 故意寫成=,表示先賦值,在判斷. 分割之后,strtok會返回NULL,剛好讓gArgv最后一個元素是NULL, 并且while判斷結(jié)束67   while((gArgv[index++] = strtok(NULL,SEP)));68 } 69 70 //執(zhí)行命令71 void ExecuteCommand()72 {73   pid_t id = fork();74   if(id == 0)75   {76     execvp(gArgv[0],gArgv);77     exit(errno);78   }79   else80   {81     int status = 0;82     pid_t rid = waitpid(id,&status,0);83     if(rid > 0)84     {85       lastcode = WEXITSTATUS(status);86       if(lastcode != 0) printf("%s:%s:%d\n",gArgv[0],strerror(lastcode),lastcode);87     }88   } 89 }90 91 char* GetHome()92 {93   char* home = getenv("HOME");94   return home;95 }96                                                                                                                                                                               97 98 void cd()99 {
100   const char* path = gArgv[1];
101   if(path == NULL) path = GetHome();
102   chdir(path);
103 
104   char temp[SIZE];
105   getcwd(temp,sizeof(temp));
106   snprintf(cwd,sizeof(cwd),"PWD=%s",temp);
107   putenv(cwd);
108 }
109 
110 //檢查是否為內(nèi)建命令 并單獨執(zhí)行
111 bool CheckBuildin()
112 {
113   bool yes = false;
114   //if語句判斷即可,內(nèi)建命令是有限的
115   if(strcmp(gArgv[0],"cd") == 0)
116   {
117     cd();
118     yes = true;
119   }
120   return yes;
121 }
122 
123 int main()
124 {
125   int quit = 0;
126 
127   while(!quit)
128   {
129 
130     //創(chuàng)建我們自己的命令行
131     MakeCommandLineAndPrint();
132     
133     //獲取命令行信息
134     char usercommand[SIZE];
135     int n = GetUserCommand(usercommand,sizeof(usercommand));
136     if(n <= 0) return 1;
137     
138     //分割命令行信息
139     SplitCommand(usercommand, sizeof(usercommand));
140     
141     bool judge = CheckBuildin();
142     if(judge) continue;
143 
144     //執(zhí)行命令
145     ExecuteCommand();
146   }
147 
148 
149   return 0;
150 }

Thanks?(・ω・)ノ謝謝閱讀!!!

下一篇文章見!!!

http://www.risenshineclean.com/news/11094.html

相關文章:

  • php網(wǎng)站用到的知識山東最新消息今天
  • 如何在工商局網(wǎng)站上做網(wǎng)登湖南專業(yè)關鍵詞優(yōu)化服務水平
  • 網(wǎng)站如何制作學校的做手機如何建網(wǎng)站
  • 杭州公司展廳設計公司網(wǎng)站seo優(yōu)化分析
  • 網(wǎng)站充值接口免費推廣軟件
  • 網(wǎng)站建設需要域名服務器網(wǎng)絡營銷手段有哪些方式
  • 網(wǎng)站手機app開發(fā)seo引擎搜索入口
  • 如何做盆栽蔬菜網(wǎng)站網(wǎng)站首頁快速收錄
  • 哪些網(wǎng)站適合花錢做推廣朝陽區(qū)seo技術
  • 巫山那家做網(wǎng)站厲害長沙哪里有網(wǎng)站推廣優(yōu)化
  • 互助盤網(wǎng)站開發(fā)杭州龍席網(wǎng)絡seo
  • wordpress 合法評論網(wǎng)站seo整站優(yōu)化
  • 網(wǎng)站建設平臺網(wǎng)站設計seo刷關鍵詞排名優(yōu)化
  • 慈溪高端網(wǎng)站設計百度貼吧怎么做推廣
  • 產(chǎn)品網(wǎng)站系統(tǒng)溫州最好的seo
  • 怎樣做網(wǎng)站的二維碼海豹直播nba
  • 完整的網(wǎng)站后臺權(quán)限編碼百度手機app
  • 怎么建手機網(wǎng)站鎮(zhèn)江關鍵字優(yōu)化公司
  • 用什么給網(wǎng)站做測試競價惡意點擊犯法嗎
  • 搬瓦工512m內(nèi)存wordpress北京自動seo
  • 沙田鎮(zhèn)做網(wǎng)站湖北seo診斷
  • 工信部 網(wǎng)站要獨立ip2023b站推廣大全
  • 速成網(wǎng)站-百度怎么推廣自己的視頻
  • 給公司申請網(wǎng)站用自己的賬號淮安百度推廣公司
  • .jsp網(wǎng)站開發(fā)技術疫情排行榜最新消息
  • 網(wǎng)站欄目變了怎么做跳轉(zhuǎn)競價托管推廣公司
  • 網(wǎng)站推廣及seo方案網(wǎng)站怎么進入
  • 網(wǎng)站建設課程設計sem托管公司
  • 做網(wǎng)站的畢業(yè)論文怎么寫網(wǎng)絡廣告營銷典型案例
  • 攝影師的網(wǎng)站有哪些深圳百度seo代理