【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
让我们思考几个问题:
- 为什么我们自己写的程序运行时要加
./ - 但是系统中的指令:ls,pwd等不用加
./? - 我们自己写的指令能不能不加
./?
我们自己写的程序要加上
./的本质就是让操作系统在当前目录下寻找我们写的程序
保存程序的默认搜索路径的就是环境变量,叫做: PATH
查看环境变量PATH的指令:echo $PATH

这些路径以冒号:为分割
因为我们自己写的程序不在这些路径中,所以我们需要加上./来运行程序
4.修改PATH
要想我们的指令像系统指令一样不加./就能运行,我们可以将自己写的程序的路径加入到环境变量PATH中
使用指令:PATH=$PATH:要添加的路径


下次重启时又会恢复为默认路径,因为操作系统在登陆时会执行以下步骤:
- 认证用户名和密码是否正确
- 形成环境变量(PATH,PWD,HOME等)
- 根据用户名初始化HOME=/root或者HOME=/home/xxx
cd $HOME(进入到自己的环境变量)
5.在命令行解释器bash中查看所有环境变量
指令:env

环境变量:
-
PWD:记录当前路径,指令
pwd就是调用了PWD这个环境变量
-
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函数提供两张表:
- 命令行参数表
- 环境变量表enü
8.本地的环境变量和环境变量
我们可以在命令行解释器bash中直接定义环境变量
指令:自己取的变量名=变量内容(=前后不能有空格)
echo $变量名指令用来打印变量

用户自己定义的环境变量就是本地的环境变量
用指令:env在bash中无法查找到刚才定义的本地的环境变量,因为本地变量不在环境变量表中

使用指令:export 本地环境变量名或者export 自己取的变量名=变量内容可以把本地环境变量加入环境变量表中

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

命令行启动的进程都是shell和bash的子进程,子进程的命令行参数和环境变量都是父进程传递的
所以命令行参数表会通过main函数的参数从父进程传递给子进程
本地变量 VS 环境变量
- 本地变量只在bash进程内部有效,不会被子进程继承
- 环境变量通过让所有子进程继承的方式,实现自身的全局性
10.内建命令与常规命令
bash中的指令可以直接使用而不用加./去寻找路径,是因为它的
路径在环境变量的PATH中
当我们把环境变量中的PATH置空后,ls和ll指令都无法使用,但pwd和echo依然正常

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

