当前位置: 首页 > news >正文

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

1.命令行

前⾯写C语⾔时,很少关注过 main 函数的参数,也没有考虑过 main 为什么会有参 数。

实际上在C语⾔中, main 函数⼀共有三个参数,在命令⾏部分先关注前两个参数:

1. argc:表示 main 函数接收到参数个数

2. argv:表示 main 函数接收的参数

根据下⾯的代码观察这两个参数具体的效果:

#include <stdio.h>int main(int argc, char* argv[]) {printf("%d\n", argc);for(int i = 0; i < argc; i++) {printf("%s\n", argv[i]);}
}

对应的 Makefile 如下:

TARGET=test 
SRC=test.c$(TARGET):$(SRC)gcc $^ -o $@ -std=c99.PHONY:clean
clean:rm -f $(TARGET)

直接运⾏程序可以看到下⾯的结果:

如果在输入./test后,再输入一些字符串可以看到下面的结果:

可以看到, argc 的值即为终端上包括 ./test 在内的所有字符串的个数,⽽ ⼀个字符串数组,存储着终端上包括 argv 是 ./test 在内的以空格间隔的字符串,这个数组 的最后⼀个元素就是 NULL 。这就是 main 函数的两个参数。

前⾯提到Linux下的命令都是⽂件,并且因为Linux是C语⾔编写的,所以所有命令 所带有的选项即为存储在 argv 数组中的字符串,⽽根据不同的参数值实现不同的功 能就可以通过类似于下⾯的形式完成:

#include <stdio.h>
#include <string.h>int main(int argc, char* argv[])
{if(argc == 1) {printf("默认功能\n");} else if(strcmp(argv[1], "-f1")==0) {printf("功能1\n");}return 0;
}

2.简单介绍命令如何传递

在Linux下输⼊的命令⾸先会被Shell拿到。

前⾯提到⽗进程和⼦进程的代码是共有的,但是⼆者数据是各⾃独⽴的,但是数据独 ⽴实际上只会建⽴在其中⼀个进程修改了数据,如果⼆者都是对变量进⾏只读不写, 那么也没有必要单独为两个进程开辟两个数据空间

对于上⾯的情况亦是如此,直接在终端上执⾏的进程,其⽗进程都是Shell,并且⽗ 进程和⼦进程都只是以只读的⽅式访问 main 函数的参数,所以就不会出现两个数据 空间。

从上⾯的过程中也可以看出,在设计操作系统、编程语⾔等时,相互都是存在依赖关系的

3.环境变量

前⾯提到 main 函数参数实际上有三个,⽽这第三个参数就是所谓的环境变量 env , 与argv⼀样, env 是⼀个字符串数组

使⽤下⾯的代码可以看到其中的内容:

#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;
}

需要注意的是,因为 argc 只能表示 argv 中的参数个数,所以对于循环终⽌条件来 说,因为env的最后⼀个位置时 NULL ,所以读取到 NULL 即可停⽌

运⾏上⾯的代码,可以看到结果是⼀堆字符串,这些字符串就是所谓的环境变量

在Linux中,环境变量和对应的值都是键值对的形式,⼀共有三种⽅式查看系统中的 环境变量:

1. 程序中遍历 env 数组

2. env指令

3. 使⽤ environ 指针访问

environ 本质是⼀个⼆级指针,其指向的是每⼀个环境变量的地址,所以通过下⾯ 的代码也可以访问到所有的环境变量:

#include <stdio.h>
#include <unistd.h>// 引入外部变量
extern char** environ;int main() {for(int i = 0; environ[i]; i++) {printf("%s\n", environ[i]);}return 0;
}

4.环境变量PATH

PATH指定了命令默认搜索的位置,因为其值中默认是/ /bin,所以命令执⾏是 会默认去/bin⽬录下找,所以前⾯将⾃⼰写的程序移动到/bin路径下就可以运⾏ 是因为默认从/bin路径下搜索

可以使⽤echo $PATH查看当前⽤户的PATH环境变量的值

也可以使⽤echo ${PATH},此处的{}表示限定变量的边界

如果需要修改PATH值,可以使⽤PATH=指定的路径,但是这种⽅式只是修改了位于 内存的系统进程中对应的PATH,⽽不会影响到本地配置⽂件中的PATH,并且这种 ⽅式会覆盖当前系统进程中的PATH值。

通过上述⽅式修改只需要退出当前⽤户再重新登陆即可重新加载对应的配置⽂ 件中的PATH

如果需要修改PATH对应的配置⽂件,可以到⽤户的家⽬录下找到.bash_profile ⽂件,修改其中的PATH值为需要的值即可

5.环境变量HOME

在Linux中,HOME环境变量指定了每⼀个⽤户的家⽬录,对于root⽤户来说,其值 即为/root,对于普通⽤户该值即为/home/⽤户名

使用  echo $HOME  来查看:

在⽤户登录时,⾸先bash会从配置⽂件中加载对应的值到HOME中,此时bash进程 中的cwd就是家⽬录,因为HOME的值为当前⽤户的家⽬录,⽽因为⼤部分运⾏在 bash进程之上的指令都是bash进程的⼦进程,⼦进程会与⽗进程共⽤⼀块数据, 所以⼦进程的cwd与⽗进程的cwd相同。所以如果直接在家⽬录运⾏⼀个普通的程 } 14 序时,查看其 cwd 值可以看到结果与⽗进程相同,例如下⾯的结果:

需要注意,并不是所有的命令都是 bash 进程的⼦进程,例如 cd 命令

cd 命令并不是⼀个单独的进程,⽽是⼀个内建(built-in)命令。所以如果使⽤ cd 改变当前 bash 的⼯作路径, cd 指令通过 chdir 函数对 bash 进程中的数据直接 进⾏修改,从⽽达到直接改变 bash 进程的 cwd ,例如下⾯的效果:

为了更加直观得看到当前 bash 进程的PID ,可以使⽤ echo $$命令,其中的$$ 就代表当前 bash 的 PID

6.环境变量PWD

在Linux中, PWD 中的值为当前⽤户所处的⼯作路径,所以使⽤pwd 命令查看当前的⼯作路径实际上就是在读取 PWD 中的值

PWD ⼀般⽤于进程在当前⼯作路径下创建⼀个⽂件,在标准库中提供了⼀个函数为 getenv ,原型如下:

char *getenv(const char *name); // 参数传递环境变量名,返回环境变量值

只要获取到了当前路径,就可以在当前路径下创建⽂件

如果需要在程序中创建或修改⼀个环境变量,可以使⽤ putenv 函数,原型如下:

int putenv(char *string);// 参数传递一个键值对,如果指定的环境变量已经存在就实现修改,否则就是新增

对应的还有⼀个 OLDPWD 环境变量,该环境变量的值为上⼀次的⼯作路径,这也就是 为什么使⽤ cd -可以切换为上⼀次⼯作路径的原因

7.环境变量 SHELL

在Linux中, SHELL 表示当前使⽤的终端:

8.理解环境变量

环境变量本质是系统提供的具有全局属性的变量,既然是全局属性,则证明所有进程 都可以访问到环境变量,这个过程实际上就是通过进程之间的⽗⼦关系实现的,因为 环境变量本质是被 bash 进程从配置⽂件加载的,所以 bash 进程和其⼦进程就都可 以看到环境变量。在⼤部分情况下环境变量是不会被修改的,所以 程实际上是共⽤⼀块环境变量空间

前⾯提到有⼀些指令时内建指令,另⼀部分是外部命令,常⻅的内建命令还有 echo 和ex port

在Linux中, bash 是 shell 脚本语⾔的⼀种实现,⽽ shell 是⼀个命令⾏解释器, ⽤户通过它与操作系统进⾏交互,它可以运⾏命令、脚本和程序,所以可以在命令⾏ 直接创建⼀个变量,这种变量也被称为本地变量,例如:

本地变量与环境变量基本⼀致,只是本地变量不具有全局属性,即⽗⼦进程不会共享

使⽤set可以查看当前创建的本地变量和环境变量,如果想要清除指定的本地变量可以使⽤unset + 本地变量名

本地变量也可以使⽤ echo 命令输出:

如果需要将本地变量添加到环境变量,可以使⽤ export 命令,例如:

也可以直接将变量的初始化结合 export 使⽤:

相关文章:

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

1.命令行 前⾯写C语⾔时&#xff0c;很少关注过 main 函数的参数&#xff0c;也没有考虑过 main 为什么会有参 数。 实际上在C语⾔中&#xff0c; main 函数⼀共有三个参数&#xff0c;在命令⾏部分先关注前两个参数&#xff1a; 1. argc&#xff1a;表示 main 函数接收到参…...

改变函数调用上下文:apply与call方法详解及实例

目录 改变函数调用上下文&#xff1a;apply与call方法详解及实例 一、什么是 apply 方法&#xff1f; 1、apply 语法 2、apply 示例 二、什么是 call 方法&#xff1f; 1、call 语法 2、call 示例 三、apply 和 call 的共同与差异 1、apply 和 call 的共同点 2、apply…...

k8s中的微服务

一、什么是微服务 用控制器来完成集群的工作负载&#xff0c;那么应用如何暴漏出去&#xff1f;需要通过微服务暴漏出去后才能被访问 Service是一组提供相同服务的Pod对外开放的接口。 借助Service&#xff0c;应用可以实现服务发现和负载均衡。 service默认只支持4层负载均…...

树莓派--AI视觉小车智能机器人--1.树莓派系统烧入及WiFi设置并进入jupyterlab

一、Raspberry Pi 系统烧入 使用树莓派&#xff0c;我们是需要有操作系统的。默认情况下&#xff0c;树莓派会在插入的SD卡上查找操作系统。这需要一台电脑将存储设备映像为引导设备&#xff0c;并将存储设备插入该电脑。大多数树莓派用户选择microSD卡作为引导设备。 1.1 下载…...

MacOS安装BurpSuite

文章目录 一、下载地址二、下载注册机三、安装教程四、启动burpsuit五、免责声明 一、下载地址 https://portswigger-cdn.net/burp/releases/download?productpro&version2024.7.1&typeMacOsx二、下载注册机 https://github.com/NepoloHebo/BurpSuite-BurpLoaderKey…...

【AI工具大全】《史上最全的AI工具合集》

一.AI编程类工具 1.CodeArts Snap CodeArts Snap是华为云研发的智能开发助手,覆盖软件开发全生命周期,提供代码生成、研发知识问答、智能协同等功能。通过自然语言编程,它能自动生成代码、解释代码逻辑、提供调试与检查,提升开发效率和软件质量。 2.ModelArts ModelArt…...

qt继承结构

一、 继承结构 所有的窗口类均继承自QWidget类&#xff0c;因此QWidget类本身包含窗口的特性。QWidget对象本身既可以作为独立窗口&#xff0c;又可以作为组件&#xff08;子窗口&#xff09;。 通过构造函数可以创建以上两种形态的QWidget&#xff1a; // 参数1&#xff1a;使…...

【HCIA复习作业】综合拓扑实验(已施工完)

一、实验要求 1.学校内部的HTTP客户端可以正常通过域名www.baidu.com访问到百度网络中的HTTP服务器 2.学校网络内部网段基于192.168.1.0/24划分&#xff0c;PC1可以正常访问3.3.3.0/24网段&#xff0c;但是Pc2不允许 3.学校内部路由使用静态路由&#xff0c;R1和R2之间两条链路…...

网络基础知识:交换机关键知识解析

了解交换机的关键知识对网络工程师至关重要。 以下是交换机的基础知识解析&#xff0c;包括其基本概念、工作原理和关键技术点&#xff1a; 01-交换机的基本概念 交换机是一种网络设备&#xff0c;用于在局域网&#xff08;LAN&#xff09;中连接多个设备&#xff0c;如计算机…...

基于System.js的微前端实现(插件化)

目录​​​​​​​ 写在前面 一、微前端相关知识 &#xff08;一&#xff09;概念 &#xff08;二&#xff09; 优势 &#xff08;三&#xff09; 缺点 &#xff08;四&#xff09;应用场景 &#xff08;五&#xff09;现有框架 1. qiankun 2. single-spa 3. SystemJ…...

MedSAM2调试安装与使用记录

目录 前言一、环境准备多版本cuda切换切换cuda版本二 安装CUDNN2.1 检查cudnn 二、使用步骤1.安装虚拟环境2.测试Gradio3.推理 总结 前言 我们在解读完MedSAM之后&#xff0c;迫不及待想尝尝这个技术带来的福音&#xff0c;因此验证下是否真的那么6。这不&#xff0c;新鲜的使…...

Linux 进程终止和进程等待

目录 0.前言 1. 进程终止 1.1 进程退出的场景 1.2 进程常见退出方法 1.2.1 正常退出 1.2.2 异常退出 2. 进程等待 2.1 进程等待的重要性 2.2 进程等待的方法 2.2.1 wait() 方法 2.2.2 waitpid() 方法 2.3 获取子进程 status 2.4 阻塞等待和非阻塞等待 2.4.1 阻塞等待 2.4.2 非阻…...

如何查看默认网关地址:详细步骤

在日常的网络配置与故障排查中&#xff0c;了解并正确查看默认网关地址是一项基础且至关重要的技能。默认网关是连接本地网络与外部网络&#xff08;如互联网&#xff09;的关键节点&#xff0c;它扮演着数据包转发的重要角色。无论是家庭网络、办公室网络还是更复杂的网络环境…...

什么是方法的返回值?方法有哪几种类型?静态方法为什么不能调用非静态成员?静态方法和实例方法有何不同?

什么是方法的返回值?方法有哪几种类型&#xff1f; 方法的返回值 是指我们获取到的某个方法体中的代码执行后产生的结果&#xff01;&#xff08;前提是该方法可能产生结果&#xff09;。返回值的作用是接收出结果&#xff0c;使得它可以用于其他的操作&#xff01; 我们可以…...

Qt开发——Qt项目打包、整合以及生成安装包保姆级教程(Windows系统)

目录 Windows下打包Qt项目 1.Qt系统环境变量的配置 2.打包 3.打包整合为一个.exe文件 4.生成安装包 做完了一个Qt项目之后&#xff0c;要干嘛呢&#xff0c;很显然要打包给别人&#xff0c;让别人也能使用这个软件&#xff0c;本期我们就来学习Qt打包&#xff0c;本期内容分…...

大数据-180 Elasticsearch - 原理剖析 索引写入与近实时搜索

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…...

大数据-172 Elasticsearch 索引操作 与 IK 分词器 自定义停用词 Nginx 服务

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…...

【Java后端】之 ThreadLocal 详解

想象一下&#xff0c;你有一个工具箱&#xff0c;里面放着各种工具。在多人共用这个工具箱的时候&#xff0c;很容易出现混乱&#xff0c;比如有人拿走了你的锤子&#xff0c;或者你找不到合适的螺丝刀。为了避免这种情况&#xff0c;最好的办法就是每个人都有自己独立的工具箱…...

2.链表(代码随想录——python版本)

2.链表&#xff08;代码随想录——python版本&#xff09; 链表的概念&#xff1a; 链表是由指针串联在一起的线性结构&#xff0c;一个节点&#xff08;node&#xff09;由两部分组成&#xff1a; 数据域——用来存储数据&#xff1b;指针域——用来指向下一个节点&#xf…...

6个解决“由于找不到vcruntime140_1.dll无法继续执行代码”问题的方法

vcruntime140_1.dll丢失的问题在Windows操作系统中相对常见&#xff0c;它通常与Microsoft Visual C Redistributable有关。本文将详细解读vcruntime140_1.dll丢失的原因、解决方法以及预防措施&#xff0c;帮助用户更好地应对这一问题。 一&#xff0c;vcruntime140_1.dll文件…...

HTML 语义化

目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案&#xff1a; 语义化标签&#xff1a; <header>&#xff1a;页头<nav>&#xff1a;导航<main>&#xff1a;主要内容<article>&#x…...

基于FPGA的PID算法学习———实现PID比例控制算法

基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容&#xff1a;参考网站&#xff1a; PID算法控制 PID即&#xff1a;Proportional&#xff08;比例&#xff09;、Integral&#xff08;积分&…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍

文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结&#xff1a; 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析&#xff1a; 实际业务去理解体会统一注…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

省略号和可变参数模板

本文主要介绍如何展开可变参数的参数包 1.C语言的va_list展开可变参数 #include <iostream> #include <cstdarg>void printNumbers(int count, ...) {// 声明va_list类型的变量va_list args;// 使用va_start将可变参数写入变量argsva_start(args, count);for (in…...

day36-多路IO复用

一、基本概念 &#xff08;服务器多客户端模型&#xff09; 定义&#xff1a;单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用&#xff1a;应用程序通常需要处理来自多条事件流中的事件&#xff0c;比如我现在用的电脑&#xff0c;需要同时处理键盘鼠标…...

Tauri2学习笔记

教程地址&#xff1a;https://www.bilibili.com/video/BV1Ca411N7mF?spm_id_from333.788.player.switch&vd_source707ec8983cc32e6e065d5496a7f79ee6 官方指引&#xff1a;https://tauri.app/zh-cn/start/ 目前Tauri2的教程视频不多&#xff0c;我按照Tauri1的教程来学习&…...

13.10 LangGraph多轮对话系统实战:Ollama私有部署+情感识别优化全解析

LangGraph多轮对话系统实战:Ollama私有部署+情感识别优化全解析 LanguageMentor 对话式训练系统架构与实现 关键词:多轮对话系统设计、场景化提示工程、情感识别优化、LangGraph 状态管理、Ollama 私有化部署 1. 对话训练系统技术架构 采用四层架构实现高扩展性的对话训练…...