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程序,环境变量至关重要。

相关推荐
A小辣椒1 天前
TShark:Wireshark CLI 功能
linux
A小辣椒1 天前
TShark:基础知识
linux
AlfredZhao1 天前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao2 天前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334662 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪2 天前
linux 拷贝文件或目录到指定的位置
linux
大树883 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠3 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质3 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
bush43 天前
嵌入式linux学习记录十四、术语
linux·嵌入式