深入学习Linux: 命令行参数与环境变量详解

文章目录

  • [1. 命令行参数](#1. 命令行参数)
    • [1.1 main函数的参数](#1.1 main函数的参数)
    • [1.2 命令行参数的作用](#1.2 命令行参数的作用)
  • [2. 环境变量](#2. 环境变量)
    • [2.1 理解一个问题](#2.1 理解一个问题)
    • [2.2 PATH环境变量](#2.2 PATH环境变量)
    • [2.3 其他环境变量](#2.3 其他环境变量)
  • [3. C/C++代码与进程之间的关系](#3. C/C++代码与进程之间的关系)
    • [3.1 用代码获取环境变量](#3.1 用代码获取环境变量)
      • [3.1.1 main函数最多有几个参数?](#3.1.1 main函数最多有几个参数?)
      • [3.1.2 shell外壳里的环境变量是哪里来的?](#3.1.2 shell外壳里的环境变量是哪里来的?)
    • [3.2 获取环境变量的若干种方法](#3.2 获取环境变量的若干种方法)
    • [3.3 环境变量、本地变量、内建命令](#3.3 环境变量、本地变量、内建命令)
      • [3.3.1 创建自己的环境变量](#3.3.1 创建自己的环境变量)
    • [3.4 内建命令](#3.4 内建命令)

1. 命令行参数

1.1 main函数的参数

main函数是可以有参数的。main函数的参数由bash和系统自动传递。命令行参数的本质是一个字符串,shell以空格为分割符号,切成了若干的子串。

细节一:命令行参数至少是1,argc>=1,argv0一定会有元素,指向的就是程序名。

细节二:选项是以空格分割的字符串,一个字符也是字符串。

细节三:argv的本质是一张表,元素由argc决定,argvargc是最后一个,且始终为NULL。

1.2 命令行参数的作用

为什么要有命令行参数?命令行参数的本质应用,是为了实现一个命令可以根据不同的选项,实现不同的子功能。也是Linux中所有命令选项功能的实现方式。问题:VS2022有没有命令行参数?有的。cat file.txtcat < file.txt 如何打印出文件内容?本质是通过命令行参数,将文件打开,打开后读文件,打印内容。

2. 环境变量

2.1 理解一个问题

环境变量具有全局属性的根本原因是:环境变量可以被bash进程的子进程继承,所有在Linux下的子进程都会拥有对应的环境变量。

./ 的本质是相对路径,本质是告诉OS,用户要执行的bin,就在当前路径下。

2.2 PATH环境变量

Linux怎么知道我应该去哪一个路径下找可执行程序?除了去 /usr/bin 路径下去找,还会不会去其他路径下去找?Linux系统,会存在所谓的环境变量的东西。

PATH是该环境变量的变量名:

bash 复制代码
echo $PATH

以冒号为分割符的多串路径,告诉Linux系统,如果用户执行一个可执行文件,没有指明路径,去哪几个路径下去找?

PATH的本质是协助Linux进行指令查找的环境变量。

如何将路径配置到环境变量里?就可以执行的时候不带有 ./

bash 复制代码
PATH=[你的路径]

你这么写就直接覆盖了:

bash 复制代码
PATH=$PATH:[你想要添加的路径]

总结:

PATH:指定命令的搜索路径。

PATH环境变量是全局的。

2.3 其他环境变量

系统级的变量,变量名和变量内容,往往具有全局属性。

还有没有其他环境变量?查询:

bash 复制代码
env

介绍其余环境变量:

bash 复制代码
echo $HISTSIZE

记忆你之前使用过的命令,默认是1000,统计最近使用的1000条命令。

bash 复制代码
echo $OLDPWD

记忆用户在运行时上一次所存在的工作路径。

bash 复制代码
echo $SSH_TTY

记录终端文件,终端窗口不一样,输入重定向对内容进行重新输入。

PATH :指定命令的搜索路径。当你在命令行输入一个命令时,系统会按照 PATH 中列出的目录顺序依次查找对应的可执行文件。

HOME :当前用户的主目录路径。执行 cd ~cd 不带参数时,就会跳转到该目录。不同用户的 HOME 不同,例如 /home/zhangsan/root

SHELL :当前用户所使用的 Shell 解释器的路径。常见的有 /bin/bash/bin/zsh 等,决定了你在终端中使用的命令解释器类型。

3. C/C++代码与进程之间的关系

3.1 用代码获取环境变量

3.1.1 main函数最多有几个参数?

三个参数,拿到系统的环境变量表,本质是将环境变量表传递给进程。

有什么用?不同的环境变量有不同的用途。

是谁传递的?怎么传递的?

环境变量在bash没有拿到的时候在哪里?

是谁传递给你的?默认是在bash内部的,bash本质是一个进程,是存储在内存中的,是临时表,内存级的。我的程序都是bash进程的子进程,子进程代码和数据是可以共享的,是父进程传递的。

所以环境变量具有全局属性。

存在两张环境变量表,当我们运行程序时,bash会fork出一个子进程,子进程可以看到父进程的参数。所以说,不传参数也能看到环境变量的原因是,子进程进行了继承。

不传参数怎么获取环境变量?

子进程都是bash的子进程,你可以获得bash的表,子进程天然可以继承父进程的数据。

语言会默认提供全局变量,全局的指针可以指向环境变量表。获取环境变量的第二种方式。

需要记住的是,环境变量可以被获取。

bash有两张表,一张是命令行参数表,一张是环境变量表。

3.1.2 shell外壳里的环境变量是哪里来的?

bash的环境变量是哪里来的?是从Linux系统的配置文件里面来的,启动时会把配置文件加载进来,所以当时你改的是内存级的数据,你关掉Xshell又打开会重新从配置文件中加载。

什么是配置文件,配置文件又是哪里来的?

家目录存在两个配置文件:

.bashrc

.bash_profile

上面的两个文件其实是相关的。

bash在启动时,会访问 .bashrc 文件,会将配置文件载入,修改一下就可以看到bash被执行,echo一行字就可以了。

root怎么不执行?每一个人都会有自己的家目录,改的不是root的配置文件。

为什么会给每个用户都搞一个bash?

bash 复制代码
while :; do ps axj | grep bash ; sleep 1; done
while :; do ps axj | grep bash ; sleep 1; echo "#############"; done

每开一个窗口就会有一个bash,每个子进程都会加载一个环境变量。

最常见:

bash 复制代码
man getenv

原理是,根据名字查找环境变量的内容,根据环境变量名遍历这张表,并依次比较,遍历成功将右边返回,失败返回NULL。

如何用C/C++获取环境变量:

C 复制代码
char *whoami = getenv("USER");

3.2 获取环境变量的若干种方法

环境变量的作用是限制程序的执行。

获取环境变量的三种做法:

  1. main函数参数:char* env[]
  2. C语言全局变量:char** environ
  3. 最佳实践:getenv(name)

测试:限制访问用户名。

3.3 环境变量、本地变量、内建命令

3.3.1 创建自己的环境变量

我想创建一个自己的环境变量怎么办?

bash 复制代码
test_env=12344
env | grep TEST_ENV

存在但env不到,这个叫本地变量。

导出成环境变量:本质是在将本地变量放到环境变量表里,你就可以查到了:

bash 复制代码
export TEST_ENV

再次查询就有了。

如果这个本地变量本来就没有,可以用export直接导也可以:

bash 复制代码
export AAA=asdfghj

能不能被自己的C语言程序获得?

C 复制代码
getenv("TEST_ENV");

子进程是可以获得父进程环境变量的,环境变量是全局的本质:环境变量是可以被子进程继承的。

如何删除环境变量:

bash 复制代码
unset [环境变量名]

取消命令行的环境变量:本质就是将环境变量,从环境变量表中删除。

其实,这些也都是内存级的,关掉重新打开就好了。

本地变量和环境变量的区别:本地变量无法被子进程继承,不具备全局性,只在bash内部可以访问!!

类比于局部变量和全局变量。

为什么要有本地变量?

bash 复制代码
cnt=0; while [ $cnt -le 100 ]; do echo $cnt; let cnt++; done

shell当中的本地变量是为了支持语法的,用于保存一些临时信息。

bash 复制代码
set

可以查询系统变量和环境变量。

如果我想让我的环境变量关掉打开后还有,打开 .bash_profile,在里面export导入一个环境变量。

3.4 内建命令

提出问题:

本地变量只能在shell内部运行,不能被子进程继承。

echo子进程看不到本地变量是如何被打印的?

  1. echo这个进程是怎样能打印本地变量的?

命令和命令是不一样的,存在二进制文件级别的命令:

普通命令:

内建命令:在shell内部自己定义,bash自己内部的一次函数调用,不依赖第三方路径。

内建命令是shell自己的,意味着内建命令的执行不需要环境变量。


欢迎大家批评指正!!!

相关推荐
会飞的小新1 小时前
《深入理解 DDR Memory Margin》系列之第四章 从 Bit Error 到 ECC——服务器为什么能够发现内存错误?
运维·服务器
Shadow(⊙o⊙)1 小时前
日志与线程池
linux·c++·算法
樂禮1 小时前
Windows-Arch Linux 键鼠共享 & 剪贴板同步配置
linux·运维·windows
CHANG_THE_WORLD1 小时前
Linux C 多线程 TCP 并发服务器:从 `accept()` 到工作线程的完整解析
linux·服务器·c语言
影视飓风TIM2 小时前
Linux基础入门笔记:命令、内核架构与压缩传输全梳理
linux·笔记·架构
敲上瘾2 小时前
Linux系统调用mmap文件映射与malloc简单模拟实现指南
linux·服务器·c语言·缓存
wdfk_prog9 小时前
嵌入式面试真题第 10 题:高优化等级下共享状态可见性、内存模型与系统级同步设计
java·linux·开发语言·面试·职场和发展·架构·c
x-cmd10 小时前
Mac 涨价后,本地 AI 还能千元入门吗?
linux·人工智能·macos·ai·agent·amd·本地ai入门
Sirius Wu11 小时前
OpenClaw Skill:Matplotlib 可视化技能 + 沙箱双层隔离完整详解
服务器·网络·人工智能·安全·ai·架构·aigc