Linux

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > Linux > Linux命令行参数和环境变量

Linux命令行参数和环境变量使用详解

作者:陳1030

文章首先讲解了命令行参数的基本概念,包括`main`函数的参数及其作用,接着介绍了Linux下统的执行流程,重点解释了`argv`和`argc`的作用,然后介绍了环境变量的概念、作用和使用方法,解释了如何临时和永久设置环境变量

1. 命令行参数

首先,我们要解决一个问题:main函数可以有参数吗?

答案是,可以的。

很多人可能第一次见到main函数还有参数,也有人只知道有参数,但不知道它代表的到底是什么意思。

我们用这一段代码先来看看现象:

从终端的输出结果可以看出,随着你在命令后面输入的参数增多,argc(参数计数器)不断增加,argv(参数向量数组)里存的内容也越来越多:

输入 ./code

输入 ./code a

这段现象背后,是 Linux 系统 exec 执行流程 的体现:

命令拆分(Shell 解析):当你在终端输入 ./code a b c 并回车时,Shell(命令行解释器)会先把这行字符串按 空格 拆分成一个字符串数组:[ "./code", "a", "b", "c" ]

传递给 main 函数:Shell 调用系统调用执行程序,操作系统内核会把这个数组作为参数,原封不动地传给 main 函数

参数封装

argc 记录了命令行输入的参数总个数,包含程序名本身;argv 是一个字符串指针数组,依次存储了从命令行解析出来的每一个参数,argv[0] 固定为程序的名称或路径,argv[1]argv[2] 等则依次存储用户输入的自定义参数。程序通过这两个参数,能够精准获取运行时的命令行输入数据,实现程序与操作系统的交互。

那么说到底,这两个参数到底有什么用呢?

我们先给大家看一个场景:

首先利用这段代码,我们实现出这样一个场景,这样看可能不太直观,但是这样大家就能理解了:

因此,命令行参数的意义在于:让同一个程序能灵活适配不同场景,无需修改源码。它让程序在启动时就能获取用户指定的配置、目标文件、功能选项等,既提升了程序的通用性与复用性,也让程序能便捷地与 Shell 脚本、其他工具联动,适配自动化、批量执行等场景,是 Linux 环境下程序与系统、用户交互的标准化、高效接口。

2. 环境变量

我们之前提到过,当我们想要执行一个我们自己编写的可执行程序的时候,需要加上 ./ ,这是因为要告诉系统:要执行的程序就在当前目录,否则系统会提示 “command not found”。简单说,./ 的作用就是指定从当前目录执行程序

可我们之前还讲过,Linux下一切皆文件,像我们平时使用的命令,比如:ls、cd、touch等等,它们也都是作为可执行程序的文件,为什么就不用加 ./ 呢?这是因为它们都放在系统里的一个目录 user/bin/底下,当执行可执行程序的时候,系统只会在这个目录下查找文件。所以我们想要执行可执行程序文件的时候,除了采用 ./ 这种方式,还可以把们要执行的文件放到 user/bin/这个目录里面,就可以不加 ./ 直接调用。

那操作系统是怎么知道,自己就要在 user/bin/ 这个目录下查找文件的呢?是谁告诉它的?

这就要介绍我们这一段的标题:环境变量。

2.1 基本概念

环境变量是操作系统为当前用户会话、Shell 进程以及所有运行中的程序提供的一组全局动态变量,用于存储系统运行所需的公共配置信息,它不依赖于某个具体程序,而是对整个当前环境生效,系统和应用程序都可以直接读取、使用这些变量来决定自身的运行行为。

在 Linux 系统中,环境变量本质是一组 “键 = 值” 形式的配置项,常见的如 PATH 记录可执行文件搜索路径、HOME 记录用户主目录、PWD 记录当前所在目录、LANG 决定系统语言与字符编码等,它们的作用是让程序不必在代码中写死固定路径或配置,从而具备更好的通用性和可移植性。

当我们在终端输入一个命令时,系统会根据 PATH 这个环境变量里保存的目录依次查找对应可执行文件,这也是为什么系统命令可以直接运行,而自己编写的程序需要加上 ./ 来明确指定路径的原因。环境变量可以临时设置,也可以写入配置文件永久生效,不同用户可以拥有不同的环境变量配置,它是系统实现灵活管理、程序间信息传递以及命令行正常工作的重要基础机制。

常见的环境变量有这些:

2.2 查看环境变量

既然有环境变量这个东西,那我们该如何具体查看它呢?那就需要使用这个命令,以PATH为例:

echo $PATH

PATH 是 Linux 中用于指定命令搜索路径的环境变量,它存储了一组用冒号分隔的系统目录,Shell 执行命令时会按顺序在这些目录中查找可执行文件,系统命令因存放在 PATH 包含的目录中而可直接执行,自定义程序不在 PATH 中,因此需要用 ./ 指定路径运行,是 Linux 实现命令查找与执行的核心机制。

那么如果我们想要修改 PATH ,除了将我们的目标文件直接加入到 user/bin/ 目录里,还可以这样操作:

# 把当前目录(.)追加到 PATH 末尾
export PATH=$PATH:.

不过这种修改只对当前终端会话有效,关闭终端后就会恢复默认。如果想要永久修改PATH,就要修改一下Shell 配置文件:

1. 编辑 ~/.bashrc 文件

vim ~/.bashrc

2. 在文件末尾添加

# 把你的程序目录加入 PATH,比如 ~/mycode
export PATH=$PATH:~/mycode

3.保存后执行 source ~/.bashrc 让配置立即生效。

不过一般不建议把当前目录 . 永久加入 PATH,因为会存在安全风险,比如恶意脚本伪装成 ls 等系统命令,被优先执行,临时使用是可以的。另外,修改 PATH 时一定要写 $PATH:比如 export PATH=xxx 会直接覆盖原来的 PATH,导致所有系统命令都找不到,必须用 $PATH:xxx 追加。

如果还想查看其他所有的环境变量,我们可以使用 env 命令:

这里的环境变量的意义都是:

2.3 通过代码获取环境变量

我们前面在讲命令行参数的时候,提到了main函数有两个参数,实际上main函数最多有三个参数:

第三个参数 char* env() ,实际上存储的就是当前操作系统里的环境变量表。本质是将环境变量表传给进程。

除了利用main函数的参数来获取环境变量,我们还可以使用 getenv函数:

getenv 是 C 语言中用于获取环境变量值的标准库函数,接收环境变量名作为参数,返回对应的值;若变量不存在则返回 NULL,是程序访问环境变量最简便的接口。

现在就有一个问题,我我们在main函数里看到的 argv 和 env 两个参数,到底是谁传递过来的数据呢?实际上,进程的命令行参数列表与环境变量列表,都是由其父进程(通常为 bash 这类 Shell)在创建新进程时传递的,而非由内核直接生成。

因为我们之前提到过,我们运行的所有文件、程序等等,其实都是 bash 这个进程的子进程,而作为子进程我们可以获取到父进程(bash)的代码和数据等等,所以bash会把会话的所有环境变量(如 PATHHOMEUSER)整理成 envp 数组,然后在创建新进程的时候直接传递过去。这也间接的让环境变量具有了全局性。

那么bash的这个环境变量列表又是从哪里获取的呢?答案是:从Linux操作系统的配置文件信息里读取到的。也就是说,当我们启动Linux操作系统,也就是创建进程bash的时候,会先读取Linux的配置文件,然后把读取到的信息加载到bash进程的上下文数据里。这也是之所以我们只要重启Linux操作系统之后,原先修改过的环境变量会被恢复成原来的值,重启的本质也就是重新再读取加载一遍。

其中的 .bashrc 和 .bash_profile 就是要读取的文件。

所以流程就是:bash创建时先会读取 .bash_profile 文件,这个文件要执行的操作是去访问 .bashrc 这个文件,而 .bashrc 的文件操作是访问 /etc/bashrc 这个系统文件,这个系统文件里面存在的就是环境变量信息。

我们还可以再验证一下:

先修改一下 .bash_profile 文件。

所以在最下面一行,我们登陆的时候,就会有对应的提示信息。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文