【Linux详解】命令行参数|环境变量

news2024/9/23 13:24:19

目录

一、命令行参数

二、环境变量

1.环境变量的基本概念

2.查看环境变量的方法

3.环境变量相关命令

4.环境变量的组织方式以及获取环境变量的三种方法

环境变量具有全局属性


一、命令行参数

【示例1】main函数也是函数,main函数可以带参吗?

没错,main函数有三种形式,其中最完整的形式是

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

}

main函数的参数可带可不带,我们今天讨论的肯定是带参的,那么这些参数是什么呢?这些是命令行参数,让我们接下来看看吧

int main(int argc, char* argc[]){}
  • ·argc(argument count)是一个整数,表示传递给程序的命令行参数的数量。

  • ·argv(argument vector)是一个字符指针数组,其中每个指针指向一个参数字符串。

我们直接来看看这个argv里面有什么东西

int main(int argc, char* argv[]){
  for(int i = 0; i < argc; i++){
    printf("argv[%d]->%s\n",i,argv[i]);
  }
  return 0;
}
[wuxu@Nanyi lesson14]$ gcc -o test minglinghang.c -std=c99
[wuxu@Nanyi lesson14]$ ./test
argv[0]->./test
[wuxu@Nanyi lesson14]$ ./test -a
argv[0]->./test
argv[1]->-a
[wuxu@Nanyi lesson14]$ ./test -d
argv[0]->./test
argv[1]->-d
[wuxu@Nanyi lesson14]$ ./test -a -b -c -d
argv[0]->./test
argv[1]->-a
argv[2]->-b
argv[3]->-c
argv[4]->-d

 

【问题1】为什么要有命令行参数?

本质:命令行参数本质是交给我们程序的不同的选型,用来定制不同的程序功能。命令中会携带很多的选项

应用:自定义命令

下面我们自定义一个命令cdd,这个命令允许用户带1个选项,如果这个选项是-a就输出“Hello,I am cdd”,-b选项就输出“cdd is cool”

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

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

  if(argc == 2 && strcmp("-a",argv[1]) == 0)
  {
    printf("Hello, I am cdd\n");
  }
  else if(argc == 2 && strcmp("-b",argv[1]) == 0)
  {
    printf("cdd is cool!\n");
  }else{
    printf("\r\tYou are supposed to use -a or -b\n");
  }

  return 0;
}
[wuxu@Nanyi lesson14]$ ./cdd -a
Hello, I am cdd
[wuxu@Nanyi lesson14]$ ./cdd -b
cdd is cool!
[wuxu@Nanyi lesson14]$ ./cdd -a -b
        You are supposed to use -a or -b

【问题2】谁干的?

结论1:父进程的数据,能被子进程看到并且访问

结论2:命令行中启动的程序,都会变成进程,其实都是bash的子进程

所以也就是父进程bash干的。bash是一个命令行解释器,我们输入的./cdd -b默认是输入给父进程bash/shell的

  1. 1.程序启动时:当您在命令行中输入程序名称并按回车时,命令行解释器(如 shell)会启动程序,并将命令行参数传递给程序。

  2. 2.操作系统:操作系统负责创建进程,并将命令行参数准备好。当程序开始执行时,操作系统将参数传递给程序的 main 函数。

二、环境变量

1.环境变量的基本概念

环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数。

环境变量通常具有某些特殊用途,在系统当中通常具有全局特性

【示例1】我们在系统中执行ls命令时,不需要./ls,而我们执行自己编写的C语言程序,并编译为可执行程序时,确需要使用./才能运行,这是为什么呢?

使用which命令可以查看该指令的存储位置,比如 which ls,会发现ls存储在/usr/bin/目录中

[wuxu@Nanyi lesson14]$ which ls
alias ls='ls --color=auto'
        /usr/bin/ls

系统中维护了一个PATH环境变量,系统可以帮助我们在PATH环境变量保存的各个路径中查找命令。echo $PATH 命令的作用是输出当前用户的PATH环境变量值。这个值通常包含多个目录,用冒号(:)分隔。例如:

[wuxu@Nanyi lesson14]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/wuxu/.local/bin:/home/wuxu/bin

也就是说,只要我们执行某个命令,这个命令在PATH的环境变量下,那么就可以不使用 ./就可以执行我们的程序。

而我们的程序并没有保存在PATH环境变量的指定目录下,因此无法不带./就执行。所以我们可以通过将可执行文件保存到PATH指定目录,这样就可以不带./运行了。但是这种方式会污染系统的命令,所以我们不建议使用这种方式

【示例2】我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找

2.查看环境变量的方法

echo $[环境变量名]

常见的环境变量

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

◉ HOME:指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)

当我以root用户身份登录时,我的HOME环境变量保存的是/root;但如果我以wuxu用户身份登录时,我的HOME环境变量保存的/home/wuxu。从这里可以发现,不同用户的HOME目录(也称为家目录)是不一样的

[root@Nanyi lesson14]# echo $HOME
/root
[root@Nanyi lesson14]# su wuxu
[wuxu@Nanyi lesson14]$ echo $HOME
/home/wuxu

◉ SHELL:当前shell,它的值通常是/bin/bash

SHELL环境变量定义了当前用户的默认shell类型。这个变量告诉系统在用户登录时应该启动哪个shell。shell是用户与操作系统交互的界面,它负责解释用户输入的命令并执行它们。

默认情况下,当用户登录时,系统会启动用户配置的默认shell。这个shell可以是各种类型的shell,如Bash、Zsh、Fish等。不同的shell有不同的命令语法和特性,因此用户可以根据个人喜好或工作需要选择不同的shell。

SHELL变量的值通常是shell的路径,例如:

  • /bin/bash:Bash(Bourne-Again SHell)是大多数Unix-like系统中默认的shell。

  • /bin/zsh:Zsh(Z shell)是一个强大的shell,提供了许多扩展和增强功能。

  • /bin/fish:Fish是一个现代化的shell,以其简洁的语法和强大的自动完成功能而受到欢迎。

 

[wuxu@Nanyi lesson14]$ echo $SHELL
/bin/bash

3.环境变量相关命令

1️⃣ echo:显示某个环境变量值

[wuxu@Nanyi lesson14]$ echo $PWD
/home/wuxu/lesson14

2️⃣ export:设置一个新的环境变量

[wuxu@Nanyi lesson14]$ export wuxu=123
[wuxu@Nanyi lesson14]$ echo $wuxu
123

注意:export设置的环境变量仅在当前会话有效,当我们将整个会话关闭,重新打开Linux命令行时,这个环境变量就会消失。

在系统中,每次启动bash时,该bash会从系统环境变量配置文件中读取环境变量信息,而export仅仅只是修改了本次启动的bash环境变量,一旦关闭重启后,将会重置环境变量。如果想要使得自定义环境变量永久存在,就需要修改配置文件,也就在/etc/profile添加环境变量

3️⃣ env:显示所有环境变量

4️⃣ unset:清除环境变量

 

 

5️⃣ set:显示本地定义的shell变量和环境变量

显示本地定义变量的前20行

[wuxu@Nanyi lesson14]$ set | head -20
BASH=/usr/bin/bash
BASHOPTS=checkwinsize:cmdhist:expand_aliases:extglob:extquote:force_fignore:histappend:interactive_comments:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
BASH_COMPLETION_COMPAT_DIR=/etc/bash_completion.d
BASH_LINENO=()
BASH_SOURCE=()
BASH_VERSINFO=([0]="4" [1]="2" [2]="46" [3]="2" [4]="release" [5]="x86_64-redhat-linux-gnu")
BASH_VERSION='4.2.46(2)-release'
COLUMNS=107
COMP_WORDBREAKS=$' \t\n"\'><=;|&(:'
DIRSTACK=()
EUID=1000
GROUPS=()
HISTCONTROL=ignoredups
HISTFILE=/home/wuxu/.bash_history
HISTFILESIZE=1000
HISTSIZE=1000

我们可以直接在bash命令行直接定义变量,不再使用export。set除了显示环境变量外,还显示了本地自定义的shell变量,例如

[root@Nanyi lesson14]# bash
[root@Nanyi lesson14]# hahshjs=12902
[root@Nanyi lesson14]# echo $hahshjs
12902

本地变量与bash环境变量的区别:本地定义的变量是局部变量,只在当前shell中有效,而环境变量是全局变量,在整个系统中都是可见的。环境变量通常用于设置系统级别的配置,而本地定义的变量用于存储脚本或命令行中的临时数据。

4.环境变量的组织方式以及获取环境变量的三种方法

每个进程都有一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串

下面介绍3种可以从环境表获取环境变量的方法

1️⃣ getenv

 使用getenv实现pwd命令:

[wuxu@Nanyi lesson14]$ cat testStatus.c
#include<stdio.h>
#include<stdlib.h> 
int main()
{
        printf("%s\n", getenv("PWD"));
        return 0;
}
[wuxu@Nanyi lesson14]$ make
gcc -o testStatus testStatus.c -std=c99
[wuxu@Nanyi lesson14]$ ./testStatus
/home/wuxu/lesson14

2️⃣ 通过第三方变量environ获取

使用environ时,需要先对该变量进行声明,即extern char** environ。下面使用代码打印环境变量的所有内容 

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

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

3️⃣ main函数env参数(命令行第三个参数)

我们在使用命令执行某些可执行程序时,bash会帮助给该程序传入3个参数↓↓↓

 

ls命令为例,ls -a -l,它的命令行参数有3个,分别时ls、-a、-l,因此argv保存的就是{“ls”, “-a”, “-l”, NULL},而第三个参数就是bash传递给它的子进程的环境变量。

下面使用main的env参数打印所有环境变量

#include <stdio.h>

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

环境变量具有全局属性

环境变量具有全局属性,可以被子进程继承下去。子进程的环境变量是从父进程继承来的,默认所有的环境变量都会被子进程继承。

 

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

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

相关文章

Python教程(二十) : 十分钟入门【PyQt6】

文章目录 专栏列表环境准备1 安装 Python2 安装 PyQt6 PyQt6 中的模块使用模块创建一个窗体&#xff1a; PyQt6 常用的控件1. QPushButton&#xff08;按钮&#xff09;2. QLabel&#xff08;标签&#xff09;3. QLineEdit&#xff08;文本输入框&#xff09;4. QTextEdit&…

(4)SVG-path中的椭圆弧A(绝对)或a(相对)

1、概念 表示经过起始点(即上一条命令的结束点)&#xff0c;到结束点之间画一段椭圆弧 2、7个参数 rx&#xff0c;ry&#xff0c;x-axis-rotation&#xff0c;large-arc-flag&#xff0c;sweep-flag&#xff0c;x&#xff0c;y &#xff08;1&#xff09;和&#xff08;2&a…

FFMpeg环境搭建(WIN10)

0、前期准备 软件环境&#xff1a;Win10 qtcreator 软件准备&#xff1a;MSYS2 安装包、 FFmpeg源码 1、软件安装 通过MSYS2安装编译工具 1、打开MSYS2安装包&#xff0c;一路next即可 &#xff08;注&#xff1a;如果需要更改路径可以自行更改&#xff09; 2、安装完成…

虚拟现实辅助工程技术助力多学科协同评估

在当今高速发展的经济环境中&#xff0c;制造业面临着多重挑战&#xff0c;包括提高产品性能、压缩设计周期、实现轻量化设计和降低成本。为了有效应对这些挑战&#xff0c;多学科协同评估成为缩短研发周期和提升研制质量的关键手段。 传统的多学科评估面临着数据孤立与融合困难…

Android 系统源码项目加载预编好的so库

Android 系统源码项目加载预编好的so库 文章目录 Android 系统源码项目加载预编好的so库一、前言二、源码中加载so1、Android.mk加载so加载so的主要相关代码&#xff1a; 2、Android.bp加载so&#xff08;1&#xff09;Android.mk使用源码命令编译成Android.bp&#xff08;2&am…

Java灰度发布

有没有在北京面试java的小伙伴&#xff0c;每家公司面试问的问题都不一样&#xff0c;昨天面试官问到了灰度发布&#xff0c;一脸懵&#xff0c;好像在哪儿听说过&#xff0c;毕竟我都没发布过&#xff0c;之前都是项目组长在干这些事儿&#xff0c;所以聊聊&#xff0c;了解一…

驾驭Autofac,ASP.NET WebApi实现依赖注入详细步骤总结

前言 嘿&#xff0c;小伙伴们&#xff0c;今天我们来一场 Autofac 的学习之旅吧&#xff01; Autofac 是一个轻量级的依赖注入框架&#xff0c;专门为 .NET 应用程序量身定做&#xff0c;它就像是你代码中的 “魔法师”&#xff0c;用它来管理对象的生命周期&#xff0c;让你…

828华为云征文|华为云Flexus X实例docker部署最新gitlab社区版,搭建自己的私人代码仓库

828华为云征文&#xff5c;华为云Flexus X实例docker部署最新gitlab社区版&#xff0c;搭建自己的私人代码仓库 华为云最近正在举办828 B2B企业节&#xff0c;Flexus X实例的促销力度非常大&#xff0c;特别适合那些对算力性能有高要求的小伙伴。如果你有自建MySQL、Redis、Ng…

大数据采集迁移工具

Flume Sqoop kafka框架 MQ&#xff1a;消息队列 broker相当于服务器 消息队列

栈和队列(1)

空栈先移动栈顶再加数据&#xff0c;满栈先插入数据再移 栈的基本概念栈是一种后进先出&#xff08;LIFO&#xff0c;Last In First Out&#xff09;的数据结构。栈支持两种主要的操作&#xff1a;•压栈&#xff08;Push&#xff09;&#xff1a;向栈中添加一个元素。•弹栈&…

Kubernetes v1.28.0安装详解

Kubernetes v1.28.0安装详解 一.环境初始化 要在所有节点执行命令进行配置 1、检查操作系统的版本 此部署环境为CentOS 7.9 [rootCentOS7 ~]# cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core) [rootCentOS7 ~]#2、主机名解析 为了方便集群节点间的互相调…

活动系统开发之采用设计模式与非设计模式的区别-数据库设计及代码设计

1、数据库ER图 2、应用框架选用 PHP语言对应的thinkphp6.1应用框架 3、功能代码设计(后端) a、父类Base.php i&#xff1a;控制登录&#xff0c;只能登录后管理员才能操作&#xff1b; ii&#xff1a;控制按钮权限&#xff0c;管理员不仅要登录&#xff0c;且必须要有对应菜单…

报错处理:超过Uobject最大数量

处理方式 一、打包时项目中设置游戏中UObject的最大数量为100000000 二、打包后的配置文件中设置 打包路径&#xff1a; 一厅统管\Windows\YZ_YTTG\Saved\Config\Windows\Engine.ini文件下添加配置文件 [/Script/Engine.GarbageCollectionSettings] gc.MaxObjectsInEditor1000…

API 网关 OpenID Connect 实战:单点登录(SSO)如此简单

作者&#xff1a;戴靖泽&#xff0c;阿里云 API 网关研发&#xff0c;Higress 开源社区 Member 前言 随着企业的发展&#xff0c;所使用的系统数量逐渐增多&#xff0c;用户在使用不同系统时需要频繁登录&#xff0c;导致用户体验较差。单点登录&#xff08;Single Sign-On&a…

2024最新!Facebook手机版和网页版改名教程!

Facebook作为全球最大的社交平台之一&#xff0c;允许用户自定义名字和昵称。在Facebook更新姓名可以帮助您更好的展现账号形象。本文将为您提供详细的步骤指导&#xff0c;帮助您在手机APP和网页版上轻松完成Facebook改名操作。 Facebook手机版改名 打开Facebook APP并登录账号…

区块链ARC如何能让节点能够大规模处理交易数据

​​发表时间&#xff1a;2024年8月7日 TAAL技术主管Michael Bckli表示&#xff0c;TAAL公司一直在对ARC进行测试&#xff0c;并准备在今年年底全面发布。因TAAL在区块链交易处理方面具备深厚的专业知识&#xff0c;BSV区块链委托TAAL进行ARC开源参考落地方案的开发。 ARC是一个…

魔珐科技受邀参与外滩大会:以3D数字人AIGC产品赋能大资管行业,重塑金融服务边界

在人工智能浪潮的推动下&#xff0c;金融行业正经历着前所未有的场景革命。2024年Inclusion外滩大会作为行业交流的盛会&#xff0c;汇聚了众多学者、专家及企业领袖&#xff0c;共同探讨AI技术在多领域的深度应用&#xff0c;特别是其在金融行业中的革新潜力。 在外滩大会上&…

在桌面商业分析应用程序中启用高级 Web UI

挑战 Mercur Business Control 应用程序在企业界&#xff0c;尤其是金融领域&#xff0c;拥有悠久的应用历史。它帮助企业处理、可视化和分析海量数据&#xff0c;从而做出明智的商业决策。 随着产品的不断演进和现代化&#xff0c;Mercur Solutions AB 为该应用创建了 Web 客…

使用RestTemplate获取国内大盘股票数据的基本信息并存入数据库中

目录 使用RestTemplate获取国内大盘股票数据的基本信息并存入数据库中 第一步&#xff1a;导入RestTemplate依赖&#xff0c;并配置RestTemplate让其加入到SpringIoC容器中 第二步&#xff1a;在yml文件定义股票的相关参数 第三步&#xff1a;向新浪网发送请求&#xff0c;获…

FP7195:非同步升压恒流LED区动IC

前言&#xff1a;LED驱动芯片是什么&#xff1f; LED驱动芯片是一种能够将电源的电压和电流转换为适合LED&#xff08;发光二极管&#xff09;使用的电压和电流的芯片。这种芯片的主要作用是控制LED的亮度和电流&#xff0c;从而保证LED的正常工作和长寿命。简单来说&#xff…