目录
环境变量类型
查看环境变量
环境变量原理
环境变量类型
环境变量是进程中一组变量信息,环境变量分为系统环境变量、用户环境变量和进程环境变量。系统有全局的环境变量,在进程创建时,进程继承了系统的全局环境变量、当前登录用户的用户环境变量和父进程的环境变量。进程也可以有自己的环境变量。
查看环境变量
shell 中获取环境变量
printenv
env
echo $环境变量名命 查看单个环境变量
printenv、env 不能显示进程中用setenv创建的环境变量
查看进程的环境变量
cat /proc/$PID/environ
环境变量以name=value的形式来描述,彼此之间由null字符(\0)分割。可以将\0替换成\n,方便查看:
cat /proc/$PID/environ | tr '\0' '\n'pr
(发现cat /proc/$PID/environ 并不能显示进程中用setenv创建的环境变量)
系统的环境变量
使用 env
或者 set 命令可以查看系统当前的环境变量;
进程的环境变量
在 Linux 系统下面,进程的环境变量来自于两部分:
1)进程初始化时由加载器载入的环境变量(来自于系统、父进程或者 exec 系统调用的参数)
2)和进程执行过程中由 setenv 函数动态设置或修改的环境变量。
初始化时载入的环境变量
进程初始化时由加载器载入的环境变量信息可以通过 /proc/<pid>/environ 文件查看:
$ cat /proc/<pid>/environ
该命令的输出格式不太容易读,所有的信息挤在了同一行。使用 tr 命令将空字符替换为换行符,将会使所有的环境变量按行显示:
$ cat /proc/<pid>/environ | tr "\\0" "\\n"
或者
$ cat /proc/<pid>/environ | tr '\0' '\n'
执行过程中设置的环境变量
进程的环境变量保存在全局变量 char **__environ
中。要想显示由进程动态修改的环境变量,首先必须有这个进程的符号表,然后通过 ptrace
系统调用(比如使用 gdb)来查看。
比如 gbd -p PID 进入后,使用set environment 就可以在GDB内设置环境变量;同样的,使用show environment 就可以查看环境变量~
(show environment 显示的不是进程的环境变量,而是进程运行环境的环境变量,需要查看进程的环境变量,则是(gdb) p (char*)getenv("HOME")
环境变量原理
每个程序都接收到一张环境表。它是一个字符指针数组,其中每个指针包含一个以 null 结尾的字符串的地址。全局变量environ则包含了该指针数组的地址:extern char **environ;
#include <stdio.h>
int main(void){
extern char **environ;
int i=0;
while(*(environ+i)!=NULL){
printf("%s\n",*(environ+i));
i++;
}
return 0;
}
存取环境变量原理
1. 如果修改一个现有的name
(a)如果新value的长度少于或等于现有value的长度,则只要在原字符串所用空间中写入新字符串。
(b)如果新value的长度大干原长度,则必须调用malloc为新字符串分配空间,然后将新字符串复制到该空间中,接着使环境表中针对name的指针指向新分配区。
2. 如果要增加一一个新的name,则操作就更加复杂。首先,调用malloc 为name = value字符串分配空间,然后将该字符串复制到此空间中,则:
(a)如果这是第一次增加- ~个新name,则必须调用malloc为新的指针表分配空间。接着,将原来的环境表复制到新分配区,并将指向新name = value字符串的指针存放在该指针表的表尾,然后又将- -个空指针存放在其后。最后使environ指向新指针表。再看一下图7-3,如果原来的环境表位于栈顶之上(这是- -种常见情况),那么必须将此表移至堆中。但是,此表中的大多数指针仍指向栈顶之上的各name=value字符串。
(b)如果这不是第-一次增加一个新name ,则可知以前已调用ma1loc在堆中为环境表分配了空间,所以只要调用realloc,以分配比原空间多存放一个指针的空间。然后将指向新name = value字符串的指针存放在该表表尾,后面跟着-一个空指针。
通过函数存取环境变量
要想在代码中使用这个数组,需要前面的声明,否则 environ 是一个非定义的符号,环境由 name=value 这样形式的字符串组成,大多数预定义名完全由大写字母组成,但是不保证全部是这样。内核并不查看这些字符串,它们的解释完全取决于各个应用程序,通常使用 getenv 和 putenv 函数来访问特定的环境变量,而不是用 environ 变量,但是要查看整个环境,就必须要用 environ 指针。
getenv(3)
#include <stdlib.h>
char *getenv(const char *name);
功能:获取环境变量的值
参数:
name:环境变量的名字
返回值:
NULL 没有找到这个环境变量
返回环境变量的值的首地址。
putenv(3)
#include <stdlib.h>
int putenv(char *string);
功能:改变一个环境变量的值,或者增加一个环境变量
参数:
string:name=value
返回值:
0 成功
非0 错误
clearenv(3)
#include <stdlib.h>
int clearenv(void);
功能:清除环境变量
参数:
void
返回值:
0 成功
非0 失败
setenv(3)
#include <stdlib.h>
int setenv(const char *name,const char *value,int overwrite);
功能:改变或增加一个环境变量
参数:
name:指定了环境变量的名字
value:指定了环境变量的值
overwrite:
0 环境变量存在,那么值不改变。
非0 环境变量存在,值被替换。
返回值:
0 成功
-1 失败 errno被设置
int unsetenv(const char *name);
功能:删除环境变量
参数:
name:指定环境变量的名字
返回值:
0 成功
-1 失败 errno被设置
- myenv.c
#include <stdio.h>
int main(void){
extern char **environ;
int i=0;
while(*(environ+i)!=NULL){
printf("%s\n",*(environ+i));
i++;
}
return 0;
}
- myenv1.c
#include <stdio.h>
int main(int argc,char *argv[],char *envp[]){
int i=0;
for(;envp[i]!=NULL;i++){
printf("%s\n",envp[i]);
}
return 0;
}
getenv & setenv 获取&设置环境变量
1. getenv:取得环境变量内容
头文件- #include<stdlib.h>
格式: char * getenv(const char *name);
意义: getenv()用来取得参数name环境变量的内容。
@param name为环境变量的名称,如果该变量存在则会返回指向该内容的指针。环境变量的格式为name=value。
return 执行成功则返回指向该内容的指针,找不到符合的环境变量名称则返回NULL。
【注】:相关函数 putenv,setenv,unsetenv;
示例
#include<stdlib.h>
mian()
{
char *p;
if((p = getenv(“USER”)))
printf(“USER=%s\n”,p);
}
执行后显示: USER = root
2. putenv:改变或增加环境变量
int putenv(const char * string);
意义:putenv()用来改变或增加环境变量的内容。
@param: string的格式为name=value,如果该环境变量原先存在,则变量内容会依参数string改变,否则此参数内容会成为新的环境变量。
reutrn 执行成功则返回0,有错误发生则返回-1。
错误代码:ENOMEM 内存不足,无法配置新的环境变量空间。
示例:
#include<stdlib.h>
main()
{
char *p;
if((p = getenv(“USER”)))
printf(“USER =%s\n”,p);
putenv(“USER=test”);
printf(“USER=%s\n”,getenv(“USER”));
}
执行 USER=root USER=test
3. setenv:改变或增加环境变量
int setenv(const char *name,const char * value,int overwrite);
name为环境变量名称字符串。
value则为变量内容。
overwrite用来决定是否要改变已存在的环境变量。如果overwrite不为0,则改变环境变量原有内容,原有内容会被改为参数value所指的变量内容。如果overwrite为0,且该环境变量已有内容,则参数value会被忽略。
reuturn 执行成功则返回0,有错误发生时返回-1。
错误代码 ENOMEM 内存不足,无法配置新的环境变量空间
示例
#include<stdlib.h>
main()
{
char * p;
if((p=getenv(“USER”)))
printf(“USER =%s\n”,p);
setenv(“USER”,”test”,1);
printf(“USER=%s\n”,getenv(“USEr”));
unsetenv(“USER”);
printf(“USER=%s\n”,getenv(“USER”));
}
结果:
USER = root USER = test USER = (null)
#include <stdio.h>
#include <stdlib.h>
int main(void){
printf("USER:%s\n",getenv("USER"));
putenv("name=tarena");
printf("name:%s\n",getenv("name"));
// putenv("name=pycoming");
setenv("name","pycoming",1);
printf("name:%s\n",getenv("name"));
unsetenv("name");
printf("name:%s\n",getenv("name"));
clearenv();
printf("USER:%s\n",getenv("USER"));
return 0;
}
标签:name,getenv,char,setenv,environ,USER,环境变量 From: https://blog.51cto.com/liangchaoxi/5730149