Linux环境变量

1.命令行参数

在认识环境变量之前,先认识下命令行参数。Linux下各种指令有各种参数,指令都有一个main函数,通过命令行参数传入main函数。比如ls -a -l中,把a,l这两个参数传递给ls这个程序中,以达到通过对应参数来指定程序执行结果的目的。

同样,可以自己写一个程序更好地进行理解,main函数默认有很多参数,其中前两个是int argc, char* argv[]

c 复制代码
int main(int argc, char *argv[])
{
    for (int i = 0; i < argc; i++)
    {
    	printf("%s\n", argv[i]);
    }
    return 0;
}

通过执行程序并传递命令行参数后,进行命令行参数打印,可以看到命令行参数通过空格区分存放到argv指针数组中。

shell 复制代码
root@hcss-ecs-e6eb:~/learning/Linux-learning/Process# ./myprocess -a 
./myprocess
-a
root@hcss-ecs-e6eb:~/learning/Linux-learning/Process# ./myprocess -a -b 
./myprocess
-a
-b

这样就可以通过命令行参数来实现同一程序的不同功能。

c 复制代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
    if (argc != 4)
    {
    	printf("Usage:\n\t%s -[add|sub|mul|div] x y\n\n", argv[0]);
    	return 1;
    }   
    int x = atoi(argv[2]);
    int y = atoi(argv[3]);  
    if (strcmp(argv[1], "-add") == 0)
    {
    	printf("%d+%d=%d\n", x, y, x+y);
    }
    else if (strcmp(argv[1], "-sub") == 0)
    {
    	printf("%d-%d=%d\n", x, y, x-y);
    }
    else if (strcmp(argv[1], "-mul") == 0)
    {
    	printf("%d*%d=%d\n", x, y, x*y);
    }
    else if (strcmp(argv[1], "-div") == 0)
    {
    	printf("%d/%d=%d\n", x, y, x/y);
    }
    else 
    {
    	printf("unknown!\n");
    }   
    return 0;
}
shell 复制代码
root@hcss-ecs-e6eb:~/learning/Linux-learning/Process# ./myprocess -add 1 2
1+2=3
root@hcss-ecs-e6eb:~/learning/Linux-learning/Process# ./myprocess -mul 3 4
3*4=12

命令行参数存放在main函数第二个参数中,而环境变量存放在第三个参数env中,该参数也是指针数组。
int main(int argc, char *argv[], char *env[])

也就是说,程序执行时,不仅会接收命令行参数表,也会接收一个环境变量表,这个环境变量表的结构与命令行参数表是一致的。

2.什么是环境变量

环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数。

在编写C/C++的代码时,会引入一些库(例如iostream),以供代码链接。但是在链接的时候,从来不知道所链接的动态链接库在哪里,同样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。

环境变量 是一堆变量,是系统内置具有特殊用途的变量,变量的本质就是开辟空间存放数据。操作系统中bash也是用C写的,在运行中可以开辟空间申请变量,这里的环境变量就是bash程序中的变量,以便bash运行时进行一些操作(例如运行编译程序进行链接动态链接库)。

一般常见的环境变量有:

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

Linux中通过echo $NAME指令来查看指定环境变量的内容,这里的NAME是指环境变量名,前必须有$

shell 复制代码
root@hcss-ecs-e6eb:~/learning/Linux-learning# echo $HOME
/root
root@hcss-ecs-e6eb:~/learning/Linux-learning# echo $SHELL
/bin/bash
root@hcss-ecs-e6eb:~/learning/Linux-learning# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

同时可以通过env指令打印所有的环境变量

shell 复制代码
root@hcss-ecs-e6eb:~/learning/Linux-learning# env
SHELL=/bin/bash
HISTSIZE=1000
HISTTIMEFORMAT=%F %T root 
PWD=/root/learning/Linux-learning
LOGNAME=root
XDG_SESSION_TYPE=tty
MOTD_SHOWN=pam
HOME=/root
LANG=en_US.UTF-8
...

其余和环境变量有关的指令
echo: 显示某个环境变量值
export: 设置一个新的环境变量
unset: 清除环境变量
set: 显示本地定义的shell变量和环境变量

PATH 环境变量

当执行自己写的程序时,需要在前面添加./才能执行,但是在执行ls程序时,则不需要。

shell 复制代码
root@hcss-ecs-e6eb:~/learning/Linux-learning/Process# ls
makefile  myprocess  myprocess.c
root@hcss-ecs-e6eb:~/learning/Linux-learning/Process# myprocess
myprocess: command not found

本质原因是 :在操作系统中,运行程序需要先找到该程序的路径,ls这样的命令,Linux中可以默认找到,因为这些命令的所在位置都处于环境变量PATH中。而自己写的程序,只有通过./系统才能知道该程序是在当前路径中的。

若想要自己的程序不需要./就可以直接执行,有两种方法,一种是直接将该程序放置PATH环境变量对应的路径中,但是不推荐,这样会污染命令池。

还有一种方法是通过export命令将指定程序路径添加至PATH环境变量中。

shell 复制代码
root@hcss-ecs-e6eb:~/learning/Linux-learning/Process# export PATH=$PATH:~/learning/Linux-learning/Process/
root@hcss-ecs-e6eb:~/learning/Linux-learning/Process# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/root/learning/Linux-learning/Process/
root@hcss-ecs-e6eb:~/learning/root@hcss-ecs-e6eb:~/learning/Linux-learning/Process# myprocess -add 1 2
1+2=3

可以看到,export命令后,PATH新增了我需要添加程序的所在路径,同时直接myprocess也成功了。

需要注意的是,使用export而不修改配置文件(该文件在家目录.bashrc中),只会在当前运行的bash中起到作用,当窗口关闭重新运行一个新的bash进程,由于默认配置文件没有被修改,新的进程中的环境变量不会被修改。

3.获取环境变量

通过代码获取环境变量

  • 利用mian函数的第三个参数 char *env[]获取环境变量
c 复制代码
#include <stdio.h>

int main(int argc, char *argv[], char *env[])
{
    // env指针数组以null为结尾,当  环境变量全部读取完毕循环会结束
    for (int i = 0; env[i]; i++)
    {
        printf("%s\n", env[i]);
    }
    return 0;
}
  • 通过第三方变量environ获取
c 复制代码
#include<stdio.h>

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

通过系统调用获取环境变量

getenv()函数是包含于<stdlib.h>头文件中的一个函数,该函数可以通过所给环境变量名返回环境变量内容。

c 复制代码
#include <stdio.h>
#include <stdlib.h>

int main()
{
    printf("%s\n", getenv("PATH"));
    return 0;
}

通常情况下,更多使用系统调用来查看环境变量内容,该函数可以查看指定某一个环境变量的内容。

4.环境变量的全局属性

实际上,一个程序的main函数中的char *env[]中的环境变量信息来自其父进程。

当父进程创建一个子进程,会将其自身的环境变量信息作为参数传递给子进程。

还是这个程序,运行后想查看是否有名为MYTEST的环境变量信息,此时肯定是没有的。

c 复制代码
#include <stdio.h>

int main(int argc, char *argv[], char *env[])
{
    for (int i = 0; env[i]; i++)
    {
        printf("%s\n", env[i]);
    }
    return 0;
}

但在bash使用export命令添加环境变量,再进行检索,会显示该环境变量。由于myprocessbash的子进程,其继承了bash的环境变量表。

shell 复制代码
root@hcss-ecs-e6eb:~/learning/Linux-learning/Process# ./myprocess | grep MYTEST
root@hcss-ecs-e6eb:~/learning/Linux-learning/Process# export MYTEST=test
root@hcss-ecs-e6eb:~/learning/Linux-learning/Process# ./myprocess | grep MYTEST
MYTEST=test

由于变量的存在,shell也成为一门语言,在后续自己编写一个shell程序,环境变量至关重要。

相关推荐
愚润求学21 分钟前
【Linux】简单设计libc库
linux·运维·开发语言·c++·笔记
chennalC#c.h.JA Ptho37 分钟前
Bodhi linux 系统详解
linux·经验分享·笔记·系统架构·系统安全
monstercl39 分钟前
游戏资源传输服务器
运维·服务器·游戏
运维开发王义杰44 分钟前
PAC文件:智能代理配置的瑞士军刀
运维
网硕互联的小客服1 小时前
服务器配置错误导致SSL/TLS出现安全漏洞,如何进行排查?
运维·服务器
QX_hao1 小时前
【docker】--镜像管理
运维·docker·容器
敲上瘾1 小时前
MySQL数据库表的约束
linux·数据库·sql·mysql·数据库开发·数据库架构·数据库系统
u0109362651 小时前
Linux电源管理(五),发热管理(thermal),温度控制 (结合设备树 和ACPI Source Language(ASL)分析)
linux
itachi-uchiha1 小时前
Linux上的rm和srm 命令
linux·运维·服务器
快乐肚皮2 小时前
深入解析Docker:核心架构与最佳实践
java·运维·docker·容器