环境变量与地址

一、基本概念:

环境变量一般是指在操作系统中用来指定操作系统运行的环境的一些参数。就比如在写C代码时,链接时我们并不知道链接的东静态库在哪里,但是照样连接成功,原因是有相关环境变量帮助编译器进行查找。

常见环境变量:

PATH:指定命令的搜索路径

HOME:指定用户的主工作目录(即用户登录到Linux系统中的默认路径)

SHELL:当前shell,它的值通常是/bin/bash

系统存在环境变量PATH来帮助系统找到二进制文件,告诉系统去哪些路径下找二进制文件。

cpp 复制代码
#include <stdio.h>
int main(int argc, char* argv[])
{
	for (int i = 0; i < argc; i++)
	{
		printf("argv[%d]: %s\n", i, argv[i]);
	} 

	return 0;
}

main函数里的argv\[\]其实就是把命令行以空格作为分隔符然后填入指针数组当中。argv\[\]是个变长数组。第一个字符是./code 就把./code这个字符串的地址填入argv0,以此类推。也就是命令行参数依次变成子串放在数组里,放了多少个由argc来记录。

平时用的命令本质上是可执行程序,这个命令一般也是C语言写的。

cpp 复制代码
#include <stdio.h>
int main(int argc, char* argv[])
{
	if (argc != 2)
	{
		printf("Usage: %s [-a|-b|-c]", argv[0]);
	}

	return 0;
}

完善一下:

cpp 复制代码
#include <stdio.h>
#include <string.h>
int main(int argc, char* argv[])
{
	if (argc != 2)
	{
		printf("Usage: %s [-a|-b|-c]\n", argv[0]);
        return 1;
	}

	const char* arg = argv[1];

	if (strcmp(arg, "-a") == 0)
	{
		printf("这是功能1\n");
	}
	else if (strcmp(arg, "-b") == 0)
	{
		printf("这是功能2\n");
	}
	else if (strcmp(arg, "-c") == 0)
	{
		printf("这是功能3\n");
	}
	else
		printf("Usage: %s [-a|-b|-c]", argv[0]);

	return 0;
}

这样子就类似输入命令比如ls -a,ls -l,命令行参数用途是可以让一个程序通过选项实现不同的子功能。main函数的命令行参数是实现程序不同子功能的方法。

进程启动时有一张表叫argv表,用来支持实现选项功能。

用env查所有环境变量。归根节底在系统内找到一个命令或某个二进制文件默认是在环境变量path所对应的子路径中一个一个找的。对PATH进行赋值就可以直接变成命令。但是ls这样系统的命令找不到了。这是因为直接赋值就把原来PATH里的路径给覆盖了。

二、如何理解环境变量:登录的时候形成一张表,叫环境变量表,是一个指针数组

输入ls -a先被bash拿到,然后就拆分,先构建命令行参数表,再用ls这个命令在环境变量表中找到PATH,再根据路径拼上程序名,然后找到了创建子进程

bash内部有两张表,命令行参数表和环境变量表 。

环境变量最开始是从配置文件来的。

和环境变量的相关命令:

echo:显⽰某个环境变量值

export: 设置⼀个新的环境变量

env: 显⽰所有环境变量

unset: 清除环境变量

set: 显⽰本地定义的shell变量和环境变量

三、获取环境变量的方法:

1.和环境变量的相关命令:

echo:显⽰某个环境变量值

export: 设置⼀个新的环境变量

env: 显⽰所有环境变量

unset: 清除环境变量

set: 显⽰本地定义的shell变量和环境变量

比如要导入一个环境变量叫MYENV=11223344,就写export MYENV=11223344,这样就可以让系统在环境变量表里写入MYENV字符串了,然后再查找,就会出现MYENV=11223344。

清除就写unset MYENV。

2.main函数的参数:有三个。

方法一:int argc, char *argv\[\], char *env\[\],后面两个是命令行参数表和环境变量表,是由系统解析好之后传给main函数的,所以可以在main函数里遍历env来获取环境变量。

cpp 复制代码
int main(int argc, char *argv[], char *env[])
{
    (void)argc;
    (void)*argv;

    for (int i = 0; env[i]; i++) // 遍历到结尾是NULL循环自己会结束
    {
        printf("env[%d]->%s\n", i, env[i]);
    }

    return 0;
}

方法二:getenv:写一个程序只能我执行其他人执行不了。

cpp 复制代码
int main(int argc, char *argv[])
{
    (void)argc;
    (void)*argv;

    const char *who = getenv("USER");
    if(who==NULL)
        return 1;

    if(strcmp(who,"lxy")==0)//比较必须是某个用户才能运行
    {
        printf("程序正常逻辑");
    }
    else 
    {
        printf("Only lxy");
    }

    return 0;
}

方法三:通过第三方变量environ获取。

cpp 复制代码
int main(int argc, char *argv[])
{
    (void)argc;
    (void)*argv;

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

    return 0;
}

四、环境变量的特性:全局性,可以被子进程继承下去

环境变量在BASH里,内建命令,执行时不需要创建子进程,而是bash自己执行,bash自己调用函数或者系统自己调用

直接在命令行当中定义本地变量,bash会记录两套变量,环境变量和本地变量,本地变量不会被子进程继承,只能在bash内部使用

相关推荐
IT摆渡者43 分钟前
11Panel 部署雷池WAF
linux
学习路上_write44 分钟前
Linux黑马命令学习
linux·运维·服务器
yunwei371 小时前
eBPF 教程:追踪 CUDA GPU 操作
linux·后端·性能优化
Android系统攻城狮1 小时前
Linux Gstreamer深度解析之gst_audio_channel_reorder_map调用流程与实战(十八)
linux·运维·服务器·音视频进阶·gstreamer音视频进阶
新时代牛马2 小时前
Linux 防火墙:nftables 与iptables 兼容层
linux·运维·服务器
ao-weilai3 小时前
Linux网络编程:网络知识基础
linux·网络·php
GeW4 小时前
RHCE10一次过!提高通过率+快速拿证的7个核心技巧
linux
浅念-4 小时前
C++ Protobuf 入门实战:基于通讯录项目吃透proto3语法与序列化
linux·服务器·网络·c++·protobuf·proto·proto3
不怕犯错,就怕不做4 小时前
RK linux在buildroot中如何添加linux命令
linux·驱动开发·嵌入式硬件
小羊在睡觉4 小时前
HLS视频
linux·后端·golang