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

當(dāng)前位置: 首頁 > news >正文

域名做好了怎么做網(wǎng)站內(nèi)容對(duì)網(wǎng)絡(luò)營(yíng)銷的認(rèn)識(shí)

域名做好了怎么做網(wǎng)站內(nèi)容,對(duì)網(wǎng)絡(luò)營(yíng)銷的認(rèn)識(shí),湖北政府網(wǎng)站集約化建設(shè),企業(yè)網(wǎng)站設(shè)計(jì)制作價(jià)格文章目錄 一、打印命令行提示符二、讀取鍵盤輸入的指令三、指令切割四、普通命令的執(zhí)行五、內(nèi)建指令執(zhí)行5.1 cd指令5.2 export指令5.3 echo指令 六、結(jié)語 一、打印命令行提示符 const char* getusername() // 獲取用戶名 {return getenv("USER"); }const char* geth…

在這里插入圖片描述

文章目錄

  • 一、打印命令行提示符
  • 二、讀取鍵盤輸入的指令
  • 三、指令切割
  • 四、普通命令的執(zhí)行
  • 五、內(nèi)建指令執(zhí)行
    • 5.1 cd指令
    • 5.2 export指令
    • 5.3 echo指令
  • 六、結(jié)語

一、打印命令行提示符

const char* getusername() // 獲取用戶名
{return getenv("USER");
}const char* gethostname() // 獲取主機(jī)名
{return getenv("HOSTNAME");
}const char* getpwd() // 獲取當(dāng)前所處的目錄
{char* pos = strrchr(getenv("PWD"), '/'); // 查找最后一個(gè) ‘/’ if(*(pos+1) != '\0') return pos+1; // 說明不是根目錄,返回最后一個(gè)文件夾return pos;
}void tooltip() // 打印命令行提示框
{printf(LEFT "%s@%s %s" RIGHT PROMPT" ", getusername(), gethostname(), getpwd());
}

在這里插入圖片描述
代碼分析:獲取基礎(chǔ)信息本質(zhì)上是通過調(diào)用 getenv 接口來獲取對(duì)應(yīng)環(huán)境變量的值。借助 strrchr 函數(shù)來查找當(dāng)前路徑中的最后一個(gè)文件分隔符 /,它有可能是文件分隔符也有可能是根目錄因此要單獨(dú)判斷。

二、讀取鍵盤輸入的指令

char command[1024]; // 存儲(chǔ)鍵盤輸入的指令int getcommand(char* command, int size) // 讀取指令
{memset(command, '\0', size);char* ret = fgets(command, size, stdin); // 這里 ret 一定不為空,因?yàn)橹辽贂?huì)輸入一個(gè)回車,fgets 可以讀取回車assert(ret != NULL);(void)ret;// “假裝使用一下ret,防止有些編譯器警告”// aaabc\n\0command[strlen(command)-1] = '\0'; // 去掉結(jié)尾的 \nreturn 1;
}int interact(char* command, int size) // 交互
{tooltip();while(getcommand(command, size) && (strlen(command) == 0)){tooltip();}
}int main()
{interact(command, sizeof(command)); // 交互printf("echo: %s\n", command);return 0;
}

在這里插入圖片描述
代碼分析:鍵盤輸入的指令本質(zhì)上就是一串字符串,這里不能用 scanf 來獲取字符串,因?yàn)?scanf 是不會(huì)讀取空格和回車的(遇到空格和回車就停止讀取),而我們一般的指令都是帶選項(xiàng)的,指令和選項(xiàng)之間一般會(huì)用空格隔開,用 scanf 會(huì)導(dǎo)致我們指令讀不全。這里使用 fgets 函數(shù)來讀取鍵盤輸入,其第一參數(shù)是存儲(chǔ)指令的空間的首地址;第二個(gè)參數(shù)是空間的大小;第三個(gè)參數(shù)是從哪個(gè)文件流中讀取,一個(gè) C/C++ 程序默認(rèn)會(huì)打開三個(gè)文件流 stdin、stdout、stderr,這里選擇從 stdin 中讀取,也就是從標(biāo)準(zhǔn)輸入中讀取。gets 函數(shù)會(huì)在結(jié)尾自動(dòng)幫我們添加 \0,并且當(dāng)讀取的字符個(gè)數(shù)大于存儲(chǔ)容量時(shí),該函數(shù)會(huì)自動(dòng)在結(jié)尾放 \0,因此我們可以不用考慮為 \0 預(yù)留空間或者認(rèn)為的在字符串結(jié)尾加 \0。其次該函數(shù)讀取成功返回 command 的首地址,否則返回 NULL,在當(dāng)前場(chǎng)景下,除非讀取錯(cuò)誤,否則至少都會(huì)讀入一個(gè) \n,一般我們輸入完指令就是敲回車,什么指令不輸也敲回車,因此正常情況下 ret 不可能為 NULL。這里還要考慮刪除掉讀取到的 \n,因?yàn)槲覀儾恍枰?#xff0c;我們只要完整的指令。

三、指令切割

#define SEPARATOR " " // 指令分隔符
char* argv[ARGC_LONG] = {NULL}; // 存儲(chǔ)指令和選項(xiàng)的起始地址void commandcut(char* command, char** argv, int argvsize) // 指令切割
{memset(argv, 0, argvsize); // 清空char cop_command[COMMAND_LONG] = {'\0'}; // 保證 command 串不被改變for(int i = 0; command[i] != '\0'; i++){cop_command[i] = command[i];}// 開始切割子串char* ret = strtok(cop_command, SEPARATOR);int i = 0;while(ret != NULL){argv[i++] = ret;ret = strtok(NULL, " ");}
}int main()
{while(1){// 1、交互獲取命令行參數(shù)interact(command, sizeof(command)); // 交互// 到這里說明指令已經(jīng)獲取到了,接下來將指令打散// 2、指令切割commandcut(command, argv, sizeof(argv));for(int i = 0; argv[i]; i++){printf("[%d]: %s\n", i, argv[i]);}printf("echo: %s\n", command);}return 0;
}

在這里插入圖片描述

代碼分析:這一步主要是借助 strtok 函數(shù)將獲取到的指令切割成一個(gè)一個(gè)的子串,將所有子串的起始地址存儲(chǔ)在 argv 里面。注意 strtok 函數(shù)會(huì)改變?cè)臻g的內(nèi)容,因此創(chuàng)建了一段臨時(shí)的空間 cop_command

四、普通命令的執(zhí)行

void normalcommandexecution(char** _argv, int* _lastcode) // 普通命令的執(zhí)行
{pid_t id = fork();if(id < 0){perror("fork");}else if(id == 0){// childint ret = execvp(_argv[0], _argv);if(ret == -1){perror("exeecp");exit(EXIT_CODE);}}else{// fatherint status;pid_t ret = waitpid(id, &status, 0); // 阻塞等待if(ret == id){*_lastcode = WEXITSTATUS(status);}}
}int main()
{while(1){// 1、交互獲取命令行參數(shù)interact(command, sizeof(command)); // 交互// 到這里說明指令已經(jīng)獲取到了,接下來將指令打散// 2、指令切割commandcut(command, argv, sizeof(argv));// 3、普通命令執(zhí)行normalcommandexecution(argv, &lastcode);}return 0;
}

在這里插入圖片描述
代碼分析:對(duì)于 ls 這種普通指令(非內(nèi)建指令),先通過 fork 創(chuàng)建子進(jìn)程,然后再調(diào)用 execvp 接口進(jìn)行程序替換,去執(zhí)行輸入的指令。

五、內(nèi)建指令執(zhí)行

5.1 cd指令

bool isnormalcommand(char **_argv) // 指令判斷
{if (strcmp(_argv[0], "cd") == 0)return false;return true;
}void changpwd(char** _argv) // 更改當(dāng)前工作目錄
{chdir(_argv[1]); // 更改當(dāng)前工作目錄// getpwd(pwd, sizeof(pwd));sprintf(getenv("PWD"), "%s", getcwd(pwd, sizeof(pwd))); // 修改環(huán)境變量
}void builtincommand(char **_argv) // 內(nèi)建命令執(zhí)行
{if (strcmp(_argv[0], "cd") == 0){changpwd(_argv);}
}int main()
{while (1){// 1、交互獲取命令行參數(shù)interact(command, sizeof(command)); // 交互// 到這里說明指令已經(jīng)獲取到了,接下來將指令打散// 2、指令切割commandcut(command, argv, sizeof(argv));// 3、指令判斷// 3、普通命令執(zhí)行if (isnormalcommand(argv)) // 普通指令normalcommandexecution(argv, &lastcode);else // 內(nèi)建指令builtincommand(argv);}return 0;
}

在這里插入圖片描述

代碼分析:要考慮內(nèi)建指令,那在指令切割之后要先對(duì)指令進(jìn)行判斷。內(nèi)建指令不需要?jiǎng)?chuàng)建子進(jìn)程去執(zhí)行,而是直接由當(dāng)前的 bash 進(jìn)程去執(zhí)行。比如說 cd 指令,執(zhí)行完 cd 指令后,我們要讓當(dāng)前的 bash 更改工作目錄,而不是讓其創(chuàng)建子進(jìn)程去執(zhí)行 cd 指令,那樣改變的就是子進(jìn)程的工作目錄??梢园l(fā)現(xiàn),一個(gè)指令執(zhí)行完后,如果會(huì)對(duì) bash 產(chǎn)生影響,那么它就必須是內(nèi)建指令。其次關(guān)于 cd 指令,它改變了當(dāng)前的工作目錄,這一點(diǎn)該如何理解呢?我 myshell 就是一個(gè)可執(zhí)行程序,我的源代碼和編譯得到的可執(zhí)行文件始終都放在 /home/wcy/linux-s/2023-10-28a/myshell 目錄下,你 cd 命令憑什么能改變我的工作目錄?其實(shí)并不然,這里改變工作目錄是:一個(gè)可執(zhí)行程序在變成進(jìn)程產(chǎn)生 PCB 對(duì)象后,PCB 里面維護(hù)了一個(gè)屬性就叫做當(dāng)前可執(zhí)行程序的工作目錄,cd 指令改變的其實(shí)就是這一屬性,并不是改變 myshell 程序的存儲(chǔ)位置,我們通過調(diào)用 chdir 系統(tǒng)調(diào)用來修改這一屬性。最后,因?yàn)槲覀兦懊媸峭ㄟ^環(huán)境變量來獲取當(dāng)前工作目錄,而環(huán)境變量在被當(dāng)前 myshell 進(jìn)程從父進(jìn)程繼承下來后是不會(huì)自動(dòng)發(fā)生改變的,因此在執(zhí)行完 cd 指令后,我們要對(duì) PWD 環(huán)境變量進(jìn)行修改,環(huán)境變量本質(zhì)上就是存儲(chǔ)在內(nèi)存中的一段字符串信息,因此我們可以采用 sprintf 函數(shù)對(duì)該字符串信息進(jìn)行修改。

在這里插入圖片描述

5.2 export指令

#define USER_ENV_SIZE 100  // 允許用戶添加的環(huán)境變量個(gè)數(shù)
#define USER_ENV_LONG 1024 // 用戶一個(gè)環(huán)境變量的最大長(zhǎng)度char userenv[USER_ENV_SIZE][USER_ENV_LONG]; // 保存用戶添加的環(huán)境變量
int userenvnum = 0;                         // 當(dāng)前用戶輸入的環(huán)境變量個(gè)數(shù)void exportcommand(char** _argv, char(*_userenv)[USER_ENV_LONG], int* _userenvnum)
{// 將用戶輸入的環(huán)境變量存儲(chǔ)起來strcpy(_userenv[*_userenvnum], _argv[1]);int ret = putenv(_userenv[(*_userenvnum)++]);if (ret == 0)perror("putenv");
}

在這里插入圖片描述
代碼分析:只要 bash 不退出,我們每次添加的環(huán)境變量都應(yīng)該被保存起來,我們輸入的環(huán)境變量是被當(dāng)做指令保存在 command 里面,當(dāng)下一次輸入指令,上一次輸入的內(nèi)容就會(huì)被清空。putenv 添加環(huán)境變量,并不是把對(duì)應(yīng)的字符串拷貝到系統(tǒng)的表當(dāng)中,而是把該字符串的地址保存在系統(tǒng)的表中,因此我們要確保保存環(huán)境變量字符串的那個(gè)地址里的環(huán)境變量不會(huì)被修改,所以我們需要為用戶輸入的環(huán)境變量,也就是那一串字符串單獨(dú)開辟一塊空間進(jìn)行存儲(chǔ),保證在內(nèi)次重新輸入指令的時(shí)候,不會(huì)影響到之前用戶添加的環(huán)境變量。因?yàn)榄h(huán)境變量本質(zhì)就是一個(gè)字符串,所以這里我們定義了一個(gè)字符二維數(shù)組來存儲(chǔ)用戶輸入的環(huán)境變量,先把用戶輸入的環(huán)境變量存入我們定義的這個(gè)數(shù)組,然后再調(diào)用 putenv 函數(shù)將數(shù)組中的內(nèi)容添加到當(dāng)前的環(huán)境變量。這樣就可以保證只要當(dāng)前 bash 不退出,用戶歷史上添加的環(huán)境變量都在。這里涉及到二維數(shù)組傳參的問題,再來回顧一下,數(shù)組名表示首元素地址,二維數(shù)組的首元素是一個(gè)一維數(shù)組,所以函數(shù)形參的類型是一個(gè)字符一維數(shù)組的地址,也就是 char(*)[USER_ENV_LONG]

5.3 echo指令

void echocommand(char **_argv, int _argc)
{if (_argv[1][0] == '$'){char *ptr = _argv[1] + 1;printf("%s\n", getenv(ptr));}else{int i = 1;while (i < _argc){char *ret = strtok(_argv[i], "\"");while (ret != NULL){printf("%s", ret);ret = strtok(NULL, "\"");}printf("%c", ' ');i++;}printf("\n");}
}

在這里插入圖片描述
代碼分析echo 指令需要考慮將輸入的 " 去掉,其次可能連續(xù)輸入多個(gè)字符串,還要考慮 echo$ 配合使用是去打印環(huán)境變量的值。

小結(jié):當(dāng)我們登陸的時(shí)候,系統(tǒng)就是要啟動(dòng)一個(gè) shell 進(jìn)程,我們 shell 本身的環(huán)境變量是在用戶登錄的時(shí)候,shell 會(huì)讀取用戶目錄下的 .bash_profile 文件,里面保存了導(dǎo)入環(huán)境變量的方式。

在這里插入圖片描述
在這里插入圖片描述

六、結(jié)語

今天的分享到這里就結(jié)束啦!如果覺得文章還不錯(cuò)的話,可以三連支持一下,春人的主頁還有很多有趣的文章,歡迎小伙伴們前去點(diǎn)評(píng),您的支持就是春人前進(jìn)的動(dòng)力!

在這里插入圖片描述

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

相關(guān)文章:

  • 浙江省建設(shè)職業(yè)注冊(cè)中心網(wǎng)站廣州營(yíng)銷seo
  • 陜西省人民政府網(wǎng)站官網(wǎng)企業(yè)網(wǎng)站模板免費(fèi)下載
  • 徐州網(wǎng)站app開發(fā)我贏網(wǎng)客服系統(tǒng)
  • 云南學(xué)校 手機(jī)網(wǎng)站建設(shè)網(wǎng)店代運(yùn)營(yíng)和推廣銷售
  • 做電影網(wǎng)站用什么程序推廣策略有哪些方法
  • 網(wǎng)站建設(shè)南京制作鏈接的app的軟件
  • 連云港做網(wǎng)站軟文發(fā)布門戶網(wǎng)站
  • 有ip怎么用自己的主機(jī)做網(wǎng)站青島谷歌優(yōu)化
  • 門戶網(wǎng)站開發(fā)jz1902020年百度搜索排名
  • 汕頭人什么叫seo網(wǎng)絡(luò)推廣
  • 網(wǎng)站后臺(tái)管理系統(tǒng)模塊怎樣進(jìn)行seo優(yōu)化
  • 整體網(wǎng)站構(gòu)架騰訊云1元域名
  • 網(wǎng)上做翻譯兼職網(wǎng)站好網(wǎng)店運(yùn)營(yíng)的工作內(nèi)容
  • 自己建一個(gè)網(wǎng)站需要多少錢地推拉新接單網(wǎng)
  • 網(wǎng)站文案技巧公司網(wǎng)頁設(shè)計(jì)
  • 經(jīng)營(yíng)性網(wǎng)站備案需要哪些東西愛站網(wǎng)關(guān)鍵詞密度查詢
  • 文化網(wǎng)站建設(shè)論文寧德市人民政府
  • vuejs 可做網(wǎng)站嗎win7優(yōu)化大師官網(wǎng)
  • wordpress 作者列表優(yōu)化網(wǎng)站教程
  • 網(wǎng)站設(shè)計(jì)任務(wù)網(wǎng)絡(luò)營(yíng)銷推廣方案模板
  • 惠州網(wǎng)站建設(shè)如何海外網(wǎng)站
  • 如何把做的網(wǎng)站變成鏈接網(wǎng)站標(biāo)題seo外包優(yōu)化
  • 重慶做網(wǎng)站_重慶網(wǎng)站建設(shè)_重慶網(wǎng)絡(luò)推廣_重慶網(wǎng)絡(luò)公司制作網(wǎng)頁app
  • 網(wǎng)站開發(fā)需求分析主要內(nèi)容一站式媒體發(fā)布平臺(tái)
  • 免費(fèi)個(gè)人網(wǎng)站下載信息流廣告素材網(wǎng)站
  • 做影視網(wǎng)站關(guān)停不受限制的搜索瀏覽器
  • xyz域名做網(wǎng)站好么電商網(wǎng)站建設(shè)定制
  • seo網(wǎng)站排名后退權(quán)威發(fā)布
  • 建設(shè)部四庫一平臺(tái)查詢網(wǎng)站電商平臺(tái)有哪些?
  • 地方政府網(wǎng)站建設(shè)中存在的問題怎么在百度上發(fā)布廣告