国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

認(rèn)識(shí)環(huán)境變量和進(jìn)程替換,實(shí)現(xiàn)一個(gè)簡(jiǎn)易的shell

這篇具有很好參考價(jià)值的文章主要介紹了認(rèn)識(shí)環(huán)境變量和進(jìn)程替換,實(shí)現(xiàn)一個(gè)簡(jiǎn)易的shell。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。


一、環(huán)境變量

1.什么是環(huán)境變量

首先,在百度百科中,環(huán)境變量的解釋是這樣的:

環(huán)境變量(environment variables)一般是指在操作系統(tǒng)中用來(lái)指定操作系統(tǒng)運(yùn)行環(huán)境的一些參數(shù),如:臨時(shí)文件夾位置和系統(tǒng)文件夾位置等。環(huán)境變量是在操作系統(tǒng)中一個(gè)具有特定名字的對(duì)象,它包含了一個(gè)或者多個(gè)應(yīng)用程序所將使用到的信息。例如Windows和DOS操作系統(tǒng)中的path環(huán)境變量,當(dāng)要求系統(tǒng)運(yùn)行一個(gè)程序而沒有告訴它程序所在的完整路徑時(shí),系統(tǒng)除了在當(dāng)前目錄下面尋找此程序外,還應(yīng)到path中指定的路徑去找。用戶通過(guò)設(shè)置環(huán)境變量,來(lái)更好的運(yùn)行進(jìn)程。

指令本質(zhì)上就是編譯好的程序和腳本,被存儲(chǔ)在特定的路徑下(默認(rèn)/user/bin/)。

比如我們執(zhí)行 ls 指令,實(shí)際上就是執(zhí)行這個(gè)程序或者腳本,而我們要執(zhí)行一個(gè)程序就必須找到該程序,我們通常要運(yùn)行一個(gè)可執(zhí)行程序,是用 ./a.out 來(lái)執(zhí)行的,./表示在當(dāng)前目錄,a.out表示一個(gè)可執(zhí)行程序。所以我們要執(zhí)行 ls 指令,就要找到 ls 所在的路徑,而環(huán)境變量的作用就是讓系統(tǒng)從指定的路徑去找,而在PATH 中有/uer/bin 路徑,所以我們就能執(zhí)行所有的指令了。

認(rèn)識(shí)環(huán)境變量和進(jìn)程替換,實(shí)現(xiàn)一個(gè)簡(jiǎn)易的shell,c++,數(shù)據(jù)結(jié)構(gòu),linux,ubuntu,centos,vim

常用的10個(gè)環(huán)境變量如下:

環(huán)境變量名稱 作用
HOME 用戶的主目錄(也稱家目錄)
SHELL 用戶使用的 Shell 解釋器名稱
PATH 定義命令行解釋器搜索用戶執(zhí)行命令的路徑
EDITOR 用戶默認(rèn)的文本解釋器
RANDOM 生成一個(gè)隨機(jī)數(shù)字
LANG 系統(tǒng)語(yǔ)言、語(yǔ)系名稱
HISTSIZE 輸出的歷史命令記錄條數(shù)
HISTFILESIZE 保存的歷史命令記錄條數(shù)
PS1 Bash解釋器的提示符
MAIL 郵件保存路徑

Linux 作為一個(gè)多用戶多任務(wù)的操作系統(tǒng),能夠?yàn)槊總€(gè)用戶提供獨(dú)立的、合適的工作運(yùn)行環(huán)境,因此,一個(gè)相同的環(huán)境變量會(huì)因?yàn)橛脩羯矸莸牟煌哂胁煌闹怠?/p>

2.環(huán)境變量的分類

按照變量的生存周期劃分,Linux 變量可分為兩類:

  • 永久的:需要修改配置文件,變量永久生效。
  • 臨時(shí)的:使用 export 命令聲明即可,變量在關(guān)閉 shell 時(shí)失效。

按作用的范圍分,在 Linux 中的變量,可以分為環(huán)境變量和本地變量:

  • 環(huán)境變量:相當(dāng)于全局變量,存在于所有的 Shell 中,具有繼承性;
  • 本地變量:相當(dāng)于局部變量只存在當(dāng)前 Shell 中,本地變量包含環(huán)境變量,非環(huán)境變量不具有繼承性。

3.查看環(huán)境變量

值得一提的是,Linux 系統(tǒng)中環(huán)境變量的名稱一般都是大寫的,這是一種約定俗成的規(guī)范。

使用 echo 命令查看單個(gè)環(huán)境變量,例如:echo $PATH;使用 env 查看當(dāng)前系統(tǒng)定義的所有環(huán)境變量;使用 set 查看所有本地定義的環(huán)境變量。查看 PATH 環(huán)境的實(shí)例如下:

認(rèn)識(shí)環(huán)境變量和進(jìn)程替換,實(shí)現(xiàn)一個(gè)簡(jiǎn)易的shell,c++,數(shù)據(jù)結(jié)構(gòu),linux,ubuntu,centos,vim

常用的命令如下:

  1. echo: 顯示某個(gè)環(huán)境變量值
  2. export: 設(shè)置一個(gè)新的環(huán)境變量
  3. env: 顯示所有環(huán)境變量
  4. unset: 清除環(huán)境變量
  5. set: 顯示本地定義的shell變量和環(huán)境變量

例如我們要設(shè)置一個(gè)新的環(huán)境變量,然后再清除:

認(rèn)識(shí)環(huán)境變量和進(jìn)程替換,實(shí)現(xiàn)一個(gè)簡(jiǎn)易的shell,c++,數(shù)據(jù)結(jié)構(gòu),linux,ubuntu,centos,vim

`

4.設(shè)置環(huán)境變量

在 Linux 中設(shè)置環(huán)境變量有三種方法:

1.所有用戶永久添加環(huán)境變量: vi /etc/profile,在 /etc/profile 文件中添加變量。

2.當(dāng)前用戶永久添加環(huán)境變量: vi ~/.bashrc,在用戶目錄下的 ~/.bashrc 文件中添加變量。

3.臨時(shí)添加環(huán)境變量 : 可通過(guò) export 命令,如運(yùn)行命令export HELLO=100。

5.獲取環(huán)境變量

  • 命令行第三個(gè)參數(shù)
#include <stdio.h>
int main(int argc, char *argv[], char *env[])
{
	 int i = 0;
	 for(; env[i]; i++){
	 printf("%s\n", env[i]);
	 }
	 return 0;
}
  • 通過(guò)第三方變量environ 獲取
#include <stdio.h>
int main(int argc, char *argv[])
{
	 extern char **environ;
	 int i = 0;
	 for(; environ[i]; i++){
	 printf("%s\n", environ[i]);
	 }
	 return 0;
}

lib.c中定義的全局變量environ指向環(huán)境變量表,environ沒有包含在任何頭文件中,所以在使用時(shí)要用extern聲明。

  • 通過(guò)系統(tǒng)調(diào)用獲取
#include <stdio.h>
#include <stdlib.h>
int main()
{
 	printf("%s\n", getenv("PATH"));
 	return 0;
}

二、進(jìn)程控制

1.進(jìn)程終止

正常退出:

  • 從 main 函數(shù)返回
  • 調(diào)用exit
  • 調(diào)用_exit

異常退出:

  • crtl + c,信號(hào)終止

_exit():

 #include <unistd.h>
 void _exit(int status);

DESCRIPTION:

The function _exit() terminates the calling process “immediately”. Any open file descriptors belonging to the process are closed; any children of the process are inherited byprocess 1, init, and the process’s parent is sent a SIGCHLD signal.

_eixt()函數(shù)立即終止進(jìn)程,關(guān)閉所有屬于該進(jìn)程的文件描述符,其子進(jìn)程被1號(hào)init 進(jìn)程領(lǐng)養(yǎng),然后向父進(jìn)程發(fā)送SIGCHLD 信號(hào)。

The value status is returned to the parent process as the process’s exit status, and can be collected using one of the wait(2) family of calls.

值狀態(tài)作為進(jìn)程的退出狀態(tài)返回到父進(jìn)程,并且可以使用 wait(2) 系列調(diào)用之一來(lái)收集。

exit():

 #include <unistd.h>
 void exit(int status);
  1. 執(zhí)行用戶通過(guò) atexit或on_exit定義的清理函數(shù)。
  2. 關(guān)閉所有打開的流,所有的緩存數(shù)據(jù)均被寫入
  3. 調(diào)用_exit

return是一種更常見的退出進(jìn)程方法。執(zhí)行return n等同于執(zhí)行exit(n),因?yàn)檎{(diào)用main的運(yùn)行時(shí)函數(shù)會(huì)將main的返回值當(dāng)做 exit的參數(shù)。

2.進(jìn)程等待

進(jìn)程等待的必要性:

  • 子進(jìn)程退出,父進(jìn)程如果不管不顧,就可能造成‘僵尸進(jìn)程’的問題,進(jìn)而造成內(nèi)存泄漏。
  • 進(jìn)程一旦變成僵尸狀態(tài),那就刀槍不入,“殺人不眨眼”的kill -9 也無(wú)能為力,因?yàn)檎l(shuí)也沒有辦法殺死一個(gè)已經(jīng)死去的進(jìn)程。
  • 父進(jìn)程派給子進(jìn)程的任務(wù)完成的如何,我們需要知道。如,子進(jìn)程運(yùn)行完成,結(jié)果對(duì)還是不對(duì),或者是否正常退出。
  • 父進(jìn)程通過(guò)進(jìn)程等待的方式,回收子進(jìn)程資源,獲取子進(jìn)程退出信息

wait():用來(lái)等待任何一個(gè)子進(jìn)程退出,由父進(jìn)程調(diào)用。

#include<sys/types.h>
#include<sys/wait.h>
pid_t wait(int*status);

返回值:
 成功返回被等待進(jìn)程pid,失敗返回-1。
參數(shù):
 輸出型參數(shù),獲取子進(jìn)程退出狀態(tài),不關(guān)心則可以設(shè)置成為NULL
wait方式:
 阻塞式等待,等待的子進(jìn)程不退出時(shí),父進(jìn)程一直不退出;

waitpid():

pid_ t waitpid(pid_t pid, int *status, int options);

參數(shù):
pid:
 Pid=-1,等待任一個(gè)子進(jìn)程。與wait等效。
 Pid>0.等待其進(jìn)程ID與pid相等的子進(jìn)程。
 
status:
 WIFEXITED(status): 若為正常終止子進(jìn)程返回的狀態(tài),則為真。(查看進(jìn)程是否是正常退出)
 WEXITSTATUS(status): 若WIFEXITED非零,提取子進(jìn)程退出碼。(查看進(jìn)程的退出碼)
 
options:
	當(dāng)options參數(shù)為0時(shí),與wait功能相同,仍是阻塞式等待,不提供額外功能
	如果為下列常量按位或則提供更多功能:
 WCONTINUED:若實(shí)現(xiàn)支持作業(yè)控制,那么由pid指定的任一子進(jìn)程在暫停后已經(jīng)繼續(xù),但狀態(tài)尚未報(bào)告,則返回狀態(tài)
 WNOHANG:若由pid指定的子進(jìn)程并不是立即結(jié)束,則waitpid不阻塞,即此時(shí)以非阻塞方式(輪詢式訪問的必要條件)等待子進(jìn)程,并且返回0。若正常結(jié)束,則返回該?進(jìn)程的ID。
 WUNTRACED:若實(shí)現(xiàn)支持作業(yè)控制,而pid指定的任一子進(jìn)程已經(jīng)暫停,且其狀態(tài)尚未報(bào)告,則返回其狀態(tài)。

返回值:
當(dāng)正常返回的時(shí)候,waitpid返回收集到的子進(jìn)程的進(jìn)程ID;
如果設(shè)置了選項(xiàng)WNOHANG,而調(diào)用中waitpid發(fā)現(xiàn)沒有已退出的子進(jìn)程可收集,則返回0;
如果調(diào)用中出錯(cuò),則返回-1,這時(shí)errno會(huì)被設(shè)置成相應(yīng)的值以指示錯(cuò)誤所在;
當(dāng)pid所指示的子進(jìn)程不存在,或此進(jìn)程存在,但不是調(diào)用進(jìn)程的子進(jìn)程,waitpid就會(huì)出錯(cuò)返回,這時(shí)errno被設(shè)置為ECHILD;

獲取子進(jìn)程status:

  • wait和waitpid,都有一個(gè)status參數(shù),該參數(shù)是一個(gè)輸出型參數(shù),由操作系統(tǒng)填充。
  • 如果傳遞NULL,表示不關(guān)心子進(jìn)程的退出狀態(tài)信息。
    否則,操作系統(tǒng)會(huì)根據(jù)該參數(shù),將子進(jìn)程的退出信息反饋給父進(jìn)程。
  • status不能簡(jiǎn)單的當(dāng)作整形來(lái)看待,可以當(dāng)作位圖來(lái)看待,具體細(xì)節(jié)如下(只研究status低16比特位):
    認(rèn)識(shí)環(huán)境變量和進(jìn)程替換,實(shí)現(xiàn)一個(gè)簡(jiǎn)易的shell,c++,數(shù)據(jù)結(jié)構(gòu),linux,ubuntu,centos,vim

我們可以通過(guò)status & 0x7f來(lái)判斷異常信號(hào)是否為0;若為0,則正常退出,然后可以通過(guò)(status >> 8) & 0xff來(lái)獲取子進(jìn)程返回值。sys/wait.h中提供了一些宏來(lái)簡(jiǎn)化這些操作:

if (WIFEXITED(status)) {
    // 正常退出:((status) & 0x7f) == 0
    // 打印退出碼:(status >> 8) & 0xff
    printf("child return: %d\n", WEXITSTATUS(status));
} else if (WIFSIGNALED(status)) {
    // 異常退出:((signed char) (((status) & 0x7f) + 1) >> 1) > 0
    // 打印異常信號(hào)值:(status) & 0x7f
    printf("child signal: %d\n", WTERMSIG(status));
}

我們用這段代碼來(lái)讀取子進(jìn)程的status,以獲取它的退出碼和異常信號(hào)值,以及父進(jìn)程收到的SIGCHLD信號(hào):

#include<stdio.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>
#include<stdlib.h>


void catchsig(int sig)
{
    printf("catch a sig : %d , pid->%d\n",sig,getpid());
}

int main()
{
    signal(SIGCHLD,catchsig);
    pid_t id = fork();

    if(id<0)
    {
        printf("fork error!\n");
        exit(-1);
    }
    else if(id==0)
    {
        int cnt = 3;
        while(cnt)
        {
            printf("this is a child process! id-->%d   pid-->%d  ppid--> %d\n",cnt--,getpid(),getppid());
        }
        //exit(-1);
       int i =  10/0;
    }

    sleep(2);
    int status = 0;
    pid_t ret = waitpid(id,&status,0);
    if(id>0)
        //0-7:終止信號(hào) 15-8:退出狀態(tài)
        printf("wait success:%d , sign number:%d , child exit code:%d\n",ret,(status & 0x7F),(status>>8 & 0xFF));

    return 0;
}

運(yùn)行結(jié)果如下:

認(rèn)識(shí)環(huán)境變量和進(jìn)程替換,實(shí)現(xiàn)一個(gè)簡(jiǎn)易的shell,c++,數(shù)據(jù)結(jié)構(gòu),linux,ubuntu,centos,vim
 其實(shí),?進(jìn)程在終?時(shí)會(huì)給?進(jìn)程發(fā)SIGCHLD信號(hào),該信號(hào)的默認(rèn)處理動(dòng)作是忽略,?進(jìn)程可以?定義SIGCHLD信號(hào)的處理函數(shù),這樣?進(jìn)程只需專?處理??的?作,不必關(guān)??進(jìn)程了,?進(jìn)程終?時(shí)會(huì)通知?進(jìn)程,?進(jìn)程在信號(hào)處理函數(shù)中調(diào)?wait清理?進(jìn)程即可。一般情況下父進(jìn)程收到這個(gè)信號(hào)的默認(rèn)處理是忽略這個(gè)信號(hào),即就是不做任何處理。

3.進(jìn)程替換

替換原理:

用fork創(chuàng)建子進(jìn)程后執(zhí)行的是和父進(jìn)程相同的程序(但有可能執(zhí)行不同的代碼分支),子進(jìn)程往往要調(diào)用一種exec函數(shù)以執(zhí)行另一個(gè)程序。當(dāng)進(jìn)程調(diào)用一種exec函數(shù)時(shí),該進(jìn)程的用戶空間代碼和數(shù)據(jù)完全被新程序替換,從新程序的啟動(dòng)例程開始執(zhí)行。調(diào)用exec并不創(chuàng)建新進(jìn)程,所以調(diào)用exec前后該進(jìn)程的id并未改變。

替換函數(shù):

#include <unistd.h>

       extern char **environ;

       int execl(const char *path, const char *arg, ...);
       int execlp(const char *file, const char *arg, ...);
       int execle(const char *path, const char *arg, ... , char * const envp[]);
       int execv(const char *path, char *const argv[]);
       int execvp(const char *file, char *const argv[]);
       int execvpe(const char *file, char *const argv[], *const envp[]);
       
	這些函數(shù)如果調(diào)用成功則加載新的程序從啟動(dòng)代碼開始執(zhí)行,不再返回。
	如果調(diào)用出錯(cuò)則返回-1,所以exec函數(shù)只有出錯(cuò)的返回值而沒有成功的返回值。

命名理解:

l(list) : 表示參數(shù)采用列表
v(vector) : 參數(shù)用數(shù)組
p(path) : 有p自動(dòng)搜索環(huán)境變量PATH
e(env) : 表示自己維護(hù)環(huán)境變量

int execl(const char *path, const char *arg, ...);

其中*path表示的是路徑,arg表示的是要執(zhí)行的程序,“…”表示的就是可變參數(shù)列表,即命令行上怎么執(zhí)行這里就寫入什么參數(shù)。必須以NULL作為參數(shù)列表的結(jié)束。

#include<unistd.h>    
#include<stdio.h>    
#include<sys/wait.h>    
#include<stdlib.h>    
int main()    
{    
  if(fork()==0)    
  {    
    printf("command begin\n");    
    execl("/usr/bin/ls","ls","-a","-l",NULL);                                                                                                            
    printf("command fail\n");    
    exit(1);    
  }    
  waitpid(-1,NULL,0);    
  printf("wait child success\n");    
  return 0;    
}    

當(dāng)子進(jìn)程執(zhí)行完打印command begin的語(yǔ)句的時(shí)候,進(jìn)行進(jìn)程的替換。其中替換的是/usr/bin/ls,在命令行要輸入的是ls -a -l,將程序運(yùn)行起來(lái):

認(rèn)識(shí)環(huán)境變量和進(jìn)程替換,實(shí)現(xiàn)一個(gè)簡(jiǎn)易的shell,c++,數(shù)據(jù)結(jié)構(gòu),linux,ubuntu,centos,vim

下面是這些函數(shù)的用法:

#include <unistd.h>
int main()
{
 	char *const argv[] = {"ps", "-ef", NULL};
 	char *const envp[] = {"PATH=/bin:/usr/bin", "TERM=console", NULL};
 	
 	execl("/bin/ps", "ps", "-ef", NULL);
 	
 // 帶p的,可以使用環(huán)境變量PATH,無(wú)需寫全路徑
 	execlp("ps", "ps", "-ef", NULL);
 	
 // 帶e的,需要自己組裝環(huán)境變量
 	execle("ps", "ps", "-ef", NULL, envp);
 	
 	execv("/bin/ps", argv);
 
 // 帶p的,可以使用環(huán)境變量PATH,無(wú)需寫全路徑
 	execvp("ps", argv);
 	
 // 帶e的,需要自己組裝環(huán)境變量
 	execve("/bin/ps", argv, envp);
 	
 	exit(0);
}

操作系統(tǒng)實(shí)際上只提供了一個(gè)接口那就是:execve,其他的函數(shù)都是對(duì)該接口封裝而成的庫(kù)函數(shù)。它們的底層都是使用execve來(lái)進(jìn)行實(shí)現(xiàn)的。

三、實(shí)現(xiàn)一個(gè)簡(jiǎn)單的shell

以下代碼利用程序替換實(shí)現(xiàn)了shell 的基本功能,包括重定向,退出碼等功能,后續(xù)還可以再補(bǔ)充。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-720574.html

#include<stdio.h>
#include<ctype.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<assert.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>
#define NUM 1024//緩沖區(qū)大小
#define COM_NUM 64//存放指令字符串的最大值
#define NONE_REDIR 0
#define INPUT_REDIR 1
#define OUPUT_REDIR 2
#define APPEND_REDIR  4
char lineCommand[NUM];//輸入緩沖區(qū)
char *myargv[COM_NUM];//存放一個(gè)個(gè)的指令字符串
int exit_code=0;//退出碼
int exit_sign=0;//退出信號(hào)值
int redirType = NONE_REDIR;//讀方式
char* myFile = NULL;

//跳過(guò)空格
#define trimSpace(start) do{while(isspace(*start)) ++start;}while(0)


void commandCheck(char* commands)
{
    assert(commands);
    char *start = commands;
    char *end = commands+strlen(commands);

    while(start<end)
    {
        if(*start == '>')
        {
            *start = '\0';
            start++;
            if(*start == '>') // >> 表示追加重定向
            {
                start++;
                redirType = APPEND_REDIR;
            }
            else // > 表示輸出重定向 
            {
                
                redirType = OUPUT_REDIR;
            }

            trimSpace(start);
            myFile = start;
            break;
        }
        else if(*start == '<') // < 表示輸入重定向
        {
            *start = '\0';
            start++;
            redirType = INPUT_REDIR;
            trimSpace(start);
            myFile = start;
            break;
        }
        else 
            start++;
    }
}

//最新添加重定向功能!!!!!
int main()
{
    while(1)
    {
        redirType = NONE_REDIR;
        myFile = NULL;

        printf("[wml @ my_bash path#]");
        fflush(stdout);
        
        //獲取輸入行內(nèi)容
        char *s = fgets(lineCommand,sizeof(lineCommand)-1,stdin);
        assert(s != NULL);
        (void)s;

        lineCommand[strlen(lineCommand)-1] = 0;

        //重定向:
        //"ls -a -l > "test.txt""  ---->  "ls -a -l"  >  "test.txt"
        //"ls -a -l >> "test.txt""  ---->  "ls -a -l"  >>  "test.txt"
        //"cat < "test.txt""  ---->  "cat"  <  "test.txt"
    
        commandCheck(lineCommand);

        //切割字符串
        myargv[0] = strtok(lineCommand," ");
        int i = 1;

        //添加顏色選項(xiàng)
        if(myargv[0]!= NULL && strcmp(myargv[0],"ls") == 0  )
        {
            myargv[i++]  = (char*) "--color=auto";
        }

        //讀取每個(gè)選項(xiàng)
        while(myargv[i++] = strtok(NULL," "));
        
        //解決工作路徑無(wú)法改變的問題
        if(myargv[0]!=NULL && strcmp(myargv[0],"cd") == 0)
        {
            if(myargv[1]!=NULL) 
                chdir(myargv[1]);
            continue;
        }

        //設(shè)置退出碼
        if(myargv[0]!=NULL && myargv[1]!=NULL && strcmp(myargv[0],"echo")==0 )
        {
            if(strcmp(myargv[1],"$?")==0)
                printf("exit_code-->%d | exit_sign-->%d\n",exit_code,exit_sign);
            else 
                printf("%s\n",myargv[1]);
            continue;
        }

#ifdef DEBUG 
        for(int i=0;myargv[i];i++)
            printf("myargv[%d]:%s\n",i,myargv[i]);
#endif

        pid_t id = fork();
        assert(id!=-1);

        if(id==0)
        {
            switch(redirType)
            {
                case NONE_REDIR:
                    break;
                case INPUT_REDIR:
                {
                    int fd  = open(myFile,O_RDONLY);
                    if(fd<0) {perror("open");return 1;}
                    dup2(fd,0);
                }
                     break;
                case OUPUT_REDIR:
                case APPEND_REDIR:
                {
                    umask(0);
                    int flag = O_WRONLY | O_CREAT;
                    if(redirType == APPEND_REDIR) flag |= O_APPEND;
                    else flag |= O_TRUNC;

                    int fd  = open(myFile,flag,0666);
                    if(fd<0){perror("open");return 2;};
                    dup2(fd,1);
                }
                    break;
                default:
                    printf("bug!\n");
                    break;

            }
            execvp(myargv[0],myargv);
           _exit(1);
        }

        int status=0;
        pid_t ret = waitpid(id,&status,0);
        assert(ret!=-1);
        (void)ret;

        exit_sign = (status & 0x7f);
        exit_code = (status>>8) & 0xff;


    }
    return 0;
}

到了這里,關(guān)于認(rèn)識(shí)環(huán)境變量和進(jìn)程替換,實(shí)現(xiàn)一個(gè)簡(jiǎn)易的shell的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【看表情包學(xué)Linux】插敘:實(shí)現(xiàn)簡(jiǎn)易的 Shell | 通過(guò)內(nèi)建命令實(shí)現(xiàn)路徑切換 | 再次理解環(huán)境變量

    【看表情包學(xué)Linux】插敘:實(shí)現(xiàn)簡(jiǎn)易的 Shell | 通過(guò)內(nèi)建命令實(shí)現(xiàn)路徑切換 | 再次理解環(huán)境變量

    ?? ??? 爆笑 教程 ????《看表情包學(xué)Linux》?? ? 猛戳訂閱 ? ? ?? ?? 寫在前面: 本章是個(gè) \\\"插敘\\\",前幾章我們學(xué)了程序替換,現(xiàn)在我們可以嘗試動(dòng)手做一個(gè) \\\"會(huì)創(chuàng)建,會(huì)終止,會(huì)等待,會(huì)程序替換\\\" 的簡(jiǎn)易?shell 了。通過(guò)本章的內(nèi)容,可以進(jìn)一步鞏固進(jìn)程替換,學(xué)習(xí)內(nèi)建

    2024年02月22日
    瀏覽(93)
  • 【Linux】教你用進(jìn)程替換制作一個(gè)簡(jiǎn)單的Shell解釋器

    【Linux】教你用進(jìn)程替換制作一個(gè)簡(jiǎn)單的Shell解釋器

    本章的代碼可以訪問這里獲取。 由于程序代碼是一體的,本章在分開講解各部分的實(shí)現(xiàn)時(shí),代碼可能有些跳躍,建議在講解各部分實(shí)現(xiàn)后看一下源代碼方便理解程序。 我們想要制作一個(gè)簡(jiǎn)單的 Shell 解釋器,需要先觀察Shell是怎么運(yùn)行的,根據(jù) Shell 的運(yùn)行狀態(tài)我們?cè)偃ミM(jìn)行模

    2024年02月02日
    瀏覽(112)
  • 『Linux從入門到精通』第 ? 期 - 學(xué)會(huì)了程序替換,我決定手寫一個(gè)簡(jiǎn)易版shell玩一玩...

    『Linux從入門到精通』第 ? 期 - 學(xué)會(huì)了程序替換,我決定手寫一個(gè)簡(jiǎn)易版shell玩一玩...

    ??作者簡(jiǎn)介: 花想云 ,在讀本科生一枚,C/C++領(lǐng)域新星創(chuàng)作者,新星計(jì)劃導(dǎo)師,阿里云專家博主,CSDN內(nèi)容合伙人…致力于 C/C++、Linux 學(xué)習(xí)。 ?? 專欄簡(jiǎn)介:本文收錄于 Linux從入門到精通 ,本專欄主要內(nèi)容為本專欄主要內(nèi)容為L(zhǎng)inux的系統(tǒng)性學(xué)習(xí),專為小白打造的文章專欄。

    2024年02月14日
    瀏覽(18)
  • 【Linux】Linux環(huán)境變量的理解 --- 命令行參數(shù)、shell子進(jìn)程、環(huán)境變量、本地變量…

    【Linux】Linux環(huán)境變量的理解 --- 命令行參數(shù)、shell子進(jìn)程、環(huán)境變量、本地變量…

    加油布魯斯,你能行的! 1. 我們平常所用的Linux指令其實(shí)也是可執(zhí)行程序,和我們自己寫的二進(jìn)制程序沒什么兩樣,那么為什么在執(zhí)行自己的程序的時(shí)候需要加上./,而執(zhí)行這些系統(tǒng)提供的指令(可執(zhí)行程序),不需要加上./呢? 2. 要執(zhí)行一個(gè)程序或者指令,必須先找到這個(gè)

    2024年01月16日
    瀏覽(19)
  • 【Linux初階】進(jìn)程替換的應(yīng)用 - 簡(jiǎn)易命令行解釋器的實(shí)現(xiàn)

    【Linux初階】進(jìn)程替換的應(yīng)用 - 簡(jiǎn)易命令行解釋器的實(shí)現(xiàn)

    ??hello,各位讀者大大們你們好呀?? ????系列專欄:【Linux初階】 ????本篇內(nèi)容:使用代碼手段實(shí)現(xiàn)一個(gè)簡(jiǎn)易的命令行解釋器,其中功能包括:打印輸出提示符、獲取用戶輸入、字符串切割、執(zhí)行命令、ls指令下?lián)碛蓄伾崾尽d、echo; ????作者簡(jiǎn)介:計(jì)算機(jī)海洋的

    2024年02月07日
    瀏覽(93)
  • 【linux】進(jìn)程替換的應(yīng)用|shell解釋器的實(shí)現(xiàn)

    【linux】進(jìn)程替換的應(yīng)用|shell解釋器的實(shí)現(xiàn)

    當(dāng)我們學(xué)過(guò)了進(jìn)程替換之后,本篇文章可以根據(jù)進(jìn)程替換的知識(shí)帶你自主實(shí)現(xiàn)一個(gè)shell命令行 實(shí)現(xiàn)步驟 1.顯示命令行提示 2.讀取輸入指令以及對(duì)應(yīng)選項(xiàng) 3.分割第二步的指令以及選項(xiàng)到命令行參數(shù)表中 4.處理內(nèi)建命令 5.進(jìn)程替換 我們通過(guò)觀察bash的命令行提示發(fā)現(xiàn)他是由三部分

    2024年04月26日
    瀏覽(100)
  • [Linux]進(jìn)程控制精講,簡(jiǎn)單實(shí)現(xiàn)一個(gè)shell

    [Linux]進(jìn)程控制精講,簡(jiǎn)單實(shí)現(xiàn)一個(gè)shell

    目錄 前言 進(jìn)程創(chuàng)建 fork函數(shù)初識(shí) 寫時(shí)拷貝 fork常見用法 fork調(diào)用失敗的原因 進(jìn)程終止 進(jìn)程退出場(chǎng)景 進(jìn)程退出碼 查看進(jìn)程退出碼 退出碼的含義 進(jìn)程常見退出方法 exit VS _exit exit函數(shù) _exit函數(shù) 二者的區(qū)別 return退出 進(jìn)程等待 進(jìn)程等待必要性 進(jìn)程等待的方法 wait方法 waitpid方法

    2023年04月26日
    瀏覽(15)
  • 【Linux】Linux進(jìn)程控制 --- 進(jìn)程創(chuàng)建、終止、等待、替換、shell派生子進(jìn)程的理解…

    【Linux】Linux進(jìn)程控制 --- 進(jìn)程創(chuàng)建、終止、等待、替換、shell派生子進(jìn)程的理解…

    柴犬: 你好啊,屏幕前的大帥哥or大美女,和我一起享受美好的今天叭?????? 1. 在調(diào)用fork函數(shù)之后, 當(dāng)執(zhí)行的程序代碼轉(zhuǎn)移到內(nèi)核中的fork代碼后 ,內(nèi)核需要分配 新的內(nèi)存塊 和 內(nèi)核數(shù)據(jù)結(jié)構(gòu) 給子進(jìn)程, 內(nèi)核數(shù)據(jù)結(jié)構(gòu)包括PCB、mm_struct和頁(yè)表,然后構(gòu)建起映射關(guān)系 ,同時(shí)

    2024年01月16日
    瀏覽(25)
  • export 是一個(gè)在 Unix 和類 Unix 系統(tǒng)(比如 Linux 和 macOS)中常用的 shell 命令,主要用于設(shè)置或?qū)С霏h(huán)境變量。

    export 是一個(gè)在 Unix 和類 Unix 系統(tǒng)(比如 Linux 和 macOS)中常用的 shell 命令,主要用于設(shè)置或?qū)С霏h(huán)境變量。環(huán)境變量是在操作系統(tǒng)中用于存儲(chǔ)系統(tǒng)設(shè)置和命令行程序配置的全局值。下面提供了一些 export 命令的基本用法和示例。 基本用法 設(shè)置環(huán)境變量 : 這里, VARIABLE_NAME 是

    2024年01月19日
    瀏覽(16)
  • 【手把手教你制作一個(gè)簡(jiǎn)易版的shell】

    【手把手教你制作一個(gè)簡(jiǎn)易版的shell】

    為了簡(jiǎn)便,命令行中的提示符我們可以直接用printf打印,而具體執(zhí)行命令可以交給子進(jìn)程去做,現(xiàn)在的關(guān)鍵是如何將獲得的命令行中的命令切割。我們?cè)趯W(xué)習(xí)C語(yǔ)言時(shí)提到了strtok函數(shù),正好這個(gè)函數(shù)可以用來(lái)作為切割。 基本框架: 不知道大家注意到了沒有,我們從鍵盤中讀取

    2023年04月16日
    瀏覽(39)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包