【Linux】命令行参数与环境变量

🌟🌟作者主页:ephemerals__****

🌟🌟所属专栏:Linux

目录

前言

一、命令行参数

[1. 什么是命令行参数](#1. 什么是命令行参数)

[2. 命令行参数的作用](#2. 命令行参数的作用)

二、环境变量

[1. 基本概念](#1. 基本概念)

[2. 常见的环境变量](#2. 常见的环境变量)

[3. 环境变量相关操作](#3. 环境变量相关操作)

定义一个新的环境变量

删除一个环境变量

查看所有的环境变量

查看某个环境变量的内容

修改环境变量

[4. 从存储角度理解环境变量](#4. 从存储角度理解环境变量)

总结


前言

在日常使用和开发中,Linux命令行以其强大而灵活的特性备受欢迎。而命令行参数与环境变量则是驱动这一强大工具的核心元素。通过合理地使用参数,我们可以精确控制命令的行为;借助环境变量,则能够配置和影响系统及程序的运行环境。本文将带你了解Linux命令行参数和环境变量的基础知识,帮助你更高效地驾驭Linux系统。

一、命令行参数

1. 什么是命令行参数

在Linux下,你可以在使用指令时加上一些选项,例如:

bash 复制代码
ls -a -l

这里的"-a""-l"都是命令行参数。通过输入不同的参数,就可以使指令产生不同的效果。那么它具体是如何实现的呢?

想必大家都或多或少地见过,c语言的main函数有这样的写法:

cpp 复制代码
int main(int argc, char* argv[])
{
    //...
}

实际上我们在执行程序时,输入的参数就会转化为一个个字符串,形成一个全局的命令行参数表,并存入main函数的参数当中。main函数获取到这些参数之后,就可以对这些参数进行不同的处理,从而产生不同的效果。

其中,argc是一个整数,表示命令行参数的个数;argv是一个char*指针数组,指向一个个命令行参数。

接下来我们尝试写一个简单的程序,获取命令行参数并一个个打印:

cpp 复制代码
#include <stdio.h>

int main(int argc, char* argv[])
{
    //遍历指针数组并打印参数
    for(int i = 0; i < argc; i++)
    {
        printf("第%d个参数:%s\n", i + 1, argv[i]);
    }
    return 0;
}

运行程序:

可以看到程序获取到我们输入的参数,并一个一个打印了出来。这里需要注意:执行程序时输入的路径+程序名"./a.out"算第一个参数

argv的末尾是一个空指针,所以无需argc也可以确定参数的数量,访问到所有参数。

2. 命令行参数的作用

通过命令行参数,我们在启动程序时就可以通过输入不同的参数,实现不同的子功能,从而做到定制程序的运行方式,无需修改源代码或重新编译。例如:可以指定输入输出文件、设置运行模式、调整算法参数等。

二、环境变量

1. 基本概念

环境变量的本质是一个以'\0'为结尾的字符串 ,它一般用于告诉操作系统某些程序的运行环境 。举个例子:我们都知道ls、man、pwd这些Linux内置的命令的本质都是可执行程序,它们都位于根目录下的usr/bin路径中。在执行这些程序时,我们不需要输入它完整的所在路径,而只需输入程序名即可。但如果是我们自己在某个目录下写的程序,执行时就要带上路径"./"。这是为什么呢?

Linux系统存在一个叫做PATH 的环境变量,它告诉命令行解释器应该去哪个路径下寻找可执行程序,当执行这些内置命令时,默认去PATH中寻找,根据PATH指定的路径执行相应的程序。

我们可以输入以下命令查看环境变量PATH的内容

bash 复制代码
echo $PATH

运行结果:

可以看到PATH当中有6个路径,以冒号 作为分割,操作系统就会按照从左到右的顺序依次在这6个路径中查找程序的位置,然后执行

当然,我们也可以给PATH重新赋值

bash 复制代码
PATH=(路径名)

也可以给PATH添加一个新的路径

bash 复制代码
export PATH=$PATH:(路径名)

如果让我们写的程序位于PATH指明的路径当中(例如在环境变量中添加当前路径或者将程序移动到环境变量指明的路径当中),那么执行时也就无需输入其所在路径了。

如果我们修改了PATH的内容,重启Bash后PATH就会恢复。这是因为环境变量是在我们启动Bash时从系统的配置文件中加载而来的,是内存级数据。如果想要永久性地改变环境变量的内容,就需要修改对应的配置文件。

2. 常见的环境变量

HOME:当前用户的家目录

USER:当前用户

LOGNAME:最初登入时的用户

SHELL:当前shell的位置

HISTSIZE:历史命令的最大记录个数

HOSTNAME:主机名

PWD:当前所在路径

OLDPWD:上次所在的路径

3. 环境变量相关操作

定义一个新的环境变量

bash 复制代码
export (环境变量=值)

删除一个环境变量

bash 复制代码
unset (环境变量名)

查看所有的环境变量

bash 复制代码
env
printenv

查看某个环境变量的内容

bash 复制代码
echo $(环境变量名)

修改环境变量

bash 复制代码
export (环境变量名)=(值)  # 给环境变量重新赋值

这种情况下,修改后的环境变量会被设置成本地变量 ,本地变量不会被子进程所继承,也就是说这个新的值只对当前的shell有用,对于我们在shell中使用的**非内建命令(需要创建子进程)**是无用的。

在shell中启动的大多数程序都是shell创建的子进程,而内建命令 无需shell创建子进程,而是通过shell自己调用函数或系统调用来完成任务。例如export、pwd等都是内建命令。

如果在这之前加上export:

bash 复制代码
export (环境变量名)=(值) 

那么就修改了环境变量,子进程也可以看得到。

4. 从存储角度理解环境变量

当bash启动时,会从操作系统的相关配置文件中读取环境变量,存入bash对应的全局的环境变量表当中。

与命令行参数表相同,环境变量表 的本质也是一个字符串数组。当创建子进程后,子进程就会继承父进程的环境变量表,因此环境变量可以被子进程继承

环境变量可以被子进程继承的意义:支持开发一些个性化程序,例如通过识别当前用户,开发只能特定用户才能执行的程序等

实际上,main函数还可以有第三个参数char* env[],表示环境变量表,由其父进程继承而来。有了它,我们就可以在代码层面访问环境变量。示例如下:

cpp 复制代码
#include <stdio.h>

int main(int argc, char* argv[], char* env[])
{
    //遍历环境变量表
    for(int i = 0; env[i]; i++)
    {
        printf("%s\n", env[i]);
    }
    return 0;
}

执行程序:

可以看到,程序打印出所有的环境变量。

当然,除了接收参数env的方式,还有其他方式也可以让我们在代码层面访问环境变量。例如声明外部变量"extern char** environ",它是一个指向环境变量表首元素的二级指针,通过它也可以访问到环境变量。

在实际开发当中,我们一般会使用getenvputenv这两个c语言函数来获取或导入环境变量。它们的使用方法如下:

cpp 复制代码
#include <stdlib.h>

char *getenv(const char *name); // 获取环境变量的值

**参数:**环境变量名

返回值: 指向对应环境变量的值的指针,如果没有,则返回NULL。

注意:返回的环境变量不要试图修改或释放。

cpp 复制代码
#include <stdlib.h>

int putenv(char *string); // 导入新的环境变量/给环境变量重新赋值

参数:(环境变量)=(值)

**返回值:**成功返回0,否则返回非0值

总结

本篇文章,我们学习了命令行参数以及环境变量的相关知识,有了命令行参数和环境变量,程序功能灵活性大大提升。如果你觉得博主讲的还不错,就请留下一个小小的赞在走哦,感谢大家的支持❤❤❤

相关推荐
love530love11 分钟前
cuDNN 9.9.0 便捷安装-Windows
运维·windows·python
天选之子1231 小时前
文本解析到大模型应用
服务器·开发语言
love530love1 小时前
将 virtualenv 环境迁移到 Conda 环境
运维·windows·python·conda·virtualenv
一刀到底2111 小时前
从实列中学习linux shell12 通过Shell脚本来优化MySQL数据库性能,特别是慢SQL跟踪和索引优化
linux·数据库·shell
ephemerals__2 小时前
【Linux】深入理解程序地址空间
linux·运维·服务器
吴声子夜歌2 小时前
Linux运维——Vim技巧一
linux·运维·vim
JhonKI2 小时前
【Linux网络】I/O多路转接技术 - epoll
linux·运维·网络·tcp/ip
42fourtytoo2 小时前
从0开始建立Github个人博客(hugo&PaperMod)
运维·服务器·python·go·github
迷茫运维路2 小时前
基于Jenkins的DevOps工程实践之Jenkins共享库
运维·jenkins·devops
伤不起bb2 小时前
Nginx 核心功能之正反代理
linux·服务器·nginx