Linux命令行参数和环境变量使用详解
1. 命令行参数
首先,我们要解决一个问题:main函数可以有参数吗?
答案是,可以的。

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

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

从终端的输出结果可以看出,随着你在命令后面输入的参数增多,argc(参数计数器)不断增加,argv(参数向量数组)里存的内容也越来越多:
输入 ./code:
argc: 1:说明只有 1 个参数(系统默认自带的程序名)。argv[0] -> ./code:argv[0]永远固定存储 程序自身的名称或路径。
输入 ./code a:
argc: 2:参数变成了 2 个(程序名 + 第一个自定义参数)。argv[1] -> a:argv[1]存储了你输入的第一个自定义参数a。
这段现象背后,是 Linux 系统 exec 执行流程 的体现:
命令拆分(Shell 解析):当你在终端输入 ./code a b c 并回车时,Shell(命令行解释器)会先把这行字符串按 空格 拆分成一个字符串数组:[ "./code", "a", "b", "c" ]
传递给 main 函数:Shell 调用系统调用执行程序,操作系统内核会把这个数组作为参数,原封不动地传给 main 函数。
参数封装:
argc:内核数一下这个数组里有几个元素,传给argc(这里是 4 个)。argv:内核把这个字符串数组的首地址传给argv。argv[argc] = NULL:C 语言标准规定,argv数组的最后一个元素后面必须跟一个NULL指针,作为参数结束的标记(虽然代码里没打印,但它存在)。
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 这个环境变量里保存的目录依次查找对应可执行文件,这也是为什么系统命令可以直接运行,而自己编写的程序需要加上 ./ 来明确指定路径的原因。环境变量可以临时设置,也可以写入配置文件永久生效,不同用户可以拥有不同的环境变量配置,它是系统实现灵活管理、程序间信息传递以及命令行正常工作的重要基础机制。
常见的环境变量有这些:
PATH: 指定命令的搜索路径HOME: 指定用户的主工作目录 (即用户登陆到 Linux 系统中时,默认的目录)SHELL: 当前 Shell, 它的值通常是 /bin/bash。
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 命令:

这里的环境变量的意义都是:
env:这是命令本身,作用是列出当前所有环境变量。SHELL=/bin/bash:指定当前使用的 Shell 解释器为 bash。USER=chen:当前登录的用户名是chen。HOME=/home/chen:当前用户的主目录,也是登录后默认进入的目录。PWD=/home/chen:当前所在的工作目录路径。PATH=/usr/local/bin:/bin:/usr/bin:...:命令搜索路径,Shell 会按顺序在这些目录中查找可执行文件。HOSTNAME=chen:当前主机的名称。TERM=xterm:当前终端的类型,影响命令行的显示和交互。LANG=en_US.UTF-8:系统的语言和字符编码设置,决定输出语言和文本处理方式。HISTSIZE=1000:Shell 历史命令记录的最大条数。HISTCONTROL=ignored:控制历史命令的记录方式,这里表示忽略重复命令。MAIL=/var/spool/mail/chen:用户邮件文件的存储路径。LOGNAME=chen:与USER类似,记录当前登录的用户名。SHLVL=1:当前 Shell 的嵌套层级,1 表示首次登录的 Shell。LESSOPEN=||/usr/bin/lesspipe.sh %s:配置less命令的预处理工具,用于查看压缩文件等。_=/bin/env:上一条执行的命令路径,这里是env命令本身。
2.3 通过代码获取环境变量
我们前面在讲命令行参数的时候,提到了main函数有两个参数,实际上main函数最多有三个参数:


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

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


getenv 是 C 语言中用于获取环境变量值的标准库函数,接收环境变量名作为参数,返回对应的值;若变量不存在则返回 NULL,是程序访问环境变量最简便的接口。
现在就有一个问题,我我们在main函数里看到的 argv 和 env 两个参数,到底是谁传递过来的数据呢?实际上,进程的命令行参数列表与环境变量列表,都是由其父进程(通常为 bash 这类 Shell)在创建新进程时传递的,而非由内核直接生成。
因为我们之前提到过,我们运行的所有文件、程序等等,其实都是 bash 这个进程的子进程,而作为子进程我们可以获取到父进程(bash)的代码和数据等等,所以bash会把会话的所有环境变量(如 PATH、HOME、USER)整理成 envp 数组,然后在创建新进程的时候直接传递过去。这也间接的让环境变量具有了全局性。
那么bash的这个环境变量列表又是从哪里获取的呢?答案是:从Linux操作系统的配置文件信息里读取到的。也就是说,当我们启动Linux操作系统,也就是创建进程bash的时候,会先读取Linux的配置文件,然后把读取到的信息加载到bash进程的上下文数据里。这也是之所以我们只要重启Linux操作系统之后,原先修改过的环境变量会被恢复成原来的值,重启的本质也就是重新再读取加载一遍。

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



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

先修改一下 .bash_profile 文件。

所以在最下面一行,我们登陆的时候,就会有对应的提示信息。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
相关文章
CentOS(Linux)下的apache服务器配置与管理方法分享
CentOS(Linux)下的apache服务器配置与管理方法分享,需要的朋友可以参考下。2011-04-04
CentOS 7.x安装部署Memcached服务器的详细方法
这篇文章主要介绍了CentOS 7.x安装部署Memcached服务器的详细步骤,需要的朋友可以参考下2018-01-01
CentOS 6.5编译安装Nginx 1.10.2+MySQL 5.5.52+PHP5.5.38
这篇文章主要介绍了CentOS 6.5编译安装Nginx 1.10.2+MySQL 5.5.52+PHP5.5.38,需要的朋友可以参考下2017-02-02


最新评论