Linux環境下編寫簡單的Shell

2021-08-30 04:14:44 字數 2976 閱讀 6351

使用程序建立、等待、終止等知識自主實現簡單的linuxshell命令列,linux環境:centos7.3

fork()函式有兩個返回值,它會給子程序返回0,給父程序返回子程序的pid,如果建立子程序失敗,則會返回-1

通過fork()建立的子程序與父程序會共享同乙份**,因為**段的資料是唯讀的,不會發生寫入,而當父程序與子程序的資料段不發生寫入時,它們的資料段也是共享的,當子程序或父程序任何一方發生寫入時,就會另外開闢自己的資料段,將原來的資料拷貝過去

正常終止(可以通過echo $?來檢視退出碼,echo $?只可檢視最近一次退出的程序的退出碼)

異常退出wait方法&waitpid方法

#include#includepid_t wait(int* status);

返回值:

成功返回則返回被等待程序的id,失敗返回0

引數: 獲取子程序的退出狀態,不關心則設定為null

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

返回值:

當waitpid收集到已退出的子程序時waitpid返回被等待程序的id

如果設定了選項wnohang,而呼叫waitpid發現沒有已退出的子程序可以被收集時,則返回0

引數說明:

pid:

pid=-1,等待任意乙個子程序,與wait效果相同。

pid>0,等待程序id與pid相等的子程序。

status:

wifexited(status): status若為正常終止子程序返回的狀態,則為真。

wexitstatus(status): 若wifexited非零,提取子程序提出碼。

options:

wnhang:若pid指定的子程序沒有結束,則waitpid()函式返回0,不予以等待。若正常結束,則返回該子程序的id。

#include#include#include#include#include#define max_argv 20

#define max_cmd 1024

void cut_str(char* argv,char cmd)//將輸入的命令分段,儲存至argv指標陣列內

else if(*ptr==' '&&flag==1)

ptr+=1;

} //去掉命令尾部的'\n'

ptr=argv[i-1];

while(*ptr!='\0')

*(ptr-1)='\0';

//以null結尾

argv[i]=null;

}void new_pro(char* argv)

else if(0==id)//子程序

else//父程序 }

int main()

;//定義陣列來儲存輸入的內容

char* argv[max_argv];//定義乙個陣列來存放argv(execvp()函式的第二個引數)

while(1)

return 0;

}

#include#include#include#includevoid process_create(pid* pid, void func, void* arg)

else if(0 == *pid)//子程序

((pf)func)(arg);//執行func函式,先要進行強制型別轉換

exit(0);

} else//父程序

}

#includeint system(const char* command);
int system(const char *command)}}

}

#includefile* popen(const char* command, const char* type);

int pclose(file* stream);

popen()也是執行shell命令並且通過管道和shell命令進行通訊。

static pid_t    *childpid = null;  

/* ptr to array allocated at run-time */

static int maxfd; /* from our open_max(), */

#define shell "/bin/sh"

file *

popen(const char *cmdstring, const char *type)

if (childpid == null)

if (pipe(pfd) < 0)

return(null); /* errno set by pipe() */

if ( (pid = fork()) < 0)

return(null); /* errno set by fork() */

else if (pid == 0)

} else

} /* close all descriptors in childpid */

for (i = 0; i < maxfd; i++)

if (childpid[ i ] > 0)

close(i);

execl(shell, "sh", "-c", cmdstring, (char *) 0);

_exit(127);

} /* parent */

if (*type == 'r') else

childpid[fileno(fp)] = pid; /* remember child pid for this fd */

return(fp);

}

Linux環境下svn回滾單個檔案的shell函式

svnrollback v 獲取到檔案的所有更新資訊 arr svn log file 從更新資訊中刪去不必要的資訊 arr 這條指令執行兩遍代表著獲取當前版本的上乙個版本號 想獲得上n個版本就重複n 1遍 arr 繼續抽取 arr 獲得目標版本號 lv echo roll back 將兩個版本的檔...

Linux的sh指令碼編寫基礎知識

本文總結的shell指令碼編寫核心要點切中要害,入門必讀。1 開頭 程式必須以下面的行開始 必須方在檔案的第一行 bin sh 符號 用來告訴系統它後面的引數是用來執行該檔案的程式。在這個例子中我們使用 bin sh來執行程式。當編寫指令碼完成時,如果要執行該指令碼,還必須使其可執行。要使編寫指令碼...

linux 下 sh 檔案語法

介紹 1 開頭 程式必須以下面的行開始 必須方在檔案的第一行 bin sh 符號 用來告訴系統它後面的引數是用來執行該檔案的程式。在這個例子中我們使用 bin sh來執行程式。當編寫指令碼完成時,如果要執行該指令碼,還必須使其可執行。要使編寫指令碼可執行 編譯 chmod x filename 這樣...