当前位置: 首页 > article >正文

【LInux进程六】命令行参数和环境变量

【LInux进程六】命令行参数和环境变量

  • 1.main函数的两个参数
  • 2.利用main函数实现一个简单的计算器
  • 3.环境变量之一:PATH
  • 4.修改PATH
  • 5.在命令行解释器bash中查看所有环境变量
  • 6.用自己写的程序查看环境变量
  • 7.main函数的第三个参数
  • 8.本地的环境变量和环境变量
  • 9.环境变量具有全局性
  • 10.内建命令与常规命令

1.main函数的两个参数

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

这两个参数又被称为命令行参数
char* argv[]是一个指针数组,包含的每个指针分别指向不同的字符串
int argc代表这个数组的元素个数(指针的数量)

通过下面的代码查看argv数组中存放的是什么字符串:

#include<stdio.h>      
int main(int argc,char* argv[])    
{    
    int i=0;                                                                                                                                                            
    for(i=0;i<argc;i++)    
    {    
        printf("%d: %s\n",i,argv[i]);    
    }    
    return 0;    
}   

在这里插入图片描述

当我们运行可执行程序mybin时,它会打印0: ./a.out
当我们以空格为分割在./mybin后面继续输入任意字符串时,它会以空格为分割,分别打印出数组中下标为0,1,2的字符串,这些输出的字符串正是我们所输入的
将命令行输入的字符串放入argv数组是操作系统所为

请添加图片描述

2.利用main函数实现一个简单的计算器

#include<stdio.h>    
#include<string.h>    
#include<stdlib.h>    

int main(int argc,char* argv[])    
{    
    if(argc != 4)    
    {    
        printf("%s Option:[add|sub|mul|div] num1 num2\n",argv[0]);    
        return 1;    
    }    
    
    int x = atoi(argv[2]);    
    int y = atoi(argv[3]); 
       
    if(strcmp(argv[1],"add") == 0)    
        printf("%d + %d = %d\n",x,y,x + y);    
    else if(strcmp(argv[1],"sub") == 0)    
        printf("%d - %d = %d\n",x,y,x - y);    
    else if(strcmp(argv[1],"mul") == 0)    
        printf("%d * %d = %d\n",x,y,x * y);    
    else if(strcmp(argv[1],"div") == 0)                                                                                                                                   
        printf("%d / %d = %d\n",x,y,x / y);    
    else    
        printf("输入操作符错误");    
    return 0;    
}    

在这里插入图片描述

3.环境变量之一:PATH

让我们思考几个问题:

  1. 为什么我们自己写的程序运行时要加./
  2. 但是系统中的指令:ls,pwd等不用加./?
  3. 我们自己写的指令能不能不加./?

我们自己写的程序要加上./的本质就是让操作系统在当前目录下寻找我们写的程序

保存程序的默认搜索路径的就是环境变量,叫做: PATH
查看环境变量PATH的指令:echo $PATH
在这里插入图片描述
这些路径以冒号:为分割
因为我们自己写的程序不在这些路径中,所以我们需要加上./来运行程序

4.修改PATH

要想我们的指令像系统指令一样不加./就能运行,我们可以将自己写的程序的路径加入到环境变量PATH中
使用指令:PATH=$PATH:要添加的路径
请添加图片描述
在这里插入图片描述

下次重启时又会恢复为默认路径,因为操作系统在登陆时会执行以下步骤:

  1. 认证用户名和密码是否正确
  2. 形成环境变量(PATH,PWD,HOME等)
  3. 根据用户名初始化HOME=/root或者HOME=/home/xxx
  4. cd $HOME(进入到自己的环境变量)

5.在命令行解释器bash中查看所有环境变量

指令:env
在这里插入图片描述
环境变量:

  1. PWD:记录当前路径,指令pwd就是调用了PWD这个环境变量在这里插入图片描述

  2. HOME:进入家目录指令:cd ~,环境变量HOME里面的内容就是家目录的位置在这里插入图片描述

6.用自己写的程序查看环境变量

使用函数:getenv()

char*  = NULL;
ret = getenv("PATH");//获取环境变量PATH

7.main函数的第三个参数

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

第三个char* env[]是指针数组,指向了一张环境变量表,打印出来的内容和使用指令env查看的内容是一样的

查看环境变量表

#include<stdio.h>
int main(int argc,char* argv[],char* env[])
{
	for(int i=0;env[i]!=NULL;i++)
	{
		printf("[%d]: %s"\n,i,env[i]);
	}
	return 0;
}

在这里插入图片描述
系统会给main函数提供两张表:

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

8.本地的环境变量和环境变量

我们可以在命令行解释器bash中直接定义环境变量
指令:自己取的变量名=变量内容(=前后不能有空格)
echo $变量名指令用来打印变量
在这里插入图片描述
用户自己定义的环境变量就是本地的环境变量
用指令:env在bash中无法查找到刚才定义的本地的环境变量,因为本地变量不在环境变量表
在这里插入图片描述
使用指令:export 本地环境变量名或者export 自己取的变量名=变量内容可以把本地环境变量加入环境变量表

在这里插入图片描述

9.环境变量具有全局性

每次重新启动bash后,我们自己定义或修改的环境变量就不见了
因为我们修改的环境变量表是bash内部的,每一次重新登陆账号都会依照家目录下的.bash_profile文件中的内容重新生成命令行解释器bash
想要定义或修改被保存下来,就要把环境变量保存在家目录中的配置文件.bash_profile中(也可能是.profile文件)
在这里插入图片描述

命令行启动的进程都是shell和bash的子进程,子进程的命令行参数和环境变量都是父进程传递的
所以命令行参数表会通过main函数的参数从父进程传递给子进程

本地变量 VS 环境变量

  1. 本地变量只在bash进程内部有效,不会被子进程继承
  2. 环境变量通过让所有子进程继承的方式,实现自身的全局性

10.内建命令与常规命令

bash中的指令可以直接使用而不用加./去寻找路径,是因为它的
路径在环境变量的PATH中
当我们把环境变量中的PATH置空后,lsll指令都无法使用,但pwdecho依然正常
在这里插入图片描述

因为Linux下的指令分为两种:

  1. 常规命令:由bash创建的子进程执行的
  2. 内置命令:由bash自己执行的(父进程内部执行)

而pwd和echo就是内置命令

当我们定义的本地变量没有放入环境变量表中时,命令env都找不到这个本地变量,而命令echo却能获取到本地变量的信息,正是因为echo是内建命令,是由父进程自己执行的,echo它可以看见父进程的变化,子进程不能接受父进程的本地变量,所以由子进程执行的常规命令env获取不到本地变量的信息(命令行启动的进程都是shell和bash的子进程,而内置命令是由bash自己执行的),直到本地变量放入具有全局性的环境变量表中,由子进程继承该环境变量表中才能使用命令env查看到
在这里插入图片描述


http://www.kler.cn/a/591332.html

相关文章:

  • 【大模型基础_毛玉仁】2.6 非 Transformer 架构
  • SSH后判断当前服务器是云主机、物理机、虚拟机、docker环境
  • 谈谈 TypeScript 中的模块系统,如何使用 ES Modules 和 CommonJS 模块?
  • STM32---FreeRTOS内存管理实验
  • 剑指 Offer II 109. 开密码锁
  • 【go】soilid与设计模式
  • 【Leetcode】203.移除链表元素
  • MyBatis 如何创建 SqlSession 对象的?
  • 手抖护理指南:全方位守护患者生活
  • 华为ISC+战略规划项目数字化转型驱动的智慧供应链革新(169页PPT)(文末有下载方式)
  • 为什么Django能有效防御CSRF攻击?
  • 爬虫基础之爬取猫眼Top100 可视化
  • Qt之自定义界面组件 一
  • 地宫取宝---dfs‘记忆
  • Python核心:Django鉴权方案全解析
  • Android第四次面试总结(基础算法篇)
  • SpringCloud 学习笔记2(Nacos)
  • 实验9-2 高级搜索技术2
  • browser-use WebUI + DeepSeek 基于AI的UI自动化解决方案
  • 苹果宣布iOS 19将支持RCS 3.0,短信功能迎来大升级