命令行参数、环境变量

news2024/9/23 19:18:48
我们在使用C语言的时候,经常的写法是int main(){//函数体}。
而且我们也知道它也只是一个函数,当一个进程启动的时候,会有专门的函数来调用这个函数。
那他有没有函数参数呢?其实也是有的,我们今天,就来认识一下main函数的参数。

命令函参数

在Linux系统中我们在命令行总是会使用各种各样的命令,而在命令的后面也会跟一些选项,而且我们知道这些当使用这些命令的时候本质也是启动了一个进程。在这里插入图片描述
这些命令也是用C语言写的,那么它们是怎么实现的的呢?这其实就谈到了main函数的参数,main函数有三个参数,我们先谈前两个参数。
在这里插入图片描述
这里面第二个变量是一个指针数组,它里面存储着字符串。第一个变量存储的是argv数组中有多少个字符串。让我们来演示一下,他里面到底会存什么?
在这里插入图片描述
那我们这么写呢?

在这里插入图片描述
在这里插入图片描述

我们发现了,那个指针数组里面存的就是当我们运行这个程序的时候我们命令行输入的东西,而这些东西是用空格来分割开来的,第一个被分割开的字符串就是启动的程序,后面可以就是程序中的选项这里字符串的分割是操作系统帮我们实现的,当操作系统分割之后就会把它通过bash父进程传给我们即将要运行的main函数这个子进程中。其实这也就解释了命令行的命令是如何实现的了。我们现在简单实现一个简易版的计算器。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char* argv[])
{
  if(argc == 4)
  {
    int a = atoi(argv[2]);
    int b = atoi(argv[3]);
    if(strcmp(argv[1], "add") == 0)
    {
       printf("%d + %d = %2d\n", a, b, a+ b);
    } 
    else if(strcmp(argv[1], "sub") == 0)
   {
       printf("%d - %d = %2d\n", a, b, a - b);
   }
   else if(strcmp(argv[1], "mul") == 0)
   {
       printf("%d * %d = %2d\n", a, b, a * b);
   }
   else if(strcmp(argv[1], "div") == 0)
   {
     if(b == 0)
     {
       printf("error:Divided by 0\n");
      return 1;
     }
       printf("%d / %d = %2d\n", a, b, a / b);
   }
   else
   {                                                                                      
     printf("option error\n");
     printf("availavle options:%s %s %s %s\n", "add", "sub", "mul", "div");
           }              
   }                
   else
   {
     printf("use error\n");
     printf("correct use:%s\n", "[cmd] [op] [num] [num]");
   }
 
   return 0;
 }

这里就是利用了命令行参数来实现了自己的一个命令行级别的指令。
在这里插入图片描述
现在,我们对命令行中的命令也不陌生了,它们也仅仅是一个程序而已
但是有人现在就一个个问题了,如果那些指令是程序的话,为什么使用他们的时候不用./来启动呢?这就需要我们介绍下一个知识点,环境变量。

2.环境变量

1). 简单认识环境变量

假如读者使用过Java或者python的ide的话,是会接触到环境变量这么个字眼的。
在这里插入图片描述
这个path就是我们在Linux研究的第一个环境变量。查看环境变量的可以这样:这个美元的符号是为了特殊说明PATH
在这里插入图片描述
我们看到它里面存储着路径,路径之间用’:'隔开,总共三个路径。其实我们的命令行指令就存在这些路径里,当我们使用指令的时候,系统会自动在这些路径里搜索,搜索到后就启动它们,所以我们把我们的文件移动到这些路径的其中一个,或者是添加我们的路径,一样可以让我们的可执行程序变成ls那样的指令。我在这里演示添加路径的方式:
添加路径如下:
在这里插入图片描述
可以看到我们没有使用./就启动了这个程序。而这里的修改方式也是在原有的环境变量上加冒号后再加路径然后再次赋值给PATH。当我们把PATH清空之后,我们会发现基本上所有的命令都不能用了:
在这里插入图片描述
我们看到了两种现象,一种是ls、clear这种命令不能用,但是echo可以用,这个问题我们稍后再谈,我们先处理指令不能用了怎么办?很简单,重启虚拟机就可以了。
在这里插入图片描述
重启之后,我们发现它又有了。这其实是因为我们没有永久修改环境变量,我们修改的只是内存中的环境变量,当我们重启之后,环境变量又会从磁盘中加载到内存,所以只有改变磁盘中的环境变量文件,才是永久修改,至于怎么永久修改环境变量,也等会儿再说。我们先来认识几个环境变量。

2). 环境变量

首先我们使用env命令可以输出所有的环境变量:
在这里插入图片描述

a. USER

其中有一个USER,是显示当前使用系统的用户。
在这里插入图片描述
可以看到,当我切换用户的时候,USER也变了。

b. HOME

为什么当我们登录普通账户的时候,进入到的是/home/zsw或者/home/zsw1?而root登陆的时候进入到的是/root?其实就是由于这个环境变量HOME的原因,它会在用户登录系统的时候,先被初始化。

c. PWD

这个我们很熟悉了,显示当前所处路径就是靠它。

d. LANG

当前全局所使用的字符集类型。

3). 获取环境变量的方式

a. getenv

我们上面说了一个env命令可以看到所有的环境变量,我们还有一个系统调用函数getenv。它也可以获取特定的环境变量:
在这里插入图片描述

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
  printf("PATH:%s\n", getenv("PATH"));             
  return 0;
}

在这里插入图片描述

b. main函数参数

还有我们说main函数里有第三个参数,那今天第三个参数就是环境变量!它是存储环境变量的一个数组,linux中以NULL结尾。
在这里插入图片描述

在这里插入图片描述

c.envrion

envrion是一个其他文件的变量,通过extern关键字可以引入它,它的类型是char** 指向的就是我们上面main函数中环境变量数组。
在这里插入图片描述
在这里插入图片描述

4. 环境变量的进一步认识

1). 永久修改环境变量

我们在前面说到,我们在命令行中修改环境变量并不是永久修改,而只是修改了内存里的,若要永久修改,需要修改磁盘中的某个文件,因为内存中的环境变量就是从磁盘中的某个文件加载而来的。
这个文件是位于家目录下的一个隐藏文件。
在这里插入图片描述
在这里插入图片描述
文件里就是关于各种加载环境变量的脚本。不再赘述,若要永久修改,就在这里添加,或者删除就可以。

2). 添加环境变量

我们假如想要添加一个环境变量,我们的方法是:export + 环境变量名=…。

在这里插入图片描述
可以看到确实是添加了,那没有export会发生什么呢?
在这里插入图片描述
发现它没有报错,其实这种没有加export的,也是变量,但只不过不是环境变量,而是本地变量。
环境变量和本地变量的区别就是,环境变量具有全局属性,通过父进程继承给子进程的方式,而本地变量只在bash内部有效。

Linux命令的进一步分类

我们来看这么一个现象:
在这里插入图片描述

那么就有人产生疑问了,那为什么使用echo命令可以输出本地变量的值呢?echo不也应该是一个命令吗?它也应该是一个程序啊,是一个bash的子进程啊。所以它不应该输出本地变量的值才对。
这里就又有了新的定义也回答了上面为什么当我们清空PATH中的路径后echo仍然可以执行,那是因为,在Linux中命令分为两种,一种是常规命令(ls,clear),一种是内建命令(echo,pwd)。常规命令就是bash的子进程,而内建命令你可以理解为是shell的一个函数,那它是shell的函数的话,自然就可以使用本地的变量了啊。

3).关于环境变量的的命令

export导入环境变量
unset 取消变量
set 显示所有变量
echo 显示某个环境变量
env 显示所有环境变量

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1141281.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

常用的网络攻击手段

前言&#xff1a;本文旨在介绍目前常用的网络攻击手段&#xff0c;分享交流技术经验 目前常用的网络攻击手段 社会工程学攻击物理攻击暴力攻击利用Unicode漏洞攻击利用缓冲区溢出漏洞进行攻击等技术 社会工程学攻击 社会工程学 根据百度百科定义&#xff1a; 社会工…

2023/10/27 JAVA学习

tab键可以对文件名进行补全 想切到其他盘的某个文件,必须先使用切盘命令 在当前文件目录输入cmd,可直接打开命令行窗口,并且处于当前文件目录 运行java文件,只用文件名不需要后缀 记得勾选文件扩展名 直接这样执行不会出现class文件,因为在底层临时生成了一个,不会长久的出现

NX二次开发后处理中保存tcl变量值到文本

直接上代码&#xff1a; static bool GetTclValue(UF_MOM_id_t mom_id, char *szName, char *szInfo, std::string &stValue,bool bShowValue /* false*/) {UF_MOM_ask_string(mom_id, szName, (const char **)&szInfo);if (szInfo){stValue szInfo;if (bShowValue){…

ArrayList的线程安全类CopyOnWriteArrayList

目录 一、CopyOnWriteArrayList简介二、CopyOnWriteArrayList的优缺点1、优点2、缺点 三、CopyOnWriteArrayList使用场景1、数据库缓存2、消息队列3、数据统计和分析 四、使用CopyOnWriteArrayList时需要注意哪些问题&#xff1f;1、内存占用问题2、数据一致性问题3、线程安全4…

Milvus 入门教程

文章目录 下载docker-compose配置文件安装 docker安装docker-compose直接下载release版本手动安装使用pip 命令自动安装 通过 docker-compose 启动容器连接 Milvus停止 milvus删除milvus的数据 下载docker-compose配置文件 先安装wget命令 yum install wget下载配置文件&…

C++之C++11字符串字面量后缀总结(二百四十八)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

如何高效自学(黑客技术)方法——网络安全

如果你想自学网络安全&#xff0c;首先你必须了解什么是网络安全&#xff01;&#xff0c;什么是黑客&#xff01;&#xff01; 1.无论网络、Web、移动、桌面、云等哪个领域&#xff0c;都有攻与防两面性&#xff0c;例如 Web 安全技术&#xff0c;既有 Web 渗透2.也有 Web 防…

2023版 STM32实战12 IIC总线读写AT24C02

IIC简述 一个多主从的串行总线&#xff0c;又叫I2C&#xff0c;是由飞利浦公司发明的通讯总线 IIC特点 -1- 串行(逐bit传输) -2- 同步(共用时钟线) -3- 半双工(收发不同进行) -4- 总线上的任何设备都可以是主机 开发使用习惯和理解 -1- 通过地址寻址 -2- 数据线的…

Linux权限及Xshell运行原理

目录 1.Linux中的用户 1.1 用户分类 1.2 用户切换 2.权限的概念 2.1 权限概念以及表示 2.2 文件属性以及类型 2.2.1 文件属性 2.2.2 文件类型 2.3 Linux下的角色 3.权限的修改 3.1 chmod 3.2 chown 3.3 chgrp 4.目录权限 5.权限掩码 5.1 默认权限 5.2 起始权限…

省时省力!掌握简单快捷的关机命令,轻松实现电脑的自由开关机

本文介绍了为电脑设置特定的自动关机时间的四种方法。我们还包括如何停止计划关机的信息。 如何用命令提示符安排计算机关机 按照以下步骤使用命令提示符进行一次性关闭。 1、在Windows搜索框中,键入CMD。 2、点击Enter。 3、在命令提示符窗口中,键入shutdown -s -t 和所…

matlab simulink 四旋翼跟拍无人机仿真

1、内容简介 略 7-可以交流、咨询、答疑 2、内容说明 四旋翼跟拍无人机仿真 四旋翼、无人机 需求分析 背景介绍 无人飞行机器人&#xff0c;是无人驾驶且具有一定智能的空中飞行器。这是一种融合了计算机技术、人工智能技术、传感器技术、自动控制技术、新型材料技术、导航…

基于机器视觉的车道线检测 计算机竞赛

文章目录 1 前言2 先上成果3 车道线4 问题抽象(建立模型)5 帧掩码(Frame Mask)6 车道检测的图像预处理7 图像阈值化8 霍夫线变换9 实现车道检测9.1 帧掩码创建9.2 图像预处理9.2.1 图像阈值化9.2.2 霍夫线变换 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分…

HCL模拟器选路实验案例

此选路题目选自职业院校技能竞赛中的一道题比较考验思路&#xff0c;适合于参加新华三杯大赛以及网络专业的同学&#xff0c;当做练习题目进行解题​​​​​​​ 题目 1.S1、S2、R1、R2运行ospf进程100&#xff0c;区域0&#xff0c;R1、R2、R3、R4、R5运行ospf进程200&#…

Linux进阶之旅:从零开始,探索基本指令的神秘力量!

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是尘缘&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f449;点击这里&#xff0c;就可以查看我的主页啦&#xff01;&#x1f447;&#x…

【java学习—九】工厂方法FactoryMethod(6)

文章目录 1. 概念2. 实际的应用 1. 概念 FactoryMethod 模式是设计模式中应用最为广泛的模式&#xff0c;在面向对象的编程中&#xff0c;对象的创建工作非常简单&#xff0c;对象的创建时机却很重要。 FactoryMethod 解决的就是这个问题&#xff0c;它通过面向对象的手法&…

RabbitMQ初入门

1、RabbitMQ是什么 RabbitMQ是“实现了高级消息队列协议&#xff08;AMQP&#xff09;的开源消息代理软件&#xff08;亦称面向消息的中间件&#xff09;。RabbitMQ服务器是用Erlang语言编写的&#xff0c;而集群和故障转移是构建在开放电信平台框架上的。所有主要的编程语言均…

23 行为型模式-迭代器模式

1 迭代器模式介绍 迭代器模式是我们学习一个设计时很少用到的、但编码实现时却经常使用到的行为型设计模式。在绝大多数编程语言中&#xff0c;迭代器已经成为一个基础的类库&#xff0c;直接用来遍历集合对象。在平时开发中&#xff0c;我们更多的是直接使用它&#xff0c;很…

C++学习 day--21 地震监测系统实现、内存泄漏检测工具

1、项目需求 地震监测系统主要是利用地震检波器收集到的地壳运动信息&#xff0c;从而预测和确定地震的震中以 及强度。 预测方法 地震检波器每隔固定的时间间隔采样一次预测地震的能量数据&#xff0c;并保存到文件中&#xff0c;地震监测 系统会从文件中读取相应的能量数据&…

第四章 文件管理 十二、虚拟文件系统

目录 一、虚拟文件系统图 二、虚拟文件系统的特点 三、存在的问题 四、文件系统挂载 一、虚拟文件系统图 二、虚拟文件系统的特点 1、向上层用户进程提供统一标准的系统调用接口&#xff0c;屏蔽底层具体文件系统的实现差异。 2、VFS要求下层的文件系统必须实现某些规定的…

Map集合 遍历:lambda方式

package day01;import java.util.*;public class Mapday1 {public static void main(String[] args) {/* HashMap 无序 不重复&#xff0c;会覆盖前面 无索引*/System.out.println("--------------------");Map<String, Integer> map new HashMap<>();m…