【linux】环境变量

🔥个人主页Quitecoder

🔥专栏linux笔记仓

目录

01.命令行参数

这段C语言程序展示了如何通过 main 函数接收和打印命令行参数

使用一个for循环遍历从0到argc-1的所有索引,argc 表示命令行传入的参数数量。

在循环体内部,printf 函数用于打印每个参数的索引和内容。argv[i] 是一个指向字符的指针,指向第i个参数的字符串


为什么要有命令行参数:

本质:命令行参数本质是交给我们程序的不同的选型,用来定制不同的程序功能。命令中会携带很多的选项。

bash 复制代码
  1 #include<stdio.h>
  2 #include<sys/types.h>
  3 #include<unistd.h>
  4 #include<string.h>
  5 
  6 int main(int argc,char *argv[])
  7 {
  8     if(argc!=2)
  9     {
 10         printf("Usage:%s -[a,b,c,d]\n",argv[0]);
 11         return 1;
 12     }
 13     if(strcmp(argv[1],"-a")==0)
 14     {
 15         printf("this is function1\n");
 16     }                                                                                                          
 17     else if(strcmp(argv[1],"-b")==0)
 18     {
 19         printf("this is function2\n");
 20     }                                                                                                                           
 21     else if(strcmp(argv[1],"-c")==0)
 22     {
 23         printf("this is function3\n");
 24     }
 25     else if(strcmp(argv[1],"-d")==0)
 26     {
 27         printf("this is function4\n");
 28     }
 29
 30     return 0;
 31 }

再看一组代码

父进程的数据,默认能被子进程看到并访问



命令行中启动的程序都会变成进程,其实都是bash的子进程

02.环境变量

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

常见环境变量

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

查看环境变量方法:

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

系统中很多的配置,在我们登录Linux系统的时候,已经被加载到bash进程中(内存)。默认我们查到的环境变量是内存级的

bash在执行命令的时候,需要先找到命令,因为未来要加载

当在 Bash 或任何其他 shell 中执行一个命令时,shell首先需要找到该命令对应的可执行文件。这个查找过程依赖于一系列环境设置和内置规则,主要涉及以下几个步骤:

  1. 内置命令 首先,Bash 会检查要执行的命令是否是一个内置命令。内置命令是 Bash 自带的,不需要额外的可执行文件,例如 cd, echo, history 等。如果是内置命令,Bash 会直接执行,不会在文件系统中寻找。

  2. 哈希表(命令缓存) 如果不是内置命令,Bash 接下来会查看其哈希表(如果已经启用的话)。哈希表存储了先前找到的命令路径,以减少寻找同一命令的时间。通过这个缓存机制,如果命令已被之前执行过一次,Bash可以快速定位到命令的位置。

  3. 环境变量PATH 如果命令不在哈希表中,Bash 会利用 PATH 环境变量指定的目录列表来查找命令。PATH 变量包含了一系列目录,这些目录用冒号(:)分隔 ,Bash 会按照这些目录的顺序去搜索可执行文件。例如,如果你的 PATH/usr/local/bin:/usr/bin:/bin,Bash 会首先检查/usr/local/bin 目录,如果没有找到,再依次检查 /usr/bin/bin

  4. 找到命令执行 一旦在 PATH 中的某个目录找到了匹配的可执行文件,Bash 会加载并执行它。如果在所有列出的目录中都没有找到可执行文件,Bash 会返回一个错误,通常是"command not found"。

  5. 权限检查 找到可执行文件后,Bash 还会检查当前用户是否有权限执行该文件。如果没有执行权限,将返回权限错误。

ls可以直接使用,我们的命令必须带上./,是因为没有进行配置环境,ls实在/usr/bin目录下的

bash 复制代码
sudo cp testStatus /usr/bin/

我们可以将此命令拷贝到/usr/bin目录下

但是不建议这样做

我们可以将我们当前目录,添加到环境变量里面

这样直接赋值会使其他指令无法正常使用,我们这样改变了它所有路径

重新登录一次路径又恢复,所以我们说默认我们查到的环境变量是内存级的

正确方法:

bash 复制代码
PATH=$PATH:/home/dyx/test_static

那么最开始的环境变量呢?它不是在内存中,而是在系统对应的配置文件中

常见环境变量

  • PATH : 指定命令的搜索路径
  • HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
  • SHELL : 当前Shell,它的值通常是/bin/bash
bash 复制代码
[dyx@VM-8-13-centos test_static]$ echo $SHELL
/bin/bash
[dyx@VM-8-13-centos test_static]$ echo $HISTSIZE
3000
  1. $SHELL
  • 变量 $SHELL 表示当前用户默认的登录 shell。
  • 输出 /bin/bash 表明默认 shell 是 Bash。这是 Linux 中最常见的 shell,提供了强大的功能和灵活的脚本选项。
  1. $HISTSIZE
  • 变量 $HISTSIZE 定义了 Bash 历史记录中可以保持的命令数量的上限。
  • 输出 3000 表明 Bash 历史记录可以保存最多 3000 条命令。这个设置帮助用户回溯和查看他们之前执行过的命令。

和环境变量相关的命令

  1. echo: 显示某个环境变量值

  2. export: 设置一个新的环境变量

    如果不用export我们创建的叫做本地变量,env显示不出来但是echo可以查到

  3. env: 显示所有环境变量

  4. unset: 清除环境变量

  5. set: 显示本地定义的shell变量和环境变量

环境变量与程序结合(理解)

environ 是一个环境变量的列表,实际上它是一个全局的、包含所有环境变量的字符串数组。每个字符串都是一个键值对,格式为 KEY=value。这个数组由操作系统在程序启动时创建,用于存储有关程序运行环境的信息

bash 复制代码
  1 #include<stdio.h>
  2 #include<sys/types.h>
  3 #include<unistd.h>
  4 #include<string.h>
  5 
  6 
  7 int main()
  8 {
  9     extern char ** environ;                                                                                                     
 10     int i=0;
 11     for(;environ[i];i++)
 12     {
 13         printf("env[%d]->%s\n",i,environ[i]);
 14     }
 15     return 0;
 16 }

libc中定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以在使用时 要用extern声明

for(;environ[i];i++):循环遍历 environ 数组,直到遇到 NULL 结束符 。每次循环索引 i 自增1,以便访问环境变量数组中的下一个元素

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

环境变量默认也是可以被子进程拿到的

环境变量们默认在bash内部

bash 复制代码
[dyx@VM-8-13-centos test_static]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dyx/.local/bin:/home/dyx/bin:/home/dyx/test_static

所以我们再执行这个命令,bash就在env表里面寻找名为PATH的环境变量并打印

我们也可以使用main的第三个参数来获取环境变量,对应env表

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


子进程再创建子进程,bash的环境变量都能被子进程拿到 ,所以说环境变量具有系统级的全局属性

还可以通过下面方式获取环境变量

c 复制代码
#include <stdio.h>
#include <stdlib.h>
int main()
{
 printf("%s\n", getenv("PATH"));
 return 0;
}

三种方法:

在 Bash 或其他 shell 中,有两类主要的命令:内建命令(built-in commands)和外部命令(external commands)。理解 exportecho 作为内建命令的含义,涉及到它们的作用、执行方式以及为什么它们被设计为内建命令。

内建命令的定义

内建命令是直接由 shell 自身提供并执行的命令,不依赖于外部程序文件。这些命令是 shell 程序的一部分,因此执行时不需要创建新的进程。由于这个原因,内建命令通常执行得更快,并且能直接访问 shell 的内部数据结构。

为什么 exportecho 是内建命令

  1. export

    • export 命令用于将 shell 变量标记为环境变量,使得子进程能够继承这些变量 。如果 export 是外部命令,那么它在独立进程中运行,无法修改创建它的 shell 的环境,这会使它无法完成其设计的功能。
    • 举例来说,当你在 Bash 中执行 export PATH=/usr/local/bin:$PATH这个命令直接修改了当前 shell 的环境变量。如果 export 是外部程序,它会修改自己的副本环境,并在程序结束时消失,对父 shell 没有任何影响
  2. echo

    • echo 命令用于输出其参数到标准输出。虽然可以实现为外部命令,但作为内建命令,echo 可以更快地执行,并可以直接处理 shell 特有的功能,如展开 shell 变量、转义字符等。
    • 例如,执行 echo $HOME 时,echo 内建命令可以直接访问并展开 $HOME 环境变量,显示当前用户的主目录路径。

你可以使用 type 命令在 Bash 中检查一个命令是否是内建的。例如:

bash 复制代码
type export
type echo

这些命令会告诉你 exportecho 是内建命令。输出可能会类似于:

plaintext 复制代码
export is a shell builtin
echo is a shell builtin

本地变量只在本bash内部有效,无法被子进程继承下去,导成环境变量,此时才能够被获取

本地变量与环境变量的区别及其行为:

本地变量

  • 定义和作用域 :本地变量在 Bash 中定义时只在当前 shell 会话中有效。它们不能被任何启动的子 shell 或调用的子进程继承。这意味着当你在一个 Bash 会话中设置一个本地变量,它对任何从这个 shell 派生的新进程都是不可见的,除非显式地传递给它们
  • 用途:本地变量通常用于临时存储数据,比如循环计数器或局部计算值,这些值不需要超出其定义的脚本或命令序列。

环境变量

  • 定义和作用域环境变量通过使用 export 命令在 Bash 中设置,这使得它们不仅在当前 shell 中有效,还可以被任何子进程继承。如果你在一个 Bash 会话中创建一个环境变量,然后启动一个子进程(如另一个 Bash 实例或任何其他程序),这个子进程将能够访问那个环境变量
  • 用途:环境变量用于配置提供给进程的操作环境,如设置系统路径、用户信息、偏好设置等,这些信息需要在多个进程之间共享。

示例

假设你在 Bash 中设置了一个本地变量和一个环境变量:

bash 复制代码
# 设置本地变量
localvar="I am a local variable"

# 设置环境变量
export envvar="I am an environment variable"

如果你从这个 Bash 会话中启动另一个 Bash 会话并尝试访问这两个变量:

bash 复制代码
echo $localvar  # 这将不会输出任何东西,因为 localvar 是本地变量
echo $envvar    # 这将输出 'I am an environment variable'

只有 envvar 被输出,因为它是一个环境变量,被导出到新的子进程中。

相关推荐
ac.char5 分钟前
在 Ubuntu 上安装 Yarn 环境
linux·运维·服务器·ubuntu
敲上瘾5 分钟前
操作系统的理解
linux·运维·服务器·c++·大模型·操作系统·aigc
长弓聊编程24 分钟前
Linux系统使用valgrind分析C++程序内存资源使用情况
linux·c++
cherub.31 分钟前
深入解析信号量:定义与环形队列生产消费模型剖析
linux·c++
梅见十柒1 小时前
wsl2中kali linux下的docker使用教程(教程总结)
linux·经验分享·docker·云原生
Koi慢热1 小时前
路由基础(全)
linux·网络·网络协议·安全
传而习乎1 小时前
Linux:CentOS 7 解压 7zip 压缩的文件
linux·运维·centos
soulteary1 小时前
突破内存限制:Mac Mini M2 服务器化实践指南
运维·服务器·redis·macos·arm·pika
我们的五年1 小时前
【Linux课程学习】:进程程序替换,execl,execv,execlp,execvp,execve,execle,execvpe函数
linux·c++·学习
爱吃青椒不爱吃西红柿‍️2 小时前
华为ASP与CSP是什么?
服务器·前端·数据库