Linux环境变量与命令行参数全解析

文章目录

  • 前言---命令行参数
  • 1 .基本概念
    1. 常见环境变量
    1. 查看环境变量方法
  • 4.和环境变量相关命令
  • 5.组织方式
  • 6.通过代码获取环境变量
  • 7.通过系统调用获取/设置环境变量
  • 8.环境变量全局属性

前言---命令行参数

命令行参数在Linux进程中的C语言实现

在Linux操作系统中,进程启动时可以通过命令行参数接收外部输入。这些参数允许用户在执行程序时传递额外的信息,如选项或数据。在C语言中,命令行参数通过main函数的特定参数来处理。

1. 命令行参数的基础概念

在C语言中,main函数的原型为:

c 复制代码
int main(int argc, char *argv[]);
  • argc(argument count):这是一个整型变量,表示命令行参数的数量。包括程序名本身,所以最小值是1(当没有额外参数时)
  • argv(argument vector):这是一个字符指针数组(即字符串数组),每个元素指向一个命令行参数字符串。其中:
    • argv[0] 通常是程序的名称或路径。
    • argv[1]argv[argc-1] 是用户传递的额外参数。
    • argv[argc] 是一个空指针(NULL),表示数组的结束。

例如,如果用户执行 ./myprogram arg1 arg2,那么:

  • argc = 3
  • argv[0] = "./myprogram"
  • argv[1] = "arg1"
  • argv[2] = "arg2"
2. C语言代码示例
c 复制代码
#include <stdio.h>

int main(int argc, char *argv[]) {
    // 打印参数数量
    printf("Total arguments: %d\n", argc);
    
    // 遍历并打印所有参数
    for (int i = 0; i < argc; i++) {
        printf("Argument %d: %s\n", i, argv[i]);
    }
    
    return 0; // 正常退出
}
3. 如何处理命令行参数

在实际应用中,命令行参数常用于配置程序行为:

  • 解析选项 :例如,使用-v表示详细模式。可以通过比较argv[i]的内容来实现。
  • 参数验证 :检查参数数量(argc)是否在预期范围内,避免错误。
  • 类型转换 :如果参数是数字,使用atoistrtol函数将字符串转换为数值。

示例:添加一个选项处理逻辑。

c 复制代码
#include <stdio.h>
#include <stdlib.h> // 用于atoi函数

int main(int argc, char *argv[]) {
    int verbose = 0; // 默认为非详细模式
    
    // 检查是否有-v选项
    for (int i = 1; i < argc; i++) {
        if (strcmp(argv[i], "-v") == 0) {
            verbose = 1;
            printf("Verbose mode enabled.\n");
        }
    }
    
    // 其他处理...
    return 0;
}

1 .基本概念

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

2. 常见环境变量

  • PATH: 这是最重要的环境变量之一。它定义了当用户在命令行输入一个命令时,系统搜索该命令可执行文件的目录列表。目录之间用冒号 : 分隔。例如:
awk 复制代码
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
 
  • HOME****: 指向当前用户的家目录(主目录)。例如:/home/username
  • USER****: 当前登录用户的用户名。
  • SHELL****: 当前用户使用的Shell程序的路径(如/bin/bash)。
  • PWD: 当前工作目录(Print Working Directory)。
  • LANG, LC_ALL, LC_*: 这些变量用于设置系统的语言环境(Locale),影响程序的语言、字符编码、日期时间格式等。
  • TERM: 定义当前使用的终端类型(如xterm-256color),这对于需要了解终端功能的程序(如文本编辑器)很重要。
  • PS1: 定义了Shell的主要提示符的格式。
  • EDITOR / VISUAL: 定义默认的文本编辑器(如vimnano)。
  • TMPDIR / TEMP: 定义临时文件的存储目录。

3. 查看环境变量方法

printenv 命令:

查看所有环境变量printenv

查看特定环境变量printenv VARIABLE_NAME (例如 printenv PATH)

env 命令: 功能与 printenv 类似,主要用于在修改后的环境中运行命令,但单独使用时也显示所有环境变量:env

echo 命令 (Shell内置): 在Shell中,可以直接使用 echo 打印变量值。注意: 需要在变量名前加上 $

bash 复制代码
echo $PATH
 

4. 和环境变量相关命令

  • printenv: 如上所述,用于打印环境变量。
  • env: 如上所述,用于打印环境变量或在指定环境变量设置下运行命令
routeros 复制代码
env VARIABLE1=value1 VARIABLE2=value2 command_to_run
 
  • export (Shell内置命令): 用于将Shell变量提升为环境变量,使其可被子进程继承。也可用于设置或修改环境变量(仅对当前Shell及其子进程有效)。
elixir 复制代码
export MY_VAR="Hello World" # 设置并导出
export PATH=$PATH:/my/new/path # 修改PATH
 
  • set (Shell内置命令): 在Bash等Shell中,set 会显示所有Shell变量(包括环境变量和未导出的局部变量)以及Shell函数。输出通常很长。
  • unset (Shell内置命令): 用于删除一个Shell变量或环境变量。
bash 复制代码
unset MY_VAR # 删除变量
 

5 .组织方式

cpp 复制代码
char *env[] = {
    "PATH=/usr/bin:/bin",
    "HOME=/home/user",
    "USER=user",
    NULL // 结束标志
};
 

6. 通过代码获取环境变量

c 复制代码
#include <stdio.h>
#include <stdlib.h>

int main() {
    // 获取 PATH 环境变量的值
    char *path_value = getenv("PATH");

    if (path_value != NULL) {
        printf("PATH value is: %s\n", path_value);
    } else {
        printf("PATH environment variable not found.\n");
    }

    // 获取 USER 环境变量的值
    char *user_value = getenv("USER");
    if (user_value != NULL) {
        printf("Current user is: %s\n", user_value);
    }

    return 0;
}
 

7. 通过系统调用获取/设置环境变量

c 复制代码
#include <stdio.h>
#include <stdlib.h>

int main() {
    // 设置一个新的环境变量
    if (setenv("MY_APP_MODE", "DEBUG", 1) != 0) { // 1 表示覆盖已存在的值
        perror("setenv failed");
        return 1;
    }

    // 获取并打印新设置的环境变量
    char *mode = getenv("MY_APP_MODE");
    if (mode) {
        printf("MY_APP_MODE is set to: %s\n", mode);
    }

    return 0;
}
 

使用 setenv()putenv() 等函数修改的是当前进程的环境变量副本。这些修改不会影响父进程或其他进程。

8. 环境变量全局属性

虽然环境变量在单个进程内是"全局"可见的,并且可以通过继承机制影响子进程,但需要理解其局限性

  • 非系统级全局: 环境变量不是操作系统内核维护的全局数据库。它们是按进程存储的。修改一个进程的环境变量不会自动改变系统中其他进程(包括其父进程)的环境变量。
  • 作用域: 环境变量的"全局性"主要体现在:
    1. 进程内全局: 进程内的所有代码都可以访问其环境变量。
    2. 继承链: 通过进程创建 (fork + exec) 的父子关系链,环境变量可以沿着这条链向下传播。登录Shell(如Bash)会读取配置文件(如~/.bashrc, /etc/profile)设置环境变量,然后所有从该Shell启动的程序(子进程)都会继承这些变量。
  • 持久化: 为了使环境变量设置对新的Shell会话有效,需要将其写入Shell的启动配置文件(如 ~/.bashrc, ~/.profile, /etc/environment)。这样,每次启动Shell时,这些配置都会被读取并设置到Shell进程的环境中,进而传播给其子进程。
  • 用户隔离: 不同用户拥有各自的家目录和Shell配置文件,因此他们的环境变量设置通常是隔离的。
相关推荐
淮北4942 小时前
GDB在ubuntu上的安装与使用
linux·运维·ubuntu
shhpeng2 小时前
在 Ubuntu 24.04 上安装 Go1.24.2
linux·运维·ubuntu
颖风船2 小时前
vscode连接vmware中的deepin虚拟机,deepin端配置
linux·ide·vscode
苏宸啊2 小时前
Linux工具
linux
Vect__2 小时前
进程间通信之管道
linux
源远流长jerry3 小时前
DPDK 实现的轻量级 UDP 回显服务程序
linux·运维·服务器·网络·网络协议·ip
A-刘晨阳3 小时前
【Linux】Prometheus + Grafana的使用
linux·运维·grafana·prometheus·监控
Mr_Xuhhh3 小时前
字节跳动面经
linux·服务器
早日退休!!!3 小时前
Linux内核内存布局:核心原理与工程实践
linux