从0开始linux(12)——命令行参数与环境变量

news2024/10/10 5:40:11

欢迎来到博主的专栏:从0开始linux
博主ID:代码小豪

文章目录

    • 命令行参数
    • 环境变量

我们先打断一下关于进程的话题,博主先来介绍两个东西,分别是命令行参数与环境变量。那么有人看到这就会问了,难道说命令行参数和环境变量是属于进程部分的内容吗?其实不是,命令行参数与环境变量与进程是独立开来的,但是它两与进程的一些操作有关,博主避免在后续的进程章节花大量篇幅(少量篇幅说不清楚)去讲解,于是在这一章节中进行补充。实际上,命令行参数与环境变量也是八竿子打不着的关系。

命令行参数

大家有没有疑惑过一点,那就是在前面的章节中,博主提到了,指令和我们自己编写的程序都是二进制文件,但是在系统当中好像它两有点不同,具体体现以下两点

  • (1)指令可以待选项,我们自己写的程序不能
  • (2)指令可以直接用,但是我们自己写的程序则需要确定文件所在路径才能用

比如ls指令,和博主自己写的程序hello.exe,ls指令可以带选项,比如ls -al,而博主写的hello.exe不能,再比如ls指令不用带路径,但是博主写的却不能不带。

ls -al#可以带选项,也可以不指定文件所在路径
./hello.exe#不能带选项,还要指定文件所在路径

其实我们自己的程序也能带指令,也可以不指定所在路径,这其中,前者与命令行参数有关,而后者则与环境变量有关,博主先带大家认识一下命令行参数

熟悉C语言的小伙伴都知道,函数是可以带参数,也可以不带参(好像是废话),但是main函数带不带参呢?这里大伙可能就有异议了,我们平时写main函数都是无参的,即使main函数带参了又有什么用呢?谁也不会去尝试调用main函数。

其实main函数也一样,可以带参,也可以无参,我们不妨给main函数加上几个参数,并且打印看看它们的结果,那么博主就将hello.exe程序的源文件(hello.c)修改一下吧。
在这里插入图片描述
接着我们编译该文件,生成hello.exe,此时惊讶的发现,编译竟然通过了,这就说明main函数其实可以带参数的,只是平时我们练习时写的那些代码不需要用到而已。那么我们赶紧运行一下,看看i,j,k的运行结果是什么。
在这里插入图片描述
嗯,好像除了i以外,j和k的数值都有些奇怪,应该不是整形值,而i的话竟然是1,这说明i一定和某些规律有关,而且大家有没有发现一个奇怪的事?那就是我们明明没有给main函数传递参数,但是main函数竟然将i,j,k都初始化了,令人惊讶。那么到底是怎么回事呢?博主也不卖关子了。咱们赶紧把命令行参数请上来吧。

我们先搞清楚一件事,那就是hello.c中的main函数的参数到底是谁给的?其实答案很简单,是bash给的,还记不记得博主在进程(1)章节给大家展示过,hello.exe的父进程其实是有父进程的,它的父进程就是bash!

在我们shell中打开的进程(包括指令,vim),其父进程都是bash

还记得我们在哪里启动的hello.exe吗?我们是在linux的shell中启动的(linux的shell程序其实就是bash,后面博主降到bash大家就要想到linux的shell)。因此hello.exe的父进程就是bash。

让我们将目光回到main函数的参数当中,其中i是一个整形,而其余两个不是,这是因为main函数允许我们设置0~3个参数,通常来说,main函数的参数只有0个,2个,3个参数,这是因为这些参数都有其对应位置,而且都有其特定意义。

无参数的main函数博主就不说了,相信大家已经写了很多了,我们先来说说2参数的main函数,其中main函数的第一个参数是int类型,第二个参数char*的数组(指针数组),我们可以随便给这些参数命名,但是通常来说,程序员约定成俗将这两个参数命名为argc,和argv,我们也不搞特殊了。两参数的main函数如下:

int main(int argc,char* argv[]);

请大家尝试一下写这么一份代码:

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

将其编译生成testcpl程序。接着我们尝试运行该程序。
在这里插入图片描述
诶,很奇怪,为什么运行的结果是将程序名重新写了一遍。如果我们在运行该程序的时候多写几个字符试试呢?

./testcpl helloworld lysb666

在这里插入图片描述
我们惊讶的发现,该程序会将我们输入在命令行中的字符全都打印出来。

这是因为,argc,和argv都是命令行参数,而main函数当中的参数列表,我们称之为命令行参数列表。
在这里插入图片描述
之所以将其称之为命令行参数,是因为它们会读取命令行中的信息,比如我们输入的“./testcpl”,“helloworld”,"lysb666"都是输入在命令行中的信息,而命令行参数,则会读取这些信息。

命令行参数的规则如下:
(1)argc读取命令行中的参数个数
(2)argv会读取命令行中的字符串
(3)argv会将命令行中的字符串按照顺序读取,并且保存在数组当中,argv的首元素,是程序名,而argv的最后的一个元素,是NULL指针。
在这里插入图片描述

利用命令行参数,我们可以实现这样的一个代码:

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

int main(int argc,char* argv[])
{
    if(argc!=2)
    { 
        printf("请加入选项:\"-h -l -c\"\n");
    }
    else
    {
        if(strcmp(argv[1],"-h")==0)
        {
            printf("hello world\n");
        }
        else if(strcmp(argv[1],"-l")==0)
        {
            printf("lysb666\n");
        }
        else if(strcmp(argv[1],"-c")==0)
        {
            printf("I love code\n");
        }
        else                                                                                                                                                                                             
        {
            printf("选项错误:请输入:\"-h,-l,-c\"");
        }
    }
    return 0;
}

然后我们尝试在命令行中输入

./testclp2
./testclp2 -h
./testclp2 -l
./testclp2 -c
./testclp2 -q

在这里插入图片描述
由于argv可以读取命令行的输入,因此我们可以在程序中根据argv中的内容,让程序做出不同的处理,也就是说,我们在命令行中可以输入一些选项,让我们的程序根据这些选项做出不同的处理。

咦?这是不是和我们指令很像,比如ls指令,如果ls指令加上"-a -l -n"等选项,ls指令的处理结果也会发生改变,没错我们linux中的指令本质上也是一个程序,因此这些指令加上选项会出现不同的处理结果,实际上也是程序中加上了命令行参数

环境变量

博主在前面提到了main还有个3参数形式。这第三个参数也能随便取名,但是它约定俗成的名字叫做env,也是一个char* []类型的数组指针。

int main(int argc,char* argv[],char*env[]);

那么argc和argv记录的是命令行,而这个env记录的东西是什么,实际上env的全称是environment,其实就是存储环境变量的字符型的指针数组。

这个env指针数组的作用和argv有点类似,其构成也有点类似,即从0开始最后一个元素,存储的是环境变量的数据,而最后一个元素是一个NULL指针。
在这里插入图片描述
于是我们可以根据这个特性,写一个查看环境变量的代码:

#include<stdio.h>

int main(int argc,char*argv[],char*env[])
{
    for(int i=0;env[i]!=NULL;i++)//只要env当前的元素不是NULL指针,就一直打印                                                                                                                                                                      
    {
        printf("env[%d]:%s\n",i,env[i]);
    }
    return 0;
}

然后将其编译,运行对应程序。
在这里插入图片描述
看到这些一大片的字符串了吗?其实它们就是所谓的环境变量,而env可以读取这些环境变量。之所以将它们称为环境变量,一方面是因为这些环境变量其实是我们linux系统的一些配置环境信息,另外方面,则是它们和我们在代码中声明的变量有点像。

我们在命令行中输入env,也能查看到全部的环境变量信息
在这里插入图片描述
哇,这环境变量也太多了,它们又是具体做什么的?别着急,博主先介绍几个环境变量,然后在讲述这些环境变量的作用,当然,博主并不打算详细的讲完所有的环境变量,如果大家感兴趣,博主将会在未来给大家详细的讲解全部的环境变量。

PATH
在环境变量中存在一个变量PATH,
在这里插入图片描述
这个PATH是:指定命令的搜索路径

还记得博主在开头讲的吗?为什么linux的指令可以不指定路径运行,而我们自己写的程序则要指定号路径才能运行。这是因为,如果我们在运行程序时,如果不指定搜索路径,则bash只会在PATH中,记录的路径中查找对应文件,如果不存在,则会告诉用户:command not found

比如我们的ls指令,使用指令witch ls可以查看ls指令的文件位置
在这里插入图片描述
这不就是位于PATH中的路径吗?

这里在介绍几个简单的环境变量

  • HOME:
    表示用户的家目录,比如我们用户使用cd~就会回到HOME变量对应的目录下
  • SHELL:
    表示当前linux环境下,用户使用的SHELL程序是哪个。系统默认的shell程序时bash
  • USER
    表示当前使用的用户
  • LANG
    表示系统当前使用的语言以及对应编码

这些环境变量可以代表我们当前的配置环境,而且还能影响到我们的进程。但是博主这里不多赘述,因为最重要的是先引入这些相关的概念,如果在后续的文章中,有用到相关的内容,博主在做补充

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

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

相关文章

Spring系列 循环依赖

文章目录 注入方式循环依赖的场景单例创建流程getSingletoncreateBeandoCreateBeancreateBeanInstance 循环依赖分析为什么都使用构造函数无法解决&#xff1f;为什么使用Autowired可以解决&#xff1f;为什么要添加到 earlySingletonObjects 缓存中&#xff1f;allowCircularR…

基于Kafka2.1解读Producer原理

文章目录 前言一、Kafka Producer是什么&#xff1f;二、主要组件1.Kafka Producer1.1 partitioner1.2 keySerializer1.3 valueSerializer1.4 accumulator1.5 sender 2.Sender2.1 acks2.2 clientinFlightBatches 3. Selector3.1 nioSelector3.2 channels 4. 全局总览 总结 前言…

【hot100-java】N 皇后

回溯篇 视频题解 真的裂开了&#xff0c;多看视频题解。 class Solution {public List<List<String>> solveNQueens(int n) {List<List<String>>retnew ArrayList<>();int []colnew int[n];boolean[] onPathnew boolean[n];boolean[] diag1ne…

(Linux和数据库)1.Linux操作系统和常用命令

了解Linux操作系统介绍 除了办公和玩游戏之外不用Linux&#xff0c;其他地方都要使用Linux&#xff08;it相关&#xff09; iOS的本质是unix&#xff08;unix是付费版本的操作系统&#xff09; unix和Linux之间很相似 Linux文件系统和目录 bin目录--放工具使用的 操作Linux远程…

双光吊舱图像采集详解!

一、图像采集 可见光图像采集&#xff1a; 使用高性能的可见光相机&#xff0c;通过镜头捕捉自然光或人工光源照射下的目标图像。 相机内部通常配备有先进的图像传感器&#xff0c;如CMOS或CCD&#xff0c;用于将光信号转换为电信号。 红外图像采集&#xff1a; 利用红外热…

【hot100-java】二叉树的最近公共祖先

二叉树篇 我觉得是比两个节点的深度&#xff0c;取min&#xff08;一种情况&#xff09; DFS解题。 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode(int x) { val x; }* }*/ clas…

Unity/VS 消除不想要的黄色警告

方法一&#xff1a;单个消除 在要关闭的代码前一行写上#pragma warning disable 警告代码编码 在要关闭代码行下面一行写上#pragma warning restore 警告代码编码 精准的关闭指定地方引起的代码警告&#xff0c;不会过滤掉无辜的代码 #pragma warning disable 0162,1634HandleL…

JDBC: 连接池

文章目录 没有连接池的现状连接池解决现状问题的原理连接池好处常用连接池的介绍Druid连接池DRUID简介Druid常用的配置参数Druid连接池基本使用API介绍 案例代码 没有连接池的现状 通过下图来分析一下我们目前jdbc程序的结构。 以前使用的jdbc的缺点&#xff1a; 1、操作数据库…

户外打气泵方案软件设计开发

随着户外活动的普及和人们对便捷生活的需求&#xff0c;打气泵成为越来越多有车人士及爱好户外运动的人的装备之一。而打气泵的核心控制是它的芯片和软件方案&#xff0c;今天我们就介绍一下打气泵芯片软件方案的开发过程与技术要点。 打气泵方案的软件设计相较于硬件更具复杂性…

数据库——sql多表查询

当要在两个表&#xff08;或多个表&#xff09;中查找对应数据时&#xff0c;与普通的查询略有不同。本篇博文用于介绍基本的多表查询的方法。 为方便展示&#xff0c;本篇建了两个数据库表“学生表”和“班级表”作为例子 其中&#xff0c;在“学生表”中&#xff0c;cid标签…

RT-DETR改进策略:BackBone改进|CAFormer在RT-DETR中的创新应用,显著提升目标检测性能

摘要 在目标检测领域,模型性能的提升一直是研究者和开发者们关注的重点。近期,我们尝试将CAFormer模块引入RT-DETR模型中,以替换其原有的主干网络,这一创新性的改进带来了显著的性能提升。 CAFormer,作为MetaFormer框架下的一个变体,结合了深度可分离卷积和普通自注意力…

SpringBoot教程(二十四) | SpringBoot实现分布式定时任务之Quartz(动态新增、修改等操作)

SpringBoot教程&#xff08;二十四&#xff09; | SpringBoot实现分布式定时任务之Quartz&#xff08;动态新增、修改等操作&#xff09; 前言数据库脚本创建需要被调度的方法创建相关实体类创建业务层接口创建业务层实现类控制层类测试结果 前言 我这边的SpringBoot的版本为2…

Android 防止截屏和录屏

通过给当前的window对象设置标记WindowManager.LayoutParams.FLAG_SECURE来防止截屏和录屏 protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 防止截屏getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManage…

vscode配置:启用括号对着色

想要的效果&#xff1a;启用括号对着色&#xff0c;在大括号之间用折线表示&#xff0c;看起来会更加直观方便&#xff0c;例如在less中嵌套层级比较多时&#xff0c;大括号的层级不容易看清楚&#xff0c;做了这个配置会更好一些。 vscode安装扩展插件&#xff1a;Bracket P…

Spring Boot学习资源库:Spring生态的精华

摘 要 社会的进步&#xff0c;教育行业发展迅速&#xff0c;人们对教育越来越重视&#xff0c;在当今网络普及的情况下&#xff0c;教学模式也开始逐渐网络化&#xff0c;各大高校开始网络教学模式。 本文研究的教学资源库系统基于Springboot框架&#xff0c;采用Java技术和MYS…

Linux deepin系统通过编辑crontab来设置定时任务---定时关机

在Linux系统中&#xff0c;crontab 是用来设置周期性被执行的指令的守护进程。通过编辑 crontab&#xff0c;您可以安排定时任务&#xff0c;比如定时关机、定时备份文件、定时运行脚本等。以下是如何编辑 crontab 来设置定时任务的步骤&#xff1a; 打开终端&#xff1a;您可以…

AcWing 802. 区间和(离散化算法,python)

本篇博客详细讲解一下离散化知识点&#xff0c;通过讲解和详细列题带大家掌握离散化。 题目&#xff1a; 原题链接&#xff1a;https://www.acwing.com/problem/content/description/804/ 假定有一个无限长的数轴&#xff0c;数轴上每个坐标上的数都是 0。 现在&#xff0c;…

平时使用的正则总结

1、将某一个字符串的后缀名后面加上“!400_500” 使用场景是将minio拿过来的图片压缩尺寸从而压缩其大小&#xff0c;加快渲染的速度。需要在图片的后缀名后面加上尺寸如下&#xff1a; const str //storage-test.test.shiqiao.com/gateway/common/isopen/2024/10/09/e708e9…

科创集团所属园区入驻企业北京铭镓半导体获 “硬科技”潜在独角兽企业认定

近日&#xff0c;科创集团所属工宇园区企业北京铭镓半导体荣获北京市科委、中关村管委会“硬科技”潜在独角兽企业认定。独角兽企业特指具备显著创新力、展现出强劲成长潜力以及获得市场高度认可的企业&#xff0c;是新经济领域发展的标志性存在。 北京铭镓半导体有限公司于202…

如何搭建直播美颜平台?视频美颜SDK的核心技术详解

时下&#xff0c;美颜效果作为提升直播吸引力的重要手段&#xff0c;已经成为主播和观众的共同期待。本篇文章&#xff0c;小编将与大家分享搭建一个高效的直播美颜平台的流程&#xff0c;重点介绍视频美颜SDK的核心技术。 一、直播美颜平台的构建 搭建一个直播美颜平台&#…