环境变量是Linux系统中用于存储系统和工作环境信息的动态值,它们影响系统进程和程序的行为。
我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但 是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数 如: 环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性
概念
环境变量是存储在系统中的键值对(name=value形式),具有以下特点:
全局或会话级作用域
通常为大写字母命名
可以被所有子进程继承
常见环境变量
1. 核心环境变量
变量名 | 用途描述 |
---|---|
PATH | 指定可执行程序的搜索路径 |
HOME | 当前用户的主目录路径 |
USER | 当前用户名 |
SHELL | 当前使用的shell程序路径 |
PWD | 当前工作目录 |
OLDPWD | 上一次的工作目录 |
LANG | 系统语言和字符编码设置 |
TERM | 终端类型 |
EDITOR | 默认文本编辑器 |
PS1 | 主提示符字符串,定义命令行提示符的显示格式 |
PATH
PATH天然存在,echo $PATH搜索路径,显示的是当前用户的可执行程序搜索路径。当你在终端输入一个命令时,系统会按照
PATH
变量中定义的目录顺序依次查找对应的可执行文件。PATH是一个由
:
分隔的目录列表,系统会在这些目录中查找你输入的命令对应的可执行文件(二进制程序、脚本等)
系统会按从左到右的顺序依次查找这些目录,一旦找到匹配的可执行文件,就会执行它,不再继续向后查找 ,如果找不到,返回“command not found”错误。
如果我们执行自己写的程序时不想带路径,有两种方法:
1将我们的程序拷贝到(echo $PATH查看)路径的某一个中(一般是/user/bin)。
2. 将程序的路径添加到PATH中
HOME
root和普通用户有所区别
和环境变量相关的命令
1. echo: 显示某个环境变量值
2. export: 设置一个新的环境变量
3. env: 显示所有环境变量
4. unset: 清除环境变量
5. set: 显示本地定义的shell变量和环境变量
env
查看所有环境变量
环境变量表
每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串
命令行参数
命令行参数是程序运行时从命令行接收的输入数据,它是控制程序行为的常用方式。
main函数的参数叫做命令行参数列表,其中,argc是参数的个数,argv[]是参数的清单。命令行参数列表的作用就是使同一个程序,能够根据命令行参数的不同,表现出不同的功能
#include <stdio.h> int main(int argc, char *argv[]) { printf("程序接收到 %d 个参数:\n", argc); for(int i = 0; i < argc; i++) { printf("argv[%d] = %s\n", i, argv[i]); } return 0; }
![]()
argc
(argument count):参数个数,包括程序名本身
argv
(argument vector):参数数组,每个元素是一个字符串
常见问题:
argc和argv从哪里来?
由操作系统在程序启动时填充
Shell负责解析命令行并构建参数数组
为什么argv[0]是程序名?
这是Unix/Linux的惯例
可用于确定程序被调用的名称
如何处理带空格的参数?
用引号包裹:
./program "hello world"
argv会将其作为一个参数传递
添加环境变量
将我们自己程序的路径添加到PATH中。
添加方法如下:PATH=$PATH:路径
我们现在查看和修改的这个PATH其实是内存级别,只要退出当前登录后再重新登录,shell就会重新加载一个环境变量。我们之前对它做过的修改就会消失。
内存级环境变量在shell中保存,shell不存在时,在系统配置文件中存好了
PATH最开始的内容是从哪里来?
环境变量开始都是在系统的配置文件中的,当我们登录时,会启动一个shell程序,shell程序会读取用户和系统相关的环境变量的配置文件,形成自己的环境变量表。然后shell进程和它所创建的子进程都是可以看见这个环境变量表的。
本地变量和环境变量
本地变量是仅在当前Shell会话中有效的变量,不会传递给子进程。(前加export变成环境变量)(export -n var1 指令变回本地变量)
本地变量只会在本bash内部有效,不会被继承
环境变量是数据,默认父子共享,但进程有独立性,修改子进程不能影响父进程(写时拷贝),无子进程先创建好了环境变量会被子进程继承下去。
指令是bash子进程
指令运行时要创建子进程,新写的可执行程序只能集成环境变量(不能集成本地变量)
我们可以直接 使用"变量名=值" 的形式定义本地变量
查看所有变量 (包括本地变量)
set
unset
删除变量
PSI
代表显示命令行格式
内建命令
常规命令要创建子进程但是内建命令不需要
内建命令不需要创建子进程(不用环境变量)直接调用即可
例子:cd
cd修改子进程路径时父进程路径会受到影响
通过代码获取环境变量
1.命令行第三个参数
#include <stdio.h>
int main(int argc, char *argv[], char *env[])
{
int i = 0;
for(; env[i]; i++){
printf("%s\n", env[i]);
}
return 0;
}
2.通过第三方变量environ获取
#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;
}
通过系统调用获取或设置环境变量
1.putenv
2.getenv:获取指定名称的环境变量值。
getenv:
#include <stdio.h>
#include <stdlib.h>
int main() {
char *path = getenv("PATH");
if (path != NULL) {
printf("PATH: %s\n", path);
} else {
printf("PATH not found\n");
}
return 0;
}
PATH: /usr/local/bin:/usr/bin:/bin
环境变量的全局属性
环境变量通常具有全局属性,可以被子进程继承下去
要加export(在本地变量与环境变量可见)
未导出的变量仅存在于 Shell 进程的私有内存中,不会写入环境变量表。
进程通过
fork()
+exec()
创建时,只能继承父进程的 环境变量,无法访问父进程的本地变量。避免子进程意外访问父进程的临时数据。
允许进程通过
export
选择性地共享配置。