命令行参数
main 函数⼀共有三个参数,在命令行部分先关注前两个参数:
1、argc:表示命令行参数的个数
2、argv:表示命令行参数的清单
根据下⾯的代码观察这两个参数具体的效果:
#include <stdio.h>int main(int argc, char* argv[]) {printf("%d\n", argc);for(int i = 0; i < argc; i++) {printf("%s\n", argv[i]);}
}
这里我们可以看到命令行,argc中显示的参数个数,argv命令行参数的清单内容
为什么要有这两个参数呢?
因为同一个程序,可以根据命令行参数,根据选项的不同,表现出不同的功能。
就比如常用指令ls -a,ls -d。
#include <stdio.h>
#include <string.h>int main(int argc, char *argv[])
{if (argc != 2){printf("Usage: code opt\n");return 1;}if (strcmp(argv[1], "-opt1") == 0)printf("功能1\n");else if (strcmp(argv[1], "-opt2") == 0)printf("功能2\n");else if (strcmp(argv[1], "-opt3") == 0)printf("功能3\n");elseprintf("默认功能\n");return 0;
}
main函数的参数是谁给传递的呢?
在命令行解释器上进行输入指令加选项,他是字符串,首先会被shell拿到,根据空格为分隔符进行打散,形成一张表argv[]和元素个数argc。
那么在命令行上启动的程序,父进程都是谁?shell
启动的进程与shell都是父子关系。子进程会继承父进程,对于只读数据,如果不做修改,那么子进程没必要拷贝,直接可以跟父进程共享,所以,命令行参数被打散形成的表,后面就不会被修改,所以子进程也可以看到。然后子进程把他们传递给main函数就可以了。
环境变量
第三个参数就是 char *env[]----->环境变量。
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;
}
a、常见的环境变量
echo:显示某个环境变量值
查看环境变量方法:
- echo $NAME //NAME:你的环境变量名称
1.PATH :
PATH:指定命令的搜索路径
echo $PATH查看PATH环境变量
如上图,PATH是个路径集合,系统可执行文件的搜索集合。
为什么系统的默认程序不需要./而自己写的程序需要加./ ?
因为PATH环境变量,告诉了shell,应该去哪个路径下查指令。
另外,如果我不想带路径,如何让我的程序不带./运行起来?
1.cp到PATH的某个路径中。
2.把自己的路径,添加到PATH中!
如果想修改路径不能这种覆盖式写。这样会导致系统丢失之前的路径。
不过也不用担心重启一下就好了,如果想追加路径那么如何写?
PATH=$PATH:路径
当我们再次关掉shell,我们发现添加的路径没了?
为什么???
因为环境变量是内存级的,是被加载到bash进程内,子进程继承环境变量,子进程修改不会改变父进程内容,关闭重新登陆shell,子进程就可以重新继承bash里面环境变量。
那么如何修改???
环境变量,开始都在系统配置文件中的。
要想永久的更改PATH,先要找到配置文件,在家目录就会存在两个配置文件 .bash_profire和 .bashrc 。
把自己的路径添加到配置文件中,就可以直接像指令使用自己的程序了。
当路径添加到配置文件中,使用指令source
指令source:在shell环境中,用于在当前环境中加载和执行脚本或配置文件。
2.HOME:
HOME:指定用户的主工作⽬录(即用户登陆到Linux系统中时,默认的⽬录)
那么是默认就在家目录里,再设置的环境变量,还是默认先读环境变量,再把当前用户设置再家目录下?
当我们在登录的时候,系统首先给我们用户创建对应的bash来给我们做准备,bash读取环境变量相关的配置文件,读取配置文件的本质就是要配置他自己的环境变量,bash也是一个进程,也要有cwd。bash的cwd设置为我们读到的HOME环境变量。
3.SHELL:
SHELL:当前Shell,它的值通常是/bin/bash。
本质记录登录了哪个shell
4.PWD:
PWD:保存当前进程所在的工作路径
5.USER
USER:表示当前使用系统的用户是谁
可以通过获取USER,意味着可以让我的子程序,识别用户身份,如果不是目标用户就不能使用该程序,是该目标用户才能使用该程序。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>int main()
{//可以让我的程序只能我运行,其他人用不了const char *who = getenv("USER");if(strcmp(who, "zxw") == 0){printf("执行程序的正常命令\n");return 0;}else{printf("无权访问\n");return 1;}return 0;
}
6.OLDPWD
OLDPWD:切换路径后,保存上一次所在的路径
本地变量
当我们查看env的时候没有发现,a,b,c。abc放在哪了?放到了本地变量。
我们可以使用set来同时查看本地变量与环境变量
我们可以使用export系统指令把本地变量更改为环境变量
export a或者当然我们也可以export a=100直接导入环境变量中
系统指令unset:清除环境变量
如果我们想清除环境变量的a=100,我们可以使用unset a,这样就可以把环境变量清除掉。
下面代码生成的可执行程序为bash的子进程:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>int main()
{//先设置本地变量ISRUNNING,然后export设置为环境变量char *isrunning = getenv("ISRUNNING");if (isrunning == NULL){while (1){printf("当前进程首次启动!\n");sleep(1);}}else{printf("当前进程已经运行了,不需要再启动了!\n");}return 0;
}
如果设置为本地环境,还是首次启动。
如果设置为环境变量,就可以不启动了。
这里想说明,环境变量可以被子进程继承下去的,而本地变量不能!
环境变量可以被子进程继承下去,环境变量可以被所有bash之后的进程全部看见,所以环境变量具有“全局”属性。
通过代码如何获取环境变量
1. main函数的第三个参数,env
2.environ//char **environ,这个二级指针指向的是env
#include <stdio.h>
int main(int argc, char *argv[])
{extern char **environ;int i = 0;for(; environ[i]; i++){printf("%s\n", environ[i]);}return 0;
}
通过系统调⽤获取或设置环境变量:系统函数getenv
#include<stdio.h>
#include<stdlib.h>int main()
{printf("%s\n",getenv("PWD"));return 0;
}
putenv ,后⾯讲解