命令行参数、环境变量详解

目录

一、命令行参数:

二、环境变量PATH

1、理解什么是环境变量

2、常见环境变量和操作

3、整体理解环境变量,系统,程序

4、如何获取环境变量(c语言)

(1)getenv() 函数

(2)使用 extern char **environ

5、内建命令

特点和用法


一、命令行参数:

我们常写的main函数是可以带参数的

int main(int argc, int argv[],int )
{
    //...
    return 0;
};

当我们在命令行输入带有main函数的程序时,
可以在程序的后面输入一些值
如图:

makefile文件:

 myprocess:myprocess.c                                                                                                        
  2   gcc -o myprocess myprocess.c -std=c99 
  3 
  4 .PHNOY:clean
  5 clean:
  6   rm -f myprocess
~

c文件:

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

当你输入n个值,argc的大小就是n
对应的,就会开辟一个大小为n的argv数组
argv数组的最后一个位置是NULL
第一个位置argv[0]一定是程序名
那么这个有什么用处呢?

其实我们输入的命令行,本质是一行字符串:
这一行字符串的意义: 程序的路径 + 名称 和 该进程匹配的选项
例如:

ls -l
ls -a
ls -d
ls -dla
….

ls本质是一个程序,后面的-x代表这个程序的不同的功能
你在命令行输入ls
本质上和你自己执行一个自己写的 ./xxx.c 可执行程序没有任何区别

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

父进程的数据,默认能被子进程看到并访问
且命令行中启动的程序,都会变成进程,其实都是bash的子进程
因此,我们平常在命令行中输入的命令,就是默认输入给bash父进程的
而bash就叫做命令行解释器
因此,bash就会把输入的字符串解释成对应的信息表
而子进程是可以看到父进程的信息的
因此,父进程就可以把对应的参数,初始化为argc,和argv[],再传给对应的子进程执行

二、环境变量PATH

1、理解什么是环境变量

可是,为什么我们在运行自己的程序时,必须加上./
执行ls pwd等程序却不需要呢?
而执行程序,首先要找到命令的所在位置,然后加载到内存中,再运行
所以,我们可以这样理解:
ls等命令不需要路径,是不是因为bash已经知道了这个程序的路径呢?
而且这个路径以某种形式默认着
而我们自己写的程序,因为没有这种默认,所以bash不认识,所以必须要指明路径
是不是这个原因呢?
是的,没错,就是如此
而这个默认的形式,就是环境变量,PATH

在Linux中,存在一些全局的设置,这些设置告诉命令行解释器,应该去哪些路径寻找可执行程序
这样,就不需要专门的再加上一个./路径
PATH是一个一系列路径的组合:

在执行一个程序时,如果这个命令在PATH的默认路径上逐个搜寻,如果找到了
就直接加载到内存并执行
如果没有找到,就提示找不到命令

这也就是为什么,当你输入一个字符串命令的时候
本质上其实是输入一个程序
这个字符串要被bash命令行解释器解释,这也就是为什么bash叫做命令行解释器
解释的过程,其实就是在环境变量设置的默认路径中,寻找对应程序的过程
如果找不到对应的程序
这个时候,命令行就会提示如下:

找不到命令行,这就是原因!

查看环境变量:

echo $PATH

(我这里用的是root用户,我们在使用自己的操作系统时,尽量不要使用root用户,因为权限太高,容易出事情)

那么,如果,我的程序也要像系统命令一样,不需要./就可以直接运行
怎么办?
很简单,比较简单粗暴的做法就是,直接cp我们的程序到/usr/bin/路径下

cp XXX /usr/bin/ 

这样,就可以像系统命令一样直接运行了

例如:当我把我的可执行文件直接拷贝到/usr/bin环境变量路径下,我就可以直接像执行命令一样,直接运行我自己写的文件。

但是强烈不建议这样做
因为会污染系统的指令集
但是事实上,这种环境变量只是一个内存级别的
什么意思?
当系统退出后,操作系统数据和代码退出内存,那么你的设置也就随之消失了
这也就说明,最开始的环境变量并不是保存在内存中,而是存在操作系统的配置文件中
每一加载Linux操作系统,都会读取加载操作系统的配置文件的内容
所以,你在修改PATH的时候,修改的只是内存中的运行备份
而没有修改操作系统的配置文件的内容

那么,配置文件在哪里
在家目录下的:
bash_profile
bashrc
/etc/bashrc

那么,到底怎么加呢?
千万不敢这样加:
PATH = 某某某路径
这会导致,你直接篡改了整个环境变量,把原来系统的默认路径都直接修改了
这样,你原来的系统命令都不能用了
应该这样加:

PATH = $PATH:/某某路径

因此,PATH是Linux下默认查找程序命令和路径,也是which查找命令指令的默认路径

2、常见环境变量和操作

查看所有环境变量:

env

查看单个环境变量:

echo $环境变量名

导进自定义环境变量:(如果不加export,叫做本地变量)

export name=value (可以是数字、字符等)

删除环境变量:

unset XXX

示例:

export mypath=1111#添加

env#全局查找

echo $mypath#单独查找

unset mypath #删除

env#全局查找

常见的环境变量:
HOME:家目录
PWD:当前路径,会动态跟进修改
HISTSIZE:历史命令记录(Linux默认1000条,我的显示是10000条)
SHELL:外壳程序

3、整体理解环境变量,系统,程序

bash进程启动的时候,默认会给子进程形成两张表:
 

argv[]命令行参数表:有用户输入命令行形成
env[]环境变量表:由操作系统的配置文件读取来形成

其中,bash通过某种方式将两张表交给子进程(其实是通过execvpe函数,在进程替换部分有)
所以,本质上,echo $PATH命令的执行
其实就是在env[]环境变量表(二级指针数组)进行遍历查找并打印出来的过程
再继续理解,其实export环境变量,其实就是再env[]环境变量表中添加一个字符串而已

其实,mian函数最多可以有三个参数:

int argc, char* argv[], char* env[]

环境变量具有系统级别的全局属性,因为环境变量本身可以被子进程继承
为什么被子进程继承就有全局属性呢?
因为bash是所有进程的父进程

4、如何获取环境变量(c语言)

(1)getenv() 函数:

函数原型:

char *getenv(const char *name);

功能:根据给定的环境变量名称 name,返回对应的环境变量值(字符串形式)。如果该环境变量不存在,则返回 NULL。
示例用法:(variable意为变量)

#include <stdio.h>
#include <stdlib.h> // for getenv()

int main() {
    char *env_value = getenv("PATH");
    if (env_value != NULL) {
        printf("PATH environment variable: %s\n", env_value);
    } else {
        printf("PATH environment variable not found.\n");
    }
    return 0;
}

(2)使用 extern char **environ

功能:environ 是一个全局变量,它指向当前进程的环境变量数组。可以遍历这个数组来获取所有的环境变量及其值。
示例用法:

#include <stdio.h>
extern char **environ;

int main() {
    char **env = environ;
    while (*env != NULL) {
        printf("%s\n", *env);
        env++;
    }
    return 0;
}

注意:使用 environ 时,需要包含 <stdio.h> 头文件,但不需要额外的 <stdlib.h>。

5、内建命令

Linux内建命令(built-in commands)指的是直接由shell(如bash)内部实现并提供的命令,而不是通过调用外部可执行文件来执行。这些命令被编译进shell的可执行文件中,因此在调用它们时不需要创建新的进程,执行速度相比外部命令更快,并且对shell的控制能力更强。

特点和用法:

  1. 性能优势:由于内建命令不需要调用外部程序,因此执行速度通常比外部命令更快,特别是在频繁调用时能显著减少系统资源的消耗。

  2. 对shell的影响:内建命令可以更深入地影响和操作shell的状态和行为,例如改变shell的环境变量、控制shell的作业和进程、修改shell的行为等。

  3. 通常的内建命令:具体的内建命令会因不同的shell而有所差异

以下是bash shell中常见的内建命令示例:

内建命令功能
cd切换当前工作目录
echo打印文本或变量到标准输出
alias创建命令别名
export设置环境变量
unset删除环境变量或shell变量
exit退出当前shell
jobs显示当前作业(jobs)列表
fg将后台作业切换到前台
bg将作业置于后台运行
source 或 .执行shell脚本并保持在当前shell环境中

 

export、echo等为内建命令
也就是说,这些命令是bash内部的一个函数
执行这些程序时,不需要创建子进程
而是bash直接调用内部的函数

因此,命令分为两种:一个是普通命令,一个是内建命令
80%的命令是普通命令,普通命令需要创建子进程

本地变量(即未用export命令添加的环境变量成为本地变量)只在本bash内部有效,无法被子进程继承下去,需要export导入环境变量,即添加到环境变量表中,此时才能获取


 

  • 64
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

二十5画生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值