欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Linux實(shí)現(xiàn)自主Shell命令行解釋器

 更新時間:2025年04月03日 09:55:26   作者:孫同學(xué)_  
本文主要介紹了Linux實(shí)現(xiàn)自主Shell命令行解釋器,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

1. 獲取用戶名的接口

通過環(huán)境變量來獲取
我們需要用到的接口getenv

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

//獲取用戶名
const char* GetUserName()
{
	const char* name = getenv("USER");
	return name == NULL ? "None" : name;
}

 //獲取主機(jī)名
const char* GetHostName()
{
	const char* hostname = getenv("HOSTNAME");
	return hostname == NULL ? "None" : hostname;
}

 //獲取當(dāng)前路徑
const char* GetPwd()
{
	const char* pwd = getenv("PWD");
	return pwd == NULL ? "None" : pwd;
}

2. 等待用戶輸入接口

當(dāng)我們沒有輸入時,我們會發(fā)現(xiàn)命令行會卡在這里等待我們輸入

在這里插入圖片描述

我們也讓我們自己的命令行能等待輸入

在這里插入圖片描述

我們可以采用fgets以文件形式讀取一行,也可以使用gets讀取一行字符串
我們接下來進(jìn)行C/C++混編的方式,因?yàn)槲覀兒竺鏁玫较到y(tǒng)調(diào)用,而這些系統(tǒng)調(diào)用都是用C寫的,如果我們純用C++來實(shí)現(xiàn)的話可能會要適配某些接口。
我們下來用fgets實(shí)現(xiàn)

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

效果展示:

在這里插入圖片描述

我們會發(fā)現(xiàn)最后多了一個空行,這里為什么會多一個空行呢?因?yàn)槲覀冊谳斎胪曜址筮€按了一次回車,我們不想讓它有這一行空行該怎么辦?我們在輸入字符串后后面還會有個\n,比如我們輸入的是"ls -a -l"最后再按一次回車就變成了"ls -a -l \n",我們只需要輸入完之后把最后的\n置為0就好了

在這里插入圖片描述

效果展示:

在這里插入圖片描述

??小tips: 這里會不會求出的字符串長度為0,然后再-1發(fā)生越界呢?答案是不會的,因?yàn)槲覀冏詈笾辽龠€要敲一次回車鍵,所以這個字符串的最小長度為1。

3. 將上述代碼進(jìn)行面向?qū)ο笫降姆庋b

我們先認(rèn)識一個新的接口snprintf

在這里插入圖片描述

在這里插入圖片描述

//制作命令行提示符
void MakeCommandline(char com_prompt[], int size)
{
	snprintf(com_prompt, size, FORMAT, GetUserName(), GetHostName(), GetPwd());//我們想讓"[%s@%s %s]# "以后能隨便調(diào)整,所以我們define一下
}

//打印命令行提示符
void PrintCommandline()
{
	char prompt[COMMAND_SIZE];
	MakeCommandline(prompt, sizeof(prompt));//先制作
	printf("%s", prompt);//再打印
	fflush(stdout);
}

 //獲取用戶輸入
bool GetCommandline(char* out, int size)
{
	//"ls -a -l "=>"ls -a -l \n"
	const char* c = fgets(out, size, stdin);//從標(biāo)準(zhǔn)輸入里獲取,放到out當(dāng)中
	if (c == NULL) return 1;
	out[strlen(out) - 1] = 0;//清理\n 
	if (strlen(out) == 0) return false; //對于我們用戶來說,有可能獲取到的字符串的長度為0,為0直接return false 
	return true; //否則return true
}

int main()
{
	//printf("[%s@%s %s]# ",GetUserName(),GetHostName(),GetPwd());
    //1. 打印命令行提示符
	PrintCommandline();

	//2.獲取用戶輸入
	char commandline[COMMAND_SIZE];//定義一個數(shù)組
	if (GetCommandline(commandline, sizeof(commandline)))//如果獲取成功
	{
		printf("echo %s\n", commandline);//回顯一下我們輸入的內(nèi)容,用作測試
	}

	return 0;
}

我們在shell中可以一直輸入,我們的程序輸入一次就結(jié)束了,所以shell永遠(yuǎn)不退出。我們應(yīng)當(dāng)不斷地獲取用戶輸入。

在這里插入圖片描述

4. 命令行解析

我們在傳字符串的時候不能“ls -a -l”整體傳入,我們要將傳入的字符串進(jìn)行變形,將這一個字符串拆成“ls” "-a" "-l"。而且我們的命令行也不能在shell中直接替換,而要創(chuàng)建子進(jìn)程。我們將字符串切成這樣那么如何快速的找到每一個元素呢?命令行參數(shù)表

將打散的字符串以NULL結(jié)尾放到g_argv[]里面。在這里又來認(rèn)識一個新的接口strtok

在這里插入圖片描述

這個接口第一次切的時候第一個參數(shù)傳的是要分割的字符串的起始地址,如果要接著切的話第一個參數(shù)就必須傳NULL,當(dāng)切除完畢返回值就為空表示沒有字符串了。
分隔符是const char*所以我們不能傳單引號,而要傳雙引號

在這里插入圖片描述

//命令行分析
bool CommandParse(char* commandline)
{
#define SEP " "
	g_argc = 0; //每次進(jìn)來初始化為0
	//"ls -a -l" => "ls" "-a" "-l"
	g_argv[g_argc++] = strtok(commandline, SEP);

	while (g_argv[g_argc++] = strtok(nullptr, SEP));//再次想切的話傳commandline就不對了,再要切歷史字符串就得把它設(shè)為nullptr,再次切的話分隔符依舊是SEP,如果切成了返回的就是下一個字符串的起始地址
	//為什么可以這樣切呢?因?yàn)樵俅吻凶执畷r,它一直切一直切最后就會會變成NULL,切成NULL首先會把g_argv數(shù)組置為NULL,符合命令行參數(shù)表的設(shè)定,NULL也會作為while的條件判斷,最后就直接結(jié)束了
		 //并且g_argc也會統(tǒng)計(jì)出命令行參數(shù)有多少個
	g_argc--;//因?yàn)镹ULL也被統(tǒng)計(jì)到了里面
	return true;
}

 //測試形成的表結(jié)構(gòu)
void PrintArgv()
{
	for (int i = 0; i < g_argc; i++)
	{
		printf("argv[%d]->%s\n", i, g_argv[i]);
	}
	printf("argc:%d", g_argc);
}

5. 執(zhí)行命令

由于我們當(dāng)前的進(jìn)程還有自己的任務(wù),所以我們將執(zhí)行命令交給子進(jìn)程來完成,那么就需要程序替換,execvp

在這里插入圖片描述

//執(zhí)行命令
int Execute()
{
	pid_t id = fork();
	if (id == 0)
	{
		//子進(jìn)程
		execvp(g_argv[0], g_argv);
		exit(1);
	}
	//父進(jìn)程
	pid_t rid = waitpid(id, nullptr, 0);
	return 0;
}

6. 路徑切割

系統(tǒng)的路徑名只有一個,我們自己寫的會跟一長串

在這里插入圖片描述

所以我們對路徑進(jìn)行切割。 C++中有個命令rfind從后向前找,substr截字符串

在這里插入圖片描述

//路徑切割
std::string DirName(const char* pwd)
{
#define SLASH "/"
	std::string dir = pwd;
	if (dir == SLASH) return SLASH;
	auto pos = dir.rfind(SLASH);
	if (pos == std::string::npos) return "BUG";//這里表示沒有找到/
	return dir.substr(pos + 1);
}

7. 解決cd命令路徑不變

到目前我們會發(fā)現(xiàn)我們執(zhí)行cd命令時路徑不發(fā)生改變,因?yàn)槟壳八械拿疃际亲舆M(jìn)程執(zhí)行的,子進(jìn)程改變路徑時改的是自己的pwd,父進(jìn)程bash的環(huán)境變量并沒有改變,我們真正要改的是父進(jìn)程的路徑,因?yàn)榘迅高M(jìn)程的路徑改了往后再創(chuàng)建子進(jìn)程所有的子進(jìn)程就會在新的路徑下執(zhí)行,因?yàn)樗械淖舆M(jìn)程的PCB都是拷貝父進(jìn)程的PCB,因此cd這樣的命令不能讓子進(jìn)程去執(zhí)行,而要讓父進(jìn)程親自執(zhí)行,這種命令叫做內(nèi)建命令如何讓bash親自去執(zhí)行呢?我們先來認(rèn)識一個新的接口chdir

在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

 //處理cd命令
bool cd()
{
	if (g_argc == 1) //表明只是cd,沒有帶任何參數(shù)
	{
		std::string home = GetHome();//將home的路徑拿過來
		if (home.empty())  return true;//如果是空就相當(dāng)于環(huán)境變量獲取失敗了
		chdir(home.c_str());//走到這里不為空,就把當(dāng)前路徑切換成家路徑了
	}
	else
	{
		std::string where = g_argv[1];
		//"cd -" / "cd ~"
		if (where == "-")
		{

		}
		else if (where == "~")
		{

		}
		else
		{
			chdir(where.c_str());
		}
	}
}
 //檢測并處理內(nèi)建命令
bool CheckAndExecBuiltin()
{
	std::string cmd = g_argv[0];
	if (cmd == "cd")//如果是內(nèi)建命令
	{
		cd();
		return true;//是內(nèi)建命令
	}
	return false;//否則不是內(nèi)建命令
}

8. 解決cd后環(huán)境變量未發(fā)生變化

我們再切換路徑后會發(fā)現(xiàn)路徑變了,但是環(huán)境變量中的路徑并沒有變。原因是路徑發(fā)生變化后環(huán)境變量沒有進(jìn)行刷新,所以我們要將新的路徑更新到環(huán)境變量中。這里我們來認(rèn)識一個系統(tǒng)調(diào)用getcwd,獲取當(dāng)前進(jìn)程的工作路徑。

在這里插入圖片描述

在這里插入圖片描述

 //獲取當(dāng)前路徑
const char* GetPwd()
{
	//const char* pwd = getenv("PWD");
	const char* pwd = getcwd(cwd, sizeof(cwd));
	if (pwd != NULL)
	{
		snprintf(cwdenv, sizeof(cwdenv), "PWD=%s", cwd);//獲得環(huán)境變量
		putenv(cwdenv);//將環(huán)境變量導(dǎo)給當(dāng)前進(jìn)程
	}
	return pwd == NULL ? "None" : pwd;
}

9. echo命令

echo命令也是內(nèi)建命令,我們可以用它echo "hello"在屏幕上打印,echo $?查看上個進(jìn)程的退出碼,echo $PATH查看環(huán)境變量。

在這里插入圖片描述

在這里插入圖片描述

//處理echo命令
void Echo()
{
	if (g_argc == 2)//意思是echo后面必須得跟東西
	{
		//echo "heool world"
		   //echo $?
			//echo $PATH
		std::string opt = g_argv[1];
		if (opt == "$?")//輸出上一個程序退出的退出碼
		{
			std::cout << lastcode << std::endl;
			lastcode = 0;//lastcode清零
		}
		else if (opt[0] == '$')//如果第一個字符時是$,那么說明查環(huán)境變量的內(nèi)容了
		{
			std::string env_name = opt.substr(1);//去掉$后的內(nèi)容就是環(huán)境變量的名字
			const char* env_value = getenv(env_name.c_str());
			if (env_value)
				std::cout << env_value << std::endl;
		}
		else
		{
			std::cout << opt << std::endl;
		}
	}
}

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

shell啟動時需要從系統(tǒng)中獲取環(huán)境變量,但是我們還做不到從配置文件中讀,今天我們直接從父shell中拿就可以了,我們自己維護(hù)一張環(huán)境變量表,然后將表導(dǎo)進(jìn)環(huán)境變量空間就行。
我們又用到一個接口environ

在這里插入圖片描述

在這里插入圖片描述

 //初始化環(huán)境變量表
void InitEnv()
{
	extern char** environ;//聲明一個環(huán)境變量所對應(yīng)的信息
	memset(g_env, 0, sizeof(g_env));//將表中的信息全部置為0
	g_envs = 0;

	//本來要從配合文件中來
	//今天從父shell中來
	//1. 獲取環(huán)境變量
	for (int i = 0; environ[i]; i++)
	{
		g_env[i] = (char*)malloc(strlen(environ[i]) + 1);
		//1.2拷貝
		strcpy(g_env[i], environ[i]);//把父進(jìn)程環(huán)境變量里的值拷貝給g_env
		g_envs++;
	}
	g_env[g_envs] = NULL;
	//2.導(dǎo)入環(huán)境變量
	for (int i = 0; g_env[i]; i++)
	{
		putenv(g_env[i]);
	}
	environ = g_env;
	//3.clean清理
}

11. 總結(jié)

用下圖的時間軸來表示事件的發(fā)生次序。其中時間從左向右。shell由標(biāo)識為sh的方塊代表,它隨著時間的流逝從左向右移動。shell從用戶讀入字符串"ls"shell建立一個新的進(jìn)程,然后在那個進(jìn)程中運(yùn)行ls程序并等待那個進(jìn)程結(jié)束。

在這里插入圖片描述

然后shell讀取新的一行輸入,建立一個新的進(jìn)程,在這個進(jìn)程中運(yùn)行程序并等待這個進(jìn)程結(jié)束。所以要寫一個shell,需要循環(huán)以下過程:

  • 獲取命令行
  • 解析命令行
  • 建立?個子進(jìn)程(fork)
  • 替換子進(jìn)程(execvp)
  • 父進(jìn)程等待子進(jìn)程退出(wait)

12.代碼實(shí)現(xiàn)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unordered_map>

#define COMMAND_SIZE 1024 
#define FORMAT "[%s@%s %s]# "
#define MAXARGC 128

//命令行參數(shù)表
char* g_argv[MAXARGC];//全局的命令行參數(shù)表
int g_argc = 0;

//環(huán)境變量表
#define MAX_ENVS 100
char* g_env[MAX_ENVS];//正常情況下shell啟動時應(yīng)該從配置文件中讀取環(huán)境變量來填充這張環(huán)境變量表,也就是說當(dāng)shell啟動時就應(yīng)該拿環(huán)境變量表來初始化它
int g_envs = 0;//環(huán)境變量的個數(shù)

//別名映射表
std::unordered_map<std::string,std::string> alias_list;


//定義一個cwd
char cwd[1024];
char cwdenv[1024];//當(dāng)前工作路徑的env

//最新程序的退出碼 last exit cide
int lastcode = 0;



//獲取用戶名
const char* GetUserName()
{
    const char* name = getenv("USER");
    return name == NULL ? "None" : name;
}

//獲取主機(jī)名
const char* GetHostName()
{
    const char* hostname = getenv("HOSTNAME");
    return hostname == NULL ? "None" : hostname;
}

//獲取當(dāng)前路徑
const char* GetPwd()
{
    //const char* pwd = getenv("PWD");
    const char* pwd = getcwd(cwd,sizeof(cwd));
    if(pwd != NULL)
    {
        snprintf(cwdenv, sizeof(cwdenv), "PWD=%s", cwd);//獲得環(huán)境變量
        putenv(cwdenv);//將環(huán)境變量導(dǎo)給當(dāng)前進(jìn)程
    }
    return pwd == NULL ? "None" : pwd;
}

//獲取家目錄
const char* GetHome()
{
    const char* home = getenv("HOME");
    return home == NULL ? "" : home;
}

//初始化環(huán)境變量表
void InitEnv()
{
    extern char** environ;//聲明一個環(huán)境變量所對應(yīng)的信息
    memset(g_env, 0, sizeof(g_env));//將表中的信息全部置為0
    g_envs = 0;

    //本來要從配合文件中來
    //今天從父shell中來
    //1. 獲取環(huán)境變量
    for(int i = 0;environ[i];i++)
    {
        //1.1申請空間
        g_env[i] = (char*)malloc(strlen(environ[i])+1);
        //1.2拷貝
        strcpy(g_env[i],environ[i]);//把父進(jìn)程環(huán)境變量里的值拷貝給g_env
        g_envs++;
    }
    g_env[g_envs] = NULL;
    //2.導(dǎo)入環(huán)境變量
    for(int i = 0;g_env[i];i++)
    {
        putenv(g_env[i]);
    }
    environ = g_env;
    //3.clean清理
}

//處理cd命令
bool cd()
{
    if(g_argc == 1) //表明只是cd,沒有帶任何參數(shù)
    {
        std::string home = GetHome();//將home的路徑拿過來
        if(home.empty())  return true;//如果是空就相當(dāng)于環(huán)境變量獲取失敗了
        chdir(home.c_str());//走到這里不為空,就把當(dāng)前路徑切換成家路徑了
    }
    else
    {
        std::string where = g_argv[1];
        //"cd -" / "cd ~"
        if(where == "-")
        {
        
        }
        else if(where == "~")
        {
        
        }
        else
        {
            chdir(where.c_str());
        }
    }
    return true;
}

//處理echo命令
void Echo()
{
    if(g_argc == 2)//意思是echo后面必須得跟東西
    {
        //echo "heool world"
        //echo $?
        //echo $PATH
        std::string opt = g_argv[1];
        if(opt == "$?")//輸出上一個程序退出的退出碼
        {
            std::cout << lastcode <<std::endl;
            lastcode = 0;//lastcode清零
        }
        else if(opt[0] == '$')//如果第一個字符時是$,那么說明查環(huán)境變量的內(nèi)容了
        {
            std::string env_name = opt.substr(1);//去掉$后的內(nèi)容就是環(huán)境變量的名字
            const char* env_value = getenv(env_name.c_str());
            if(env_value)
                std::cout << env_value << std::endl;
        }
        else
        {
            std::cout << opt << std::endl;
        }
    }   

}

//路徑切割
std::string DirName(const char* pwd)
{
#define SLASH "/"
    std::string dir = pwd;
    if(dir == SLASH) return SLASH;
    auto pos = dir.rfind(SLASH);
    if(pos == std::string::npos) return "BUG";//這里表示沒有找到/
    return dir.substr(pos+1);
}

//制作命令行提示符
void MakeCommandline(char com_prompt[],int size)
{
    //snprintf(com_prompt, size, FORMAT,GetUserName(),GetHostName(),GetPwd());//我們想讓"[%s@%s %s]# "以后能隨便調(diào)整,所以我們define一下
    snprintf(com_prompt, size, FORMAT,GetUserName(),GetHostName(),DirName(GetPwd()).c_str());//我們想讓"[%s@%s %s]# "以后能隨便調(diào)整,所以我們define一下
}

//打印命令行提示符
void PrintCommandline()
{
    char prompt[COMMAND_SIZE];
    MakeCommandline(prompt,sizeof(prompt));//先制作
    printf("%s",prompt);//再打印
    fflush(stdout);
}

//獲取用戶輸入
bool GetCommandline(char* out,int size)
{
    //"ls -a -l "=>"ls -a -l \n"
    const char *c = fgets(out,size,stdin);//從標(biāo)準(zhǔn)輸入里獲取,放到out當(dāng)中
    if(c == NULL) return 1;
    out[strlen(out)-1] = 0;//清理\n 
    if(strlen(out) == 0) return false; //對于我們用戶來說,有可能獲取到的字符串的長度為0,為0直接return false 
    return true; //否則return true
}

//命令行分析
 bool CommandParse(char* commandline)
{
#define SEP " "
    g_argc = 0; //每次進(jìn)來初始化為0
    //"ls -a -l" => "ls" "-a" "-l"
    g_argv[g_argc++] = strtok(commandline,SEP);
    
   while((bool)(g_argv[g_argc++] = strtok(nullptr,SEP)));//再次想切的話傳commandline就不對了,再要切歷史字符串就得把它設(shè)為nullptr,再次切的話分隔符依舊是SEP,如果切成了返回的就是下一個字符串的起始地址
   //為什么可以這樣切呢?因?yàn)樵俅吻凶执畷r,它一直切一直切最后就會會變成NULL,切成NULL首先會把g_argv數(shù)組置為NULL,符合命令行參數(shù)表的設(shè)定,NULL也會作為while的條件判斷,最后就直接結(jié)束了
   //并且g_argc也會統(tǒng)計(jì)出命令行參數(shù)有多少個
   g_argc--;//因?yàn)镹ULL也被統(tǒng)計(jì)到了里面
   return g_argc > 0 ? true : false;
}

//測試形成的表結(jié)構(gòu)
void PrintArgv()
{
    for(int i = 0;i < g_argc; i++)
    {
        printf("argv[%d]->%s\n",i,g_argv[i]);
    }
    printf("argc:%d\n",g_argc);
}

//檢測并處理內(nèi)建命令
bool CheckAndExecBuiltin()
{
    std::string cmd = g_argv[0];
    if(cmd == "cd")//如果是內(nèi)建命令
    {
        cd(); 
        return true;//是內(nèi)建命令
    }
    else if(cmd == "echo")
    {
        Echo();
        return true;//內(nèi)建命令執(zhí)行完后return true
    }
    else if(cmd == "export")
    {
        
    }
    else if(cmd == "alias")//說明是一個別名
    {
        //std::string nickname = g_argv[1];
       // alisa_list.insert(k,v);
    }
    return false;//否則不是內(nèi)建命令
}

//執(zhí)行命令
int Execute()
{
    pid_t id = fork();
    if(id == 0)
    {
        //子進(jìn)程
        execvp(g_argv[0],g_argv);
        exit(1);
    }
    int status = 0;//退出信息
    //父進(jìn)程
    pid_t rid = waitpid(id, &status, 0);
    if(rid > 0) //說明等成功了
    {
        lastcode = WEXITSTATUS(status);//最后一個進(jìn)程退出的退出碼
    }
    return 0;
}
int main()
{
    //shell啟動時需要從系統(tǒng)中獲取環(huán)境變量
    //我們的環(huán)境變量信息應(yīng)該從父shell中統(tǒng)一來
    InitEnv();


    while(true)
    {
         //printf("[%s@%s %s]# ",GetUserName(),GetHostName(),GetPwd());
         //1. 打印命令行提示符
         PrintCommandline();

         //2.獲取用戶輸入
         char commandline[COMMAND_SIZE];//定義一個數(shù)組
         if(!GetCommandline(commandline,sizeof(commandline)))//如果獲取失敗continue重新獲取
            continue;    
        
         // printf("echo %s\n",commandline);//回顯一下我們輸入的內(nèi)容,用作測試

         //3."ls -a -l" -> "ls" "-a" "-l"
         //命令行分析
         if(!CommandParse(commandline))//分析commandline中的命令行
            continue;//只有解析成功后才往下走,否則就繼續(xù)
         //PrintArgv();

         // 檢查別名 直接將commandline替換成別名

         //4.檢測并處理內(nèi)建命令
         if(CheckAndExecBuiltin())
            continue;//若為內(nèi)建命令就不用創(chuàng)建子進(jìn)程了,由bash親自執(zhí)行
         //5. 執(zhí)行命令
         Execute();

   }
    return 0;
}

到此這篇關(guān)于Linux實(shí)現(xiàn)自主Shell命令行解釋器的文章就介紹到這了,更多相關(guān)Shell命令行解釋器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • 解析Linux?xfs文件系統(tǒng)stat命令Birth字段為空的原因

    解析Linux?xfs文件系統(tǒng)stat命令Birth字段為空的原因

    這篇文章主要介紹了Linux?xfs文件系統(tǒng)stat命令Birth字段為空的原因探究,stat命令在一些平臺下Birth字段有值,而在一些平臺則為空值,這是什么原因呢,下面小編給大家詳細(xì)講解,需要的朋友可以參考下
    2023-05-05
  • Shell文本處理三劍客之sed的使用

    Shell文本處理三劍客之sed的使用

    這篇文章主要介紹了Shell文本處理三劍客之sed的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • Bash的For循環(huán)(根據(jù)每次遞增的數(shù))

    Bash的For循環(huán)(根據(jù)每次遞增的數(shù))

    需要執(zhí)行一個命令,每次消除500個id,通常寫的是遞增1的,記一筆,怕忘了
    2013-08-08
  • Shell編程中Shift的用法小結(jié)

    Shell編程中Shift的用法小結(jié)

    本文給大家分享Shell編程中Shift的用法小結(jié),文末文給大家擴(kuò)展介紹Shell grep 命令擴(kuò)展增強(qiáng)問題分析,感興趣的朋友跟隨小編一起看看吧
    2021-07-07
  • Linux定義變量腳本分享

    Linux定義變量腳本分享

    這篇文章主要為大家詳細(xì)介紹了Linux定義變量的腳本,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • linux啟動dhcp服務(wù)器步驟

    linux啟動dhcp服務(wù)器步驟

    在本篇文章里小編給大家整理了關(guān)于linux怎么啟動dhcp服務(wù)器的相關(guān)知識點(diǎn)內(nèi)容,需要的朋友們跟著學(xué)習(xí)下。
    2019-05-05
  • 如何使用 Shell 腳本執(zhí)行 .NET Core 應(yīng)用

    如何使用 Shell 腳本執(zhí)行 .NET Core 應(yīng)用

    這篇文章主要介紹了如何使用 Shell 腳本執(zhí)行 .NET Core 應(yīng)用,幫助大家更好的理解和使用shell 腳本,感興趣的朋友可以了解下
    2020-09-09
  • linux打包某個可執(zhí)行文件及其依賴文件

    linux打包某個可執(zhí)行文件及其依賴文件

    這篇文章主要為大家詳細(xì)介紹了如何通過linux打包某個可執(zhí)行文件及其依賴文件,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟了解一下
    2024-12-12
  • Linux中10個方便的Bash別名

    Linux中10個方便的Bash別名

    今天小編就為大家分享一篇關(guān)于Linux中10個方便的Bash別名,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-09-09
  • 使用Linux shell腳本實(shí)現(xiàn)FTP定時執(zhí)行批量下載指定文件

    使用Linux shell腳本實(shí)現(xiàn)FTP定時執(zhí)行批量下載指定文件

    使用FTP定時批量下載指定文件的shell腳本,具體實(shí)例介紹如下所示,需要的朋友參考下吧
    2017-04-04

最新評論