Linux: 命令行参数和环境变量究竟是什么?

news2024/11/17 11:18:18

Linux: 命令行参数和环境变量究竟是什么?

  • 一、命令行参数
    • 1.1 main函数参数意义
    • 1.2 命令行参数概念
    • 1.3 命令行参数实例
  • 二、环境变量
    • 2.1 环境变量概念
    • 2.2 环境变量:PATH
      • 2.2.1 如何查看PATH中的内容
      • 2.2.2 如何让自己的可执行文件不带路径运行
    • 2.3 环境变量:PWD
    • 2.3 环境变量: HOME
  • 三、获取环境变量的3种方式
    • 3.1 getenv()函数
    • 3.2 main函数传参
    • 3.3 通过第三方变量environ获取(extern char** environ)
  • 四、环境变量如何获取
    • 4.1 子进程环境变量获取方式
    • 4.2 父进程环境变量获取方式
  • 五、本地变量和环境变量
  • 六、Linux命令分类和环境变量相关的命令

一、命令行参数

 在main函数中,我们可以给main函数传递3个参数(库函数头为main(int argc, char *argv[], char *env[]))(这里我们只用前两个参数)。那究竟如何给main函数传递参数呢?每个参数分别表示什么?

1.1 main函数参数意义

main函数中,argc表示指针数组arvg中有效元素的个数。接下来我们来看一段代码!

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

int main(int argc, char* argv[])                                                                                                                     
{                                                                  
    int i = 0;                                                     
    for(; i < argc; i++)                                           
    {                                                              
        printf("%d: %s\n", i, argv[i]);                            
    }                                                              
}   

【运行现象】:
在这里插入图片描述

1.2 命令行参数概念

 1.1中main()函数在运行时,我们输入的指令会被bash或shell当成一个大的字符串,并以空格的形式分割成若干个小的字符串。而这些小字符串会形成一张指针数组表,bash或shell会指针数组有效个数传给argc参数,指针数组表地址传给argc参数

在这里插入图片描述
 我们在来看看系统指令现象,来对比上述mian函数。

在这里插入图片描述

我们将上述这种lsls -lls -l -a称之为命令行参数。输入的指令会被bash或shell以空格分割成小字符串,并形成一种指针数组表用于存放每一个小的字符串,并将该指针数组的有效个数传递给mian函数的argc参数,而指针数组表的地址传递给argv参数。其中./mybinls这种为可执行程序、其他的为选项。命令行参数可以让同一段代码通过不同的选项来实现不同的功能!!

1.3 命令行参数实例

 下面我们希望一段代码,通过不同的指令来实现简单的计算器。其中格式为可执行程序 功能参数(add、sub、mul、div) 两个参与运算的数据d1 d2
 显然我们需要给mian函数中,有效字符的个数为4,此时我们仅需比较argv[1]传递的字符串是什么即可判断对于的功能选项。下面我们来看看如何实现吧!

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
    
int main(int argc, char *argv[])    
{    
    if(argc != 4)//传入数据错误,显示正确使用手册    
    {        
        printf("Use error\nUsage %s op[-add|sub|mul|div] d1 d2\n", argv[0]);    
        return 1;    
    }    
    
    int x = atoi(argv[2]);//将字符窜转整型    
    int y = atoi(argv[3]);    
    if(strcmp(argv[1], "add")==0)    
    {    
        int result = x + y;    
        printf("%d + %d = %d\n", x, y, result);    
    }    
    else if(strcmp(argv[1], "sub")==0)    
    {    
        int result = x - y;    
        printf("%d - %d = %d\n", x, y, result);    
    }    
    else if(strcmp(argv[1], "mul")==0)    
    {    
        int result = x * y;    
        printf("%d * %d = %d\n", x, y, result);                                                                                                          
    
    }    
    else if(strcmp(argv[1], "div")==0)    
    {    
        if(y == 0)//非法数据、除数为0
        {
            printf("%d/%d=error! div zero\n", x, y);
        }
        else 
        {
            int result = x / y;
            printf("%d / %d = %d\n", x, y, result);
        }
    }
    else
    {
        printf("Use error\nUsage %s op[-add|sub|mun|div] d1 d2\n", argv[0]);

    }
    return 0;
}

【测试结果】:

在这里插入图片描述

二、环境变量

 在shell中,对于系统指令(lspwd)的我们直接在命令行输入相关指令便可执行对于的功能;但对于用于自己编写的可执行程序,运行时必须在前加./来指令程序的相对路径。而这种差异就和环境变量有关!!

2.1 环境变量概念

环境变量(environment variables)一般是指在操作系统中,用于指定操作系统运行环境的一些参数。环境变量通常具有特殊用途,并且具有全局特性!!
 比如我们在编写C/C++程序时,我们不知道、也不关心所谓的动/静态库在哪里。但我们每次都能编译成功,形成可执行程序。原因在于有相关的环境变量帮助编译器进行查找!!

下面我们来看看操作系统中,究竟有哪些常见的环境变量!

2.2 环境变量:PATH

PATH是用于指定系统搜索路径的环境变量。

 在命令行参数讲解中,有一个小细节。系统指令可以直接只需在命令行输入相关指令便可执行对于的功能,而我们自己的可执行程序必须在前面加./,否则会报错:command not found。这是为啥呢?
 原因在于运行一个可执行程序前,操作系统需要得到该可执行程序的路径
。这只是为啥我们自己的可执行程序必须加./才能运行。至于系统指令,原因在于环境变量PATH中保存着一系列系统搜索路径。运行系统指令时,操作系统会依次搜索PATH中保存的路径,只要PATH中保存了当前指令的存在路径,程序便可以运行成功!!

2.2.1 如何查看PATH中的内容

 我们可以通过指令echo $PATH来查看PATH中保存的内容。PATH保存的路径会以冒号作为分割符,将路径分隔开!

在这里插入图片描述

2.2.2 如何让自己的可执行文件不带路径运行

$emsp;让自己的可执行程序不带路径运行通常由两种方法:将可执行文件路径添加到PATH环境变量中、将可执行文件拷贝到系统的指定路径下!!

【将可执行文件路径添加到PATH环境变量】:
 我们可以通过指令PATH=&PATH:可执行文件路径将可执行文件路径添加到PATH环境变量!!

在这里插入图片描述

  • 上述行为都是对内存中的数据进行操作。默认更改的环境变量、仅限于本次登录!!

【将可执行文件拷贝到系统的指定路径下】:

在这里插入图片描述
tips:

  • 上述将指定文件拷贝到系统指定路径下的行为也被称为程序安装!!系统运行可执行程序时,默认会在环境变量和系统指令路径下进行查找!

2.3 环境变量:PWD

$emsp;我们在来看看下面这些指令:
在这里插入图片描述
 我们发现pwd指令每次都能成功获取到当前工作坐在路径!这时为何?
原因在于系统中存在一个环境变量PWD,该环境变量用于保存用户的当前工作路径。每次执行pwd执行时,pwd会读取环境变量PWD中的内容,并回显给用户!

2.3 环境变量: HOME

 我们每次在登录shell时,为什么对于root账号,所处工作目录为/root;而对于普通用户,则是/home xxx?
原因在于系统中存在某些环境变量,在我们还未登录时就已经被加载了。这些变量是由操作系统的配置文件或命令行参数指定的。当用于登录shell时,该环境变量会识别出用户的身份,从而初始化环境变量HOME。最后shell直接通过cd $HIME达到上述现象。
shell环境变量加载流程
在这里插入图片描述

三、获取环境变量的3种方式

 在Linux中,我们可以通过env指令来查看当前进程中的所有环境变量。而获取环境变量通常有以下3种方式。

3.1 getenv()函数

 在Linux中,提供一个名为getenv函数(char *getenv(const char *name););该函数可以获取环境变量中的内容。

例如:
【源代码】:

int main(int argc, char *argv[], char *env[])    
{    
    printf("PATH:%s\n", getenv("PATH"));; 
 	  return 0;
}

【运行结果】:
在这里插入图片描述

3.2 main函数传参

 在命令行参数中,我们已经提到过mian函数可以传3个参数,mian函数原型为:main(int argc, char *argv[], char *env[])
程序在启动时,系统可以选择的给进程(main函数)提供两张表:命令行参数表(argc维护)、环境变量表(env维护)。

【源代码】:

#include <stdio.h>

int main(int argc, char *argv[], char* env[])
{
    for(int i = 0; env[i]; i++)
        printf("env[%d]: %s\n", i, env[i]);
    return 0;
}

【运行结果】:
在这里插入图片描述

3.3 通过第三方变量environ获取(extern char** environ)

 在shell中,环境变量会以写时拷贝的方式继承给子进程。换而言之,环境变量具有全局属性,父子进程以写时拷贝的方式看到同一种环境变量表。
 那子进程如何“继承”的环境变量表呢?
libc中定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以在使用时 要用extern声明。

实例:
【源代码】:

#include <stdio.h>

int main()
{
    extern char **environ;
    for(int i = 0; environ[i]; i++)
        printf("environ[%d]: %s\n", i, environ[i]);
    return 0;
}

【运行结果】:
在这里插入图片描述

四、环境变量如何获取

4.1 子进程环境变量获取方式

 命令行启动的进程都是shell或bash的子进程,而子进程的环境变量都是父进程以命令行参数的形式传递给子进程的。

4.2 父进程环境变量获取方式

 在shell中直接修改环境变量PATH虽然可行,但这是直接更改shell进程内部的环境变量信息。在下一次登录时,该修改值会被恢复!!

 这是由于父进程(准确的来说是shell)每次重新登录时,都会形成新的bash解释器,并且bash解释器会自动读取配置文件./.bash_profile(在家目录下)中的信息,为shell进程形成一张环境变量表!!即父进程shell的环境变量信息是以脚本配置文件的形式存在的!!

五、本地变量和环境变量

 在shell中除了系统默认的环境变量,也可以手动添加环境变量!

【例如】:

MYENV=helloLinux

在这里插入图片描述
 当上述添加的环境变量并未添加到环境变量表中,被称为本地变量。使用export指令可以将本地变量导入环境变量表中,变为环境变量!!即export MYENV

 本地变量只在bash进程内部有效,不会被子进程所继承;而环境变量通过让所有子进程继承的方式,实现全局性!

六、Linux命令分类和环境变量相关的命令

 在Linux中,Linux命令分为常规命令和内建命令。

命令种类用途
常规命令fork让子进程执行的。具体表现在对环境变量PATH清空后,诸如ls、cd、mkdir、touch等指令失效
内建命令shell内部的一个函数,可以直接读取shell内部的本地变量。如export、pwd

环境变量相关的命令

命令种类用途
echo显示某个环境变量值
export设置一个新的环境变量
env显示所有环境变量
unset清除环境变量
set:显示本地变量和环境变量

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

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

相关文章

科普文:K8S中常见知识点梳理

简单说一下k8s集群内外网络如何互通的 要在 Kubernetes&#xff08;k8s&#xff09;集群内外建立网络互通&#xff0c;可以采取以下措施&#xff1a; 使用service&#xff1a; 使用Service类型为NodePort或LoadBalancer的Kubernetes服务。这可以使服务具有一个公共IP地址或端口…

Java面试八股之MySQL中int(10)和bigint(10)能存储读的数据大小一样吗

MySQL中int(10)和bigint(10)能存储读的数据大小一样吗 在MySQL中&#xff0c;int(10)和bigint(10)的数据存储能力并不相同&#xff0c;尽管括号内的数字&#xff08;如10&#xff09;看起来似乎暗示着某种关联&#xff0c;但实际上这个数字代表的是显示宽度&#xff0c;而不是…

深入讲解C++基础知识(三)

目录 一、命名空间1. 创建命名空间2. 访问命名空间2.1 using 编译指令2.2 using 声明2.3 直接使用全名 3. 嵌套命名空间4. 匿名命名空间5. 命名空间的注意事项5.1 头文件中不应该包含 using 声明和 using 编译指令。5.2 最好使用 using 声明而不是 using 编译指令 二、标准库类…

LiveNVR监控流媒体Onvif/RTSP用户手册-录像计划:批量配置、单个配置、录像保存(天)、配置时间段录像

TOC 1、录像计划 支持单个通道 或是 通道范围内配置支持快速滑选支持录像时间段配置 1.1、录像存储位置如何配置&#xff1f; 2、RTSP/HLS/FLV/RTMP拉流Onvif流媒体服务 支持 Windows Linux 及其它CPU架构&#xff08;国产、嵌入式…&#xff09;操作系统安装包下载 、 安装…

Kubernetes平台迁移

Kubernetes&&平台迁移 信息收集 信息收集

浅析Nginx技术:开源高性能Web服务器与反向代理

什么是Nginx&#xff1f; Nginx是一款轻量级、高性能的HTTP和反向代理服务器&#xff0c;也可以用作邮件代理服务器。它最初由俄罗斯的程序员Igor Sysoev在2004年开发&#xff0c;并于2004年首次公开发布。Nginx的主要优势在于其非阻塞的事件驱动架构&#xff0c;能够处理大量并…

128陷阱详解(从源码分析)

1、128陷阱描述 Integer 整型 -128~127 超过这个范围&#xff0c;比较会不准确 例子 public static void main(String[] args) {Integer a128;Integer b128;Integer e127;Integer f127;System.out.println(ab); //输出falseSystem.out.println(a.equals(b)); //输出trueS…

小程序做自定义分享封面图,Canvas base64图片数据真机上不显示?【已解决】

首选说一下需求&#xff0c;做一个小程序分享&#xff0c;但是封面图要自定义&#xff0c;除了要有对应商品还有有背景图&#xff0c;商品名。类似这种 实现逻辑&#xff0c;把商品图和背景图&#xff0c;再加上价格和商品名用canvas 渲染出来 这是弄好之后的效果图&#xff0…

LeetCode-刷题记录-前缀和合集(本篇blog会持续更新哦~)

一、前缀和&#xff08;Prefix Sum&#xff09;算法概述 前缀和算法通过预先计算数组的累加和&#xff0c;可以在常数时间内回答多个区间和相关的查询问题&#xff0c;是解决子数组和问题中的重要工具。 它的基本思想是通过预先计算和存储数组的前缀和&#xff0c;可以在 O(1)…

NCCL 中的一些辅助debug 知识点

1&#xff0c;调试nccl 启动kernel的方法 ncclLaunchKernel cuLaunchKernelEx ncclStrongStreamLaunchKernel cudaLaunchKernel ncclLaunchOneRank cudaLaunchKernel 在 nccl lib 中&#xff0c;不存在使用<<<grid, block,,>>> 这种类似方式启…

【咨询】企业数字档案馆(室)建设方案-模版范例

导读&#xff1a;本模版来源某国有大型医药行业集团企业数字档案馆&#xff08;室&#xff09;建设方案&#xff08;一期300W、二期250W&#xff09;&#xff0c;本人作为方案的主要参与者&#xff0c;总结其中要点给大家参考。 目录 1、一级提纲总览 2、项目概述 3、总体规…

【零基础】学JS之APIS(基于黑马)

喝下这碗鸡汤 披盔戴甲,一路勇往直前! 1. 什么是事件 事件是在编程时系统内发生的动作或者发生的事情 比如用户在网页上单击一个按钮 2. 什么是事件监听? 就是让程序检测是否有事件产生&#xff0c;一旦有事件触发&#xff0c;就立即调用一个函数做出响应&#xff0c;也称为 注…

深度学习(笔记内容)

1.国内镜像网站 pip使用清华源镜像源 pip install <库> -i https://pypi.tuna.tsinghua.edu.cn/simple/ pip使用豆瓣的镜像源 pip install <库> -i https://pypi.douban.com/simple/ pip使用中国科技大学的镜像源 pip install <库> -i https://pypi.mirro…

华为eNSP:HCIA汇总实验

本次拓扑实验需求&#xff1a; 1、内网地址用DHCP 2、VLAN10不能访问外网 3、使用静态NAT 实验用到的技术有DHCP、划分VLAN、IP配置、VLAN间的通信&#xff1a;单臂路由、VLANIF&#xff0c;静态NAT、基本ACL DHCP是一种用于自动分配IP地址和其他网络参数的协议。 划分VLA…

Elasticsearch:Node.js ECS 日志记录 - Winston

这是继上一篇文章 “Elasticsearch&#xff1a;Node.js ECS 日志记录 - Pino” 的续篇。我们继续上一篇文章来讲述使用 Winston 包来针对 Node.js 应用生成 ECS 向匹配的日子。此 Node.js 软件包为 winston 记录器提供了格式化程序&#xff0c;与 Elastic Common Schema (ECS) …

Linux系统下的用户管理模式

Linux系统下的用户管理模式 本文以属于Linux系统基本概念&#xff0c;如果以查找教程教程&#xff0c;解决问题为主&#xff0c;只需要查看本文后半部分。 如需要系统性学习请查看本文前半部分。 文章目录 Linux系统下的用户管理模式1. Linux下用户的概念2. 创建不同类型的用户…

前沿重器[53] | 聊聊搜索系统6:精排

前沿重器 栏目主要给大家分享各种大厂、顶会的论文和分享&#xff0c;从中抽取关键精华的部分和大家分享&#xff0c;和大家一起把握前沿技术。具体介绍&#xff1a;仓颉专项&#xff1a;飞机大炮我都会&#xff0c;利器心法我还有。&#xff08;算起来&#xff0c;专项启动已经…

STM32实战篇:闪灯 × 流水灯 × 蜂鸣器

IO引脚初始化 即开展某项活动之前所做的准备工作&#xff0c;对于一个IO引脚来说&#xff0c;在使用它之前必须要做一些参数配置&#xff08;例如&#xff1a;选择工作模式、速率&#xff09;的工作&#xff08;即IO引脚的初始化&#xff09;。 IO引脚初始化流程 1、使能IO引…

TTS模型汇总

TTS是“Text-to-Speech”的缩写&#xff0c;中文意思是“文本到语音”。这是一种将文本信息转换成口语的技术&#xff0c;通常通过计算机程序实现。TTS技术可以应用于多种场景&#xff0c;包括但不限于&#xff1a; 辅助阅读&#xff1a;帮助视障人士或有阅读困难的用户通过听…

SHARPNESS-AWARE MINIMIZATION FOR EFFICIENTLY IMPROVING GENERALIZATION--论文笔记

论文笔记 资料 1.代码地址 https://github.com/google-research/sam https://github.com/davda54/sam 2.论文地址 https://arxiv.org/abs/2010.01412 3.数据集地址 论文摘要的翻译 在当今严重过度参数化的模型中&#xff0c;训练损失的值很难保证模型的泛化能力。事实上…