Linux环境变量


前言

环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性


一、常见环境变量

PATH : 指定命令的搜索路径。
HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)。
SHELL : 当前Shell,它的值通常是/bin/bash。

PATH:
为什么我们要运行我们自己写的可执行程序的时候,需要加./呢?这是因为我们需要告诉系统,我们的文件在那里。
为什么pwd,ls,touch这些命令不需要指定文件在那里呢?这是因为,环境变量帮助系统找到他们在那里。
当然我们也可以把我们的可执行文件添加到PATH环境变量里面的搜索路径中,这样我们执行我们编写的可执行文件时,就不需要加./了。
在这里插入图片描述
查看环境变量方法:

echo $NAME //NAME:你的环境变量名称

我们可以通过查看PATH环境变量的内容得出,路径是以:分号划分的,我们也可以自定义添加上我们指定的搜索路径,将我们的程序所在路径加入环境变量PATH当中。

export PATH=$PATH:/home/ccc/BK/12_8BK //程序所在路径

在这里插入图片描述
在这里插入图片描述
这样我们在指定路径下编写的可执行二进制文件,就可以不用加./指定文件位置了。
如果你胡乱改了的话,改不回去也没关系,因为这是环境变量由子程序继承的,只要你把xshell退了,重新再进又会还原之前的环境变量。在这里插入图片描述
HOME: 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)。
为什么我们在Linux一登录账号后,系统会自动帮我们进到对应的目录下?这是因为HOME环境变量,记录了,我们每个账号家目录的位置。
在这里插入图片描述

我当前登录的账号是ccc $HOME默认记录的是,ccc账号的家目录

在这里插入图片描述

我切换成root账号,$HOME默认记录的是root账号的家目录。

我们也可以自定义一些环境变量
在这里插入图片描述
这里,我设置了一个环境变量hello=333,但是我们在ehco和env显示全局环境变量中都没有找到他,这是因为我们自定义的环境变量是本地的,不是全局的,如果要改为全局,需要加上export 加环境变量名。

在这里插入图片描述
取消我们刚刚设置的环境变量名的命令是unset 加环境变量名
在这里插入图片描述
如果要显示本地定义的shell变量和环境变量命令是set,输入后会显示很多环境变量出来。

和环境变量相关的命令

  1. echo: 显示某个环境变量值
  2. export: 设置一个新的环境变量
  3. env: 显示所有环境变量
  4. unset: 清除环境变量
  5. set: 显示本地定义的shell变量和环境变量

二、查看获取环境变量的方法

1.extern char** environ;

每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>


int main()
{
  extern char** environ;
  for(int i = 0;environ[i];++i)
  {
    printf("%d:%s\n",i,environ[i]);
  }
  return 0;
}

environ是一个C语言提供的全局指针数组,里面保存着环境变量的首字符串地址,结尾以NULL结束。在这里插入图片描述

2.getenv()

getenv()和上面的environ最大的区别是,可以指定获取那些环境变量,我们简单写一下权限不足的检测程序,检测如果不是root用户的话,会打印permisson,denied,如果是root用户则打印用户名。
代码如下(示例):

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
int main()
{
  char* user = getenv("USER");
  if(strcmp("root",user)==0)
  {
    printf("%s\n",user);
    printf("%s\n",user);
    printf("%s\n",user);
    printf("%s\n",user);
    printf("%s\n",user);
    printf("%s\n",user);
  }
  else
  {
    printf("permisson,denied\n");
  }
  sleep(1);
  return 0;
}

在这里插入图片描述
这里登录的是ccc的用户,不是root,结果如我们预期的显示permisson,denied
在这里插入图片描述
这里我们用sudo 暂时切换成root,结果如我们预期的显示root用户名,这就是简单版的用户判断,通过调用USER环境变量,判断用户是否有相对应的权限。

3.main函数的参数 char* env[]

main函数也有参数的其中env跟上方的environ是一样的,同样保存着环境变量首字符串的地址,以NULL结束

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
int main(int argc,const char* argv[],char* env[])
{
	//env最后以NULL结尾 NULL字面上 = 0
  for(int i = 0;env[i];++i)
  {
    printf("%d:%s\n",i,environ[i]);
  }
  sleep(1);
  return 0;
}

执行我们编写的程序后,输出的结果跟我们输入env命令的结果是一样的。


三.获取命令行参数

main函数的参数int argc,char* argv[],是获取我们的命令行参数的,是由shell和系统完成的。
以下面代码为例:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
int main(int argc,const char* argv[])
{
  for(int i = 0;i < argc;++i)
  {
    printf("argv[%d]:%s\n",i,argv[i]);
  }
  sleep(1);
  return 0;
}

在这里插入图片描述
在这里插入图片描述
我们可以发现,随着我们输入可执行程序名字,随着我们的选项加多,我们打印出来的数值也随着变多了,我们可以理解为,./myprocess 是程序,后面的-a -b是选项,跟ls -a -l -d是一样的,所以命令行参数,本质是传递给argv的,整体是大字符串,我们对命令行解析的时候,把大字符串,拆解成"ls" “-a” "-l"以空格分隔的字符串,argc记录着一共有多少个字符串,默认0下标 保存的是命令,之后的则是保存着选项,最后以NULL结尾,这些都是shell和操作系统来做的,这些有什么用呢?下面展示实例。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <time.h>
int main(int argc,const char* argv[])
{
  if(argc < 2)
 {
    printf("需要添加指定选项:(-a,-b,-c,-ab,-bc)\n");
    return 1;
  }
  if(strcmp("-a",argv[1])==0)
  {
    printf("功能a\n");
  }
  if(strcmp("-b",argv[1])==0)
  {
    printf("功能b\n");
  }
  if(strcmp("-c",argv[1])==0)
  {
    printf("功能c\n");
  }
  if(strcmp("-ab",argv[1])==0)
  {
    printf("功能ab\n");
  }
  if(strcmp("-bc",argv[1])==0)
  {
    printf("功能bc\n");
  }
  sleep(1);
  return 0;
}

程序输出

[ccc@VM-8-6-centos 12_8BK]$ ./myprocess
需要添加指定选项:(-a,-b,-c,-ab,-bc)
[ccc@VM-8-6-centos 12_8BK]$ ./myprocess -ab
功能ab
[ccc@VM-8-6-centos 12_8BK]$ ./myprocess -bc
功能bc
[ccc@VM-8-6-centos 12_8BK]$ ./myprocess -a
功能a

可以理解为,./myprocess是程序,给他不同的选项,执行不同的功能,相当于ls -a -l这些命令,这就是命令行参数最大的意义,同一个程序,不同的选项,执行不同的功能。
ls -a
ls -al执行不同的功能

[ccc@VM-8-6-centos 12_8BK]$ ls -a
. … makefile myprocess myprocess.c
[ccc@VM-8-6-centos 12_8BK]$ ls -al
total 28
drwxrwxr-x 2 ccc ccc 4096 Dec 8 13:13 .
drwxrwxr-x 4 ccc ccc 4096 Dec 8 10:32 …
-rw-rw-r-- 1 ccc ccc 82 Dec 8 11:54 makefile
-rwxrwxr-x 1 ccc ccc 8464 Dec 8 13:13 myprocess
-rw-rw-r-- 1 ccc ccc 1078 Dec 8 13:13 myprocess.c

如果不想在程序名前加./ 可以根据上方的环境变量,把我们的程序文件路径添加到环境变量$PATH里面,执行我们的程序就可以不用添加./了,本质上我们的命令就是c/c++写的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值