【Linux】命令行参数与环境变量
本文深入解析了Linux系统中命令行参数和环境变量这两个关键概念。环境变量作为操作系统的"运行参数",具有全局特性,可通过export命令设置或配置文件持久化,常用命令包括echo、env等;在C程序中可通过main函数参数或environ变量获取。命令行参数则是程序启动时传入的参数,通过main函数的argc和argv接收。两者虽都是程序与系统交互的方式,但环境变量具有全局性
在 Linux 系统的学习与开发中,命令行参数和环境变量是两个极为重要的概念,它们是程序与系统、程序与用户交互的关键桥梁。本文将从基本概念入手,逐步深入,结合代码示例详细解析这两个知识点。
一、环境变量:操作系统的“运行参数”
(一)基本概念
环境变量(environment variables)是操作系统中用来指定运行环境的参数集合。它有以下几个关键特性:
- 特殊用途:比如在编译 C/C++ 程序时,链接器依靠环境变量查找动态 / 静态库,我们无需手动指定库路径也能完成链接。
- 全局特性:在系统中具有全局性,影响范围广泛。
(二)常见环境变量
Linux 系统中有许多预定义的环境变量,以下是最常见的几个:
环境变量 作用 示例 PATH 指定命令的搜索路径,系统会按该路径顺序查找可执行程序 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin HOME 指定用户的主工作目录,即用户登录系统后的默认目录 普通用户为 /home/xxx,root 用户为/rootSHELL 指定当前使用的 Shell,Linux 默认通常是 /bin/bash/bin/bash
(三)查看环境变量的方法
最直接的方式是使用
echo命令,格式为echo $变量名。
- 单变量查看:
echo $变量名,如echo $PATH。- 批量查看:
env显示所有环境变量;set显示本地 Shell 变量和环境变量。
(四)举例
1、PATH环境变量测试
将以上简单的代码编译成可执行程序后,我们来对比两种执行方式:
- 带路径执行:
./hello
- 直接执行:
hello
问题来了,为什么系统命令(如
ls、cd)可以直接执行,而我们的hello程序必须带路径?那是因为系统命令的可执行文件位于
PATH环境变量指定的路径中,系统会自动搜索;而hello所在路径不在PATH中,所以必须手动指定路径。所以我们可以试试将程序路径加入PATH:
export PATH=$PATH:程序实际所在路径
直接执行
hello,此时程序可以正常运行。2、HOME环境变量测试
- root 用户执行:
echo $HOME,输出/root。
- 普通用户执行:
echo $HOME,输出/home/xxx(xxx 为用户名)。
如下图,执行
cd ~; pwd,输出的路径与$HOME的值一致,说明~是HOME的简写。
(五)与环境变量相关的命令
命令 功能 echo 显示单个环境变量的值 export 设置新的环境变量(或导出已有变量为环境变量) env 显示所有环境变量 unset 清除环境变量 set 显示本地定义的 Shell 变量和环境变量
(六)环境变量的组织方式
每个程序都会收到⼀张环境表,环境表是⼀个字符指针数组,每个指针指向⼀个以’\0’结尾的环境字符串。
(七)通过代码获取环境变量
在 C 语言中,有两种常见方式获取环境变量。
方式 1:通过
main函数的第三个参数
main函数可以接收第三个参数char *env[],它指向环境变量表。#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; }运行的结果和使用env命令一样。
方式 2:通过全局变量
environ#include <stdio.h> int main(int argc, char *argv[]) { extern char **environ; int i = 0; for(; environ[i]; i++){ printf("%s\n", environ[i]); } return 0; }
libc中定义了全局变量environ,它指向环境变量表。由于environ未包含在头文件中,使用时需用extern声明。
(八)通过系统调用获取或设置环境变量
Linux 提供了系统调用函数来获取或设置环境变量,常用的有
getenv和putenv(后面讲解)。函数
getenv:获取指定环境变量的值函数原型:
char *getenv(const char *name);#include <stdio.h> #include <stdlib.h> // getenv需要的头文件 int main() { printf("%s\n", getenv("PATH")); return 0; }
(九)环境变量的全局属性
环境变量具有全局属性,可以被子进程继承。我们通过一个例子来验证这一点。
#include <stdio.h> #include <stdlib.h> int main() { char *env = getenv("MYENV"); if(env){ printf("%s\n", env); } return 0; }直接运行程序,无输出(因为
MYENV环境变量不存在)。此时我们导出环境变量MYENV:
export MYENV="hello world"再次运行程序:
说明子进程(我们的程序)继承了父进程(Shell)的环境变量。
但当我们执行MYENV="hello world“(不export)时,这个变量仅属于当前 Shell 的本地变量(Local Variable),其作用域仅限于当前 Shell 进程本身,不会被子进程(例如我们编译的 C 程序)继承。
原理分析:
- Shell 进程在创建子进程时,会将自己的环境变量(通过
export声明的变量)复制一份传递给子进程,但本地变量不会被复制。- 因此,直接执行
MYENV="hello world"后运行程序,子进程中无法获取MYENV;而通过export MYENV="hello world"声明后,MYENV成为环境变量,才能被子进程继承。
(十)环境变量的持久化设置
临时通过
export设置的环境变量,会在当前 Shell 关闭后失效。若需环境变量永久生效(系统重启后仍可用),需修改系统配置文件,具体分为以下两种场景:
- 对所有用户生效(全局设置)
修改
/etc/profile或/etc/environment文件(需 root 权限),所有用户登录后均可使用该环境变量。(以修改/etc/profile为例)1、使用 root 权限打开文件
sudo vim /etc/profile2、在文件末尾添加环境变量声明
export MYENV="hello world" # 格式:export 变量名=值(值若含空格需用引号包裹)3、无需重启,执行以下命令让系统重新加载配置文件:
source /etc/profile
仅对当前用户生效(局部设置)
修改当前用户主目录下的
~/.bashrc或~/.bash_profile文件(无需 root 权限),仅当前用户可使用该环境变量。(以修改~/.bashrc为例)1、打开文件
vim ~/.bashrc # 或 gedit ~/.bashrc2、在文件末尾添加环境变量声明
export MYENV="hello world"3、使配置立即生效
source ~/.bashrc # 重新加载当前用户的配置文件注意事项:
- 配置文件中的环境变量声明必须带
export,否则仅为文件所在 Shell 的本地变量,无法被子进程继承。- 若同时修改了全局和局部配置文件,局部配置会覆盖全局配置(优先级:
~/.bashrc>~/.bash_profile>/etc/profile)。- 对于
~/.bash_profile和~/.bashrc的区别:
~/.bash_profile仅在用户登录时加载(如通过ssh登录或图形化界面登录);~/.bashrc在每次打开新的终端窗口时加载,更适合日常临时添加的环境变量,推荐优先使用。
二、命令行参数
(一)基本概念
命令行参数是用户在启动程序时,通过命令行传递给程序的参数,用于控制程序的行为、指定输入输出等。例如
ls -l /home中,-l和/home都是ls命令的命令行参数。
(二)命令行参数在 C 程序中的表示
想必大家对这两个参数都很眼熟,但是我们并不知道是干什么用的。
C 程序通过
main函数的前两个参数接收命令行参数:
int argc:参数个数(argument count),包含程序名本身。char *argv[]:参数数组(argument vector),每个元素是一个参数字符串,argv[0]是程序名,argv[1]到argv[argc-1]是用户传入的参数。例如:
#include <stdio.h> int main(int argc, char *argv[]) { printf("参数个数 argc = %d\n", argc); for (int i = 0; i < argc; i++) { printf("argv[%d] = %s\n", i, argv[i]); } return 0; }
三、命令行参数与环境变量的区别与联系
对比项 命令行参数 环境变量 作用域 仅对当前启动的程序有效 具有全局属性,可被子进程继承 传递时机 程序启动时通过命令行传递 程序启动前已由系统或用户设置 修改方式 需重新启动程序并传入新参数 可通过 export、修改配置文件等方式动态修改(或持久化)联系 两者都是程序与外部交互的方式,共同决定程序的运行行为
更多推荐













所有评论(0)