【Linux】命令行参数和环境变量

一.理解什么是上下文数据

并发

并发: 多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发。

我们知道一个进程在cpu上执行了一段时间之后,即使没有执行完,也会被剥离下来,我们把这称为基于进程切换基于时间片轮转的调度算法

几个问题

1.为什么函数的返回值会被外部拿到呢?

答:返回的时候会保存到寄存器里,通过CPU的寄存器拿到数据

        当返回的数据很大时,会用多个寄存器保存。

2.系统如何得知代码执行到第几行了?

答:通过程序计数器pc(也叫eip)

        程序计数器:记录当前进程正在执行指令的下一行指令的地址

其实CPU中有很多寄存器,例如通用寄存器(eax,ebx),记录栈帧的(ebp,esp,eip),状态寄存器(status);

那么这些寄存器都有什么作用呢?

答:提高效率,进程高频数据会放入寄存器中;也就是说,CPU内的寄存器保存的是,进程相关的数据,而这些数据被称为上下文

上下文作用

        进程在从CPU上离开的时候,要将自己的上下文数据保存好,甚至带走,其目的是为了下次运行此进程时能够恢复,否则每次都从头开始运行,效率太低了。

        上下文会存在进程的PCB中。

进程切换时:

  1. 保存上下文
  2. 恢复上下文

二.命令行参数

在初学C语言的时候,可能在一些书籍上会看到main函数带参数,就像这样

int main(int argc,char*argv[])
{
    //....
    return 0;
}

这个argv是一个整型,argc表示argv指针数组的大小

那这些参数有什么用呢?

我们知道其实代码在执行时,第一个调用的函数不是main函数,所以是可以给main函数传参的

在来看下面这一段代码:

#include <stdio.h>

int main(int argc,char*argv[])
{
    for(int i=0;argv[i];i++)
    {
        printf("argv[%d]->%s\n",i,argv[i]);
    }
    
    return 0;
}

运行结果:

其实  "./mycmd -a -b -c  -d" 被当成一个字符串,以空格为分隔,被分成了五个字符串,然后再依次填入argv指针数组中,最后一个位置的下一个位置再填成空指针

那么这有什么用呢?

我们平常使用的那些指令,例如 ls 什么的,它们后面跟不同的选项,就会有不同的功能,原理就是这个命令行参数。

例:

int main(int argc,char*argv[])
{

    if(argc==2)
    {
       if(strcmp(argv[1],"-a")==0)                                                                                                           
              printf("功能1\n");
       else if(strcmp(argv[1],"-b")==0)
              printf("功能2\n");
       else if(strcmp(argv[1],"-c")==0)
              printf("功能3\n");
       else if(strcmp(argv[1],"-d")==0)
              printf("功能4\n");
       else
              printf("default\n");
      }
      else
          printf("mycmd -> [-a|-b|-c|-d]\n");

     return 0;
}


三.环境变量

是什么

环境变量是系统提供的一组name=value形式的变量,不同的环境变量有不用的用途,通常具有全局性和可继承性

我们所运行的进程,都是bash的子进程,bash本身在启动的时候,会从操作系统的配置文件中读取相关环境变量的信息子进程会继承父进程交给我的环境变量

下面让我们来认识几个环境变量

PATH

PATH : 指定命令的搜索路径

我们在使用ls这些命令时,并不需要带路径,而使用我们自己写的就要带路径,这是为什么呢?

这就跟PATH环境变量有关了。

使用下面命令,查看PATH环境变量

echo $PATH   //$符号用于提取环境变量的值,否则只是单纯的打印PATH

 可以看到,这一串用 " : " 分隔开的路径,就是系统寻找命令的路径,我们可以把当前路径添加进PATH,这样我们自己写的也可以不带路径直接使用了。

不过这个PATH是内存性质的,如果不小心改错了,也不用担心,重新登陆 xshell 就行了。

 HOME

HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)

echo $HOME

 SHELL

SHELL : 当前Shell,它的值通常是/bin/bash

echo $SHELL

 本地变量

NAME=value   //像这样设置的就是本地变量,注意 = 号两边不能有空格

 本地变量只在bash本地有效,不可以被继承。

环境变量相关命令

  1. echo: 显示某个环境变量值
  2. export: 设置一个新的环境变量,可以将本地变量导入变成环境变量
  3. env: 显示所有环境变量(无法显示本地变量)
  4. unset: 清除环境变量
  5. set: 显示本地定义的shell变量和环境变量(即显示本地变量和环境变量)

环境变量的组织方式

环境变量的组织方式和命令行参数是一样的。

所以一个进程在运行时,不是简单的加载到内存中,还会传入两张核心向量表:

  1. 命令行参数表
  2. 环境变量表

通过代码如何获取环境变量

函数getenv

#include <stdio.h>
#include <unistd.h>

int main()
{
    printf("PATH:%s\n",getenv("PATH"));
    return  0;
}

命令行第三个参数

其实main函数还能传第三个参数:char *env[]

#include <stdio.h>

int main(int argc, char* argv[], char* env[])
{
	for (int i = 0; env[i]; i++)
	{
		printf("env[%d]->%s\n", i, env[i]);
	}

	return 0;
}

 由于很长,这里只截一部分

 通过第三方变量environ获取

#include <stdio.h>

int main()
{
    extern char**environ;  //注意要先声明一下

    for(int i=0;environ[i];i++)
    {
        printf("environ[%d]->%s\n",i,environ[i]);
    }

    return 0;
}

内建命令

 这里发生了一个奇怪的现象,MY_VALUE是本地变量,为什么可以用echo命令打印出来?

执行命令时,bash要创建子进程,那么它运行的时候要创建子进程吗?

如果需要创建子进程,那么因为本地变量不会被继承,也就不会被打印出来,可事实并非如此。

其实命令分为两批:

  1. 常规命令:通过创建子进程完成的;
  2. 内建命令:bash不创建子进程,而是由自己亲自执行,类似于bash调用了自己写的,或是系统提供的函数。

echo就是一个典型的内建命令,类似的还有 cd 命令


🐬🤖本篇文章到此就结束了, 若有错误或是建议的话,欢迎小伙伴们指出;🕊️👻

😄😆希望小伙伴们能支持支持博主啊,你们的支持对我很重要哦;🥰🤩

😍😁谢谢你的阅读。😸😼

  • 18
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 29
    评论
评论 29
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值