为什么输入指令就可以执行,而自己的写的程序要./才可以执行?
在操作系统执行指令的时候,系统会去环境变量里面的路径PATH去找对应的可执行程序,如下图:打印出来打的路径就是我们系统中存放路径的环境变量,所以linux的基本指令的路径添加到环境变量里面去了,而我们写的可执行程序在本地路径中我们的程序这需要指定路径。
进程的工作路径
我们可以查看对应进程的目录,如图:
进程其实就是可执行程序,在每一个程序运行时,都会在linux的/proc生成对应pid(j进程id)的目录,在该目录中记录了该进程的工作路径,所以这也解释了为什么我们在C语言中fopen打开文件的时候会在我们的工作目录中新建文件。
如何创建环境变量?
export 变量名 = 变量值 (添加环境变量)
unset 变量名 (去掉环境变量)
echo $本地变量名–输出本地变量
把当前路径添加到PATH环境变量里面
这样会把PATH里面原本的内容覆盖掉,导致之前指令就不要用了,导致之前的bin目录、sbin目录的命令都不能用呢?
要在PATH= $PATH:当前路径,才可以添加
我覆盖了环境变量,在环境变量PATH中没有了usr/bin/pwd,但是我为什么pwd还能使用呢?
我们通过env指令输出该进程的环境变量,可以发现里面有个PWD的环境变量,这个环境变量就是用于记录当前进程的工作路径的,所以也解释了为什么PATH环境变量被覆盖了但是pwd依然可以使用。
总结:linux常用的环境变量?以及他们的含义
PATH : 指定命令的搜索路径
HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
PWD:记录当前进程的工作路径的
SHELL : 当前Shell,它的值通常是/bin/bash
SSH TTY:记录当前的终端路径
OLDPWD:当前路径的上一次的路径
USER:用户名
LOGNAME:
环境变量与用户权限
getenv函数
使用:传入环境变量的名字,返回对于的环境变量的值
在这段代码中,我通过getenv这个函数获取了环境变量user的值,而user环境变量是用来记录当前bash的用户的,然后我再根据不同的值去做逻辑判断,在linux实现权限也是这个逻辑。
为什么要给main函数传参?
在一些C语言代码中,他们会给main函数传参如图:
argc记录的是argv中的char指针个数,argv是一个char 的指针数组
argv里面存的是什么呢?
存的是我们在执行这个可执行文件的时候,输入的字符串,比如:ls -l -a这样子,但是他argv[]存储的方式是将一个字符串按照空格划分,分成若干个字符串存放在里面。
为什么要这样做呢?
示例代码:
#include <stdio.h>
#include <string.h>
int main(int argc,char* argv[])
{
if(argc == 1)
{
printf("功能1\n");
}
switch(argc)
{
case 2:
if(strcmp("-a",argv[1])==0)
{
printf("功能a\n");
}
else if(strcmp("-b",argv[1])==0)
{
printf("功能b\n");
}
else if(strcmp("-c",argv[1])==0)
{
printf("功能c\n");
}
else if(strcmp("-d",argv[1])==0)
{
printf("功能d\n");
}
else if(strcmp("--help",argv[1])==0)
{
printf("Usage:%s -[a|b|c|d]\n",argv[0]);
}
break;
default:
break;
}
return 0;
}
在这个代码实现了根据不同选项输出不同的值
main函数还可以接受环境变量向量表的传参
参考程序:
#include <stdio.h>
int main(int argc,char* argv[],char* env[])
{
int i = 0;
for(;env[i];i++)
{
printf("env[%d]->%s\n",i,env[i]);
}
return 0;
}
调用该程序一样可以输出所有的环境变量
**细节补充:
1.在程序执行时,编译器会通过一个函数去调用main函数给main函数传参,才会获取这两张表的信息,而我们执行的可执行程序是bash的子进程,而这也间接的表述了环境变量是可以通过父进程继承到子进程的
2.我们不接收main函数这三个参数的时候为什么不会报错呢?
编译器会对你的main函数有没有参数做条件编译,如果你有写参数,编译器会给你使用有参数的 Startup()或者CRTStartup()
**
总结——main函数可以接受两个向量表:1.命令行参数表 2.环境变量表
向量表结构图示:
命令行参数表的作用:为指令、工具,软件等提供命令行选项的支持
本地变量与内建命令
set指令:可以查到本系统内的所有变量,包括本地变量和环境变量
本地变量不会像环境变量那样被子进程继承只会在本地的bash中有用,本地变量的作用域仅限于定义它们的函数内部。当函数执行完毕后,这些本地变量就会被销毁,不再存在。但是,如果你在 Bash 命令行界面(CLI)中定义了一个本地变量,那么这个变量会在你关闭终端或者退出当前的 shell 会话时被销毁。
echo是bash的子进程,那为什么echo可以获取到本地变量并且对他进行输出呢?因为echo是内建命令
两批命令:
1.常规命令 – 通过创建子进程完成的
2.内建命令 – bash不创建子进程,而是由自己亲自执行,类似于bash调用了自己写的,或者系统提供的函数
chdir函数
相似的内置命令还有cd 对于cd而言,如果创建子进程去执行的话,那么父进程是不会被改变的,但是cd命令直接修改当前bash的路径位置,所以他是一个内置命令。
为什么没有发生变化呢?是因为在main函数中创建了子进程,子进程不能改变父进程的数据,所以没有发生改变。
environ外部变量
是一个指向环境变量表的指针,可以通过该指针找到环境变量。
总结:环境变量的知识点
- 环境变量是系统提供的一组name=value形式的变量
- 环境变量可以被子进程继承,所以通常具有全局属性