【Linux】环境变量--PATH环境变量/环境变量的操作/命令行参数

news2024/11/29 4:34:28

文章目录

  • 一、PATH环境变量
    • 1.什么是PATH环境变量
    • 2.如何添加PATH环境变量
    • 3.系统中的其他环境变量
    • 4.环境变量的来源
  • 二、环境变量的操作
    • 1.设置环境变量
    • 2.通过getenv获取环境变量
    • 3.环境变量的意义
  • 三、命令行参数

一、PATH环境变量

1.什么是PATH环境变量

这里我们先提出一个问题:为什么我们运行自己写的程序需要带路径,而系统的指令不需要带路径?

这是因为系统能找到它的位置,系统中是存在相关的环境变量,保存了程序的搜索路径的,系统中搜索可执行程序的环境变量叫做PATH。所以我们只需要把我们的程序拷贝到/usr/bin/路径下即可(但是我们不推荐,理由下面解释)

首先我们理解什么是环境变量

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

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

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

所以事实上,Linux中的各种指令本质上是/usr/bin目录下的一个个可执行的程序,和我们自己编写的可执行程序没有任何区别。但是使用指令的时候,系统会自动去PATH中寻找指令,如果找到了就执行,没有找到就报错-“command not found”,所以Linux中的各种指令不需要指定路径,而我们自己写的程序需要指定路径

2.如何添加PATH环境变量

我们可以使用如下指令来查看PATH环境变量中包含的内容:

echo $PATH

在这里插入图片描述

我们需要注意的是,PATH中不同的路径分隔符为:

我们也可以通过向PATH中添加内容让我们自己的程序可以不指定路径就能被执行

方法一:直接将程序添加到/usr/bin目录下(不建议使用这种方法,因为我们写的程序没有经过测试,可能会污染指令池)

在这里插入图片描述

我们删除使用如下指令:

sudo rm /usr/bin/mycmd

之后我们执行我们自己写的程序又需要带上路径

在这里插入图片描述

方法二:使用export命令将当前可执行程序的路径导入PATH

export PATH=$PATH:当前路径

在这里插入图片描述

【注意】

$PATH代表之前的PATH中的内容,:之后的尾新添加的内容,所以我们不能直接使用如下指令:

export PATH=当前路径

因为这样会将之前PATH中的内容覆盖掉,使得Linux中的各种指令必须指定目录才能执行,因为操作系在/usr/bin找不到系统中原来的指令了,此时,我们只需要重新登录即可,因为环境变量属于内存级变量,我们每次登录shell的时候,环境变量都会重新编译执行。同时,PATH中不能有空格,因为Linux中以空格作为分隔符

在这里插入图片描述

我们学过Java的同学都知道,我们在最开始学的时候需要在windows中配置环境变量,其实本质就是向PATH中添加内容(windows中的路径分隔符为分号)

windows下查看环境变量:

设置->关于->高级系统设置->环境变量

在这里插入图片描述

3.系统中的其他环境变量

PATH环境变量只是系统中众多环境变量的一种,除了PATH,我们还有许多其他环境变量,不同的环境变量有不同的功能,也适用于不同的场景

PATH : 指定命令的搜索路径

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

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

HOSTNAME:主机名

USER:当前用户名

PWD:当前系统路径

HISTSIZE:shell能记住的最多的历史命令的数量

在这里插入图片描述

我们也可以使用env命令来查看系统中所有的环境变量:

在这里插入图片描述

4.环境变量的来源

我们使用“ ls - al /hone/hdp”指令就可以发现家目录下 存在两个隐藏文件–.bash_profile与.bashrc:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

实际上,我们在登录shell的时候,操作系统会让我们当前的shell进行执行.bash_profile文件内的内容,而.bash_profile又会调用执行.bashrc,他们会将对应的环境变量导入到shell进程的上下文环境中,所以,这样解释了为什么我们把$PATH覆盖了之后,重新登录shell之后就可以了

环境变量的定义

环境变量是操作系统为了满足不同的应用场景,预先在系统内设置一大批全局变量,这些变量往往具有特殊功能,且能够一直被bash以及bash的子进程访问。

环境变量具有全局属性的根本原因是环境变量会被子进程继承

二、环境变量的操作

1.设置环境变量

Linux命令行的可以定义变量的,但是我们以这种方式定义的变量吧本地变量,即只在bash进程中有效,而不是环境变量,因为环境变量具有全局属性

在这里插入图片描述

我们可以使用export直接定义环境变量,也可以使用它将已经存在的本地变量变成环境变量

在这里插入图片描述

我们可以使用set命令来查看所有变量,包括环境变量和本地变量,使用unset来取消变量,包括环境变量和本地变量

在这里插入图片描述

2.通过getenv获取环境变量

我们可以使用 echo $环境变量名 来获取特定的环境变量,也可以通过getenv()函数来获取环境变量:

在这里插入图片描述

其中name是我们需要获取环境变量的名称,如果获取成功就返回环境变量的具体内容,失败就返回NULL

这样我们就可以使用getenv()函数来编写系统中某些指令了,比如pwd:

#include <stdio.h>
#include <stdlib.h>
#define MYPWD "PWD"
int main()
{
    char* env = getenv(MYPWD);
    printf("%s\n",env);
    return 0;
}

在这里插入图片描述

3.环境变量的意义

我们知道,环境变量是操作系统为了满足不同的应用场景,预先在系统内设置的一大批全局变量,其中PATH就是为了满足我们指令路径搜索的需求,而除了指令需求之外还有许多其他需求,其中非常重要的一个就是身份认证

我们以一个例子说明:

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

#define USER "USER"

int main()
{
    char* who = getenv(USER);
    if(strcmp(who,"root")==0)
    {
        printf("user:%s\n",who);
        printf("user:%s\n",who);
        printf("user:%s\n",who);
        printf("user:%s\n",who);
        printf("user:%s\n",who);
    }
    else
    {
        printf("权限不足\n");
    }
    
    return 0;
}

在这里插入图片描述

我们这里使用su -,而不是su,因为su -会重新登录shell,此时shell会重新加载环境变量,让$USER从hdp变成root,而su只是把用户身份切换为root

在这里插入图片描述

我们可以在程序内部通过getenv函数来获取当前Linux用户,然后判断其是否具备某种权限,再执行对应的操作

此外,我们还可以使用stat来获取一个文件的其他属性,比如读写执行等,然后根据这些属性判断一个用户是否能对该文件进行对应的操作

在这里插入图片描述

stat指令是一个用于显示文件或目录详细信息的命令,包括文件大小、创建时间、修改时间、访问时间和权限等。在Linux和Unix操作系统中,stat命令通常使用以下语法:

stat [选项] 文件名

其中,选项可以是以下之一:

  • -c:指定自定义格式输出。
  • -f:指定文件系统信息输出格式。
  • -t:指定时间格式输出。

三、命令行参数

我们出来可以通过getenv函数来获取环境变量,还可以通过命名行参数来获取环境变量

我们知道,C语言中的main函数是有参数的,这些参数可以通过命令行进行传递:

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

其中argc是一个整数,代表的是argv数组元素的个数,argv是一个指针数组,数组里面的每一个元素都指向一个字符串

我们可以打印argv数组中存放的环境变量,增加选项时环境变量也随之增加

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

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

在这里插入图片描述

他们配合使用就可以实现类似于"ls -a -l -d"选项的功能,通过我们传递不同的选项使用不同的功能

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

int main(int argc,char* argv[],char* env[])
{
    if(argc != 2)
    {
        printf("Usage: \n\t\%s [-a/-b/-c/-ab/-ac/-bc]\n",argv[0]);
    }
    if(strcmp("-a",argv[1]) == 0)
    {
        printf("功能a\n");
    }
    if(strcmp("-b",argv[1]) == 0)
    {
        printf("功能b\n");
    }
    if(strcmp("-c",argv[1]) == 0)
    {
        printf("功能c\n");
    }
    if(strcmp("-ab",argv[1]) == 0)
    {
        printf("功能ab\n");
    }
    if(strcmp("-ac",argv[1]) == 0)
    {
        printf("功能ac\n");
    }
    if(strcmp("-bc",argv[1]) == 0)
    {
        printf("功能bc\n");
    }
    
    return 0;
}

在这里插入图片描述

而指针数组env就是用于接受父进程传递过来的环境变量的参数,我们可以在main函数中打印env的内容:

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

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

在这里插入图片描述

程序也可以通过环境表environ来获取环境变量–环境变量表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境变量字符串,每个进程都会收到一张环境变量表

在这里插入图片描述

在这里插入图片描述

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

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

在这里插入图片描述

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

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

相关文章

限制Domain Admin登录非域控服务器和用户计算机

限制Domain Admin管理员使用敏感管理员帐户(域或林中管理员组、域管理员组和企业管理员组中的成员帐户)登录到信任度较低的服务器和用户端计算机。 此限制可防止管理员通过登录到信任度较低的计算机来无意中增加凭据被盗的风险。 建议采用的策略 建议使用以下策略限制对信任度…

Python 自动化: eip、cen监控数据对接到 grafana

新钛云服已累计为您分享775篇技术干货 概览 日常运维中&#xff0c;我们有时需要关注阿里云中 EIP 和 CEN 的监控数据&#xff0c;如果每次登录到平台查看&#xff0c;不太方便。 可以通过 API 获取监控数据&#xff0c;并输入到 influxDB&#xff0c;然后再到 Grafana 中展示&…

2023最新最全【虚幻4引擎】下载安装零基础教程

1、创建Epic Games账户 我们先打开浏览器&#xff0c;输入以下网址&#xff1a;unrealengine.com 随后点击【立即开始】 选择许可证类型&#xff0c;此处提供三种选项&#xff0c;分别是【游戏】、【非游戏】以及【私人定制】 第一类许可证适用于游戏和商业互动产品&#xff…

CSS特效012:边框线条环绕流动效果

CSS常用示例100专栏目录 本专栏记录的是经常使用的CSS示例与技巧&#xff0c;主要包含CSS布局&#xff0c;CSS特效&#xff0c;CSS花边信息三部分内容。其中CSS布局主要是列出一些常用的CSS布局信息点&#xff0c;CSS特效主要是一些动画示例&#xff0c;CSS花边是描述了一些CSS…

小程序如何添加打印机来打印订单

在采云小程序中&#xff0c;支持打印订单的小票、标签、发货单和电子面单。小票打印机用于打印小票&#xff0c;类似于超市小票、外卖小票等。标签打印机用于打印商品标签&#xff0c;类似于奶茶上面粘贴的标签&#xff0c;用于表示饮料名称和规格等。货单打印机用于打印发货单…

Rust 语言中的结构体

目录 1、结构体 2、结构体的定义和实例化 2.1 使用字段初始化简写语法 2.2 使用结构体更新语法从其他实例创建实例 2.3 没有命名字段的元组结构体 2.4 没有任何字段的类单元结构体 2.5 结构体示例程序 3、方法 3.1 关联函数 3.2 多个 impl 块 1、结构体 struct&…

C++二分查找算法:规划兼职工作

题目 你打算利用空闲时间来做兼职工作赚些零花钱。 这里有 n 份兼职工作&#xff0c;每份工作预计从 startTime[i] 开始到 endTime[i] 结束&#xff0c;报酬为 profit[i]。 给你一份兼职工作表&#xff0c;包含开始时间 startTime&#xff0c;结束时间 endTime 和预计报酬 pro…

DDR3 的相关设计规范(个人总结)

文章目录 阻抗控制布局布线电源处理时序要求 DDR3 的相关设计规范(个人总结) 阻抗控制 DDR3 要严格控制阻抗&#xff0c;单线 50ohm&#xff0c;差分 100ohm&#xff0c;差分一般为时钟、DQS。在走线过程中&#xff0c;尽量减小阻抗跳变的因素&#xff0c;比如:换层(无法避免…

Python编程技巧 – 使用列表(list)

Python编程技巧 – 使用列表(list) Python Programming Skills – Using a List 在Python编程语言中&#xff0c;我们会用到许多列表&#xff08;List&#xff09;。 一门强大的编程语言会包含列表&#xff08;或者数组&#xff09;的数据结构。列表&#xff08;或数组&#…

workman使用手册1.0

workman官网地址&#xff1a;高性能PHP应用容器 workerman 1&#xff1a;把workman项目放到linux服务器后&#xff0c;需要启动你的php文件&#xff0c;才可以使用 定位到项目根目录&#xff1a;例&#xff1a;cd /mnt/workman 启动代码&#xff1a;php outin.php start -d 停…

【计算机网络笔记】网络地址转换(NAT)

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

鸿蒙LiteOs读源码教程+向LiteOS中添加一个系统调用

本文分为2个部分&#xff1a;第1部分简要介绍如何读鸿蒙Liteos源码&#xff0c;第2部分是实验向LiteOS中添加一个系统调用的完整过程。 前置资料&#xff1a; imx6ull开发板使用方式详解 源码下载 编译运行简单程序 Ubuntu虚拟机使用鸿蒙LiteOs操作系统常见错误汇总 一、鸿…

二进制的形式在内存中绘制一个对象实例

一、引用类型实例的内存布局 从内存布局的角度来看&#xff0c;一个引用类型的实例由如下图所示的三部分组成&#xff1a;ObjHeader TypeHandle Fields。前置的ObjHeader用来缓存哈希值和同步状态&#xff0c;TypeHandle部分存储类型对应方法表&#xff08;Method Table&…

2023年亚太杯数学建模思路 - 复盘:光照强度计算的优化模型

文章目录 0 赛题思路1 问题要求2 假设约定3 符号约定4 建立模型5 模型求解6 实现代码 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 问题要求 现在已知一个教室长为15米&#xff0c;宽为12米&…

Golang 协程、主线程

Go协程、Go主线程 1)Go主线程(有程序员直接称为线程/也可以理解成进程):一个Go线程上&#xff0c;可以起多个协程&#xff0c;你可以这样理解&#xff0c;协程是轻量级的线程。 2)Go协程的特点 有独立的栈空间 共享程序堆空间 调度由用户控制 协程是轻量级的线程 go线程-…

[CSS] 文本折行

文本折行一般分为两种情况&#xff1a; CJK&#xff08;Chinese/Japanese/Korean&#xff09; 字符和非 CJK 字符。一般非 CJK 字符折行发生在两个单词的空格中间&#xff0c;见下图&#xff1a; 图中文本 “hello world” 包裹容器的宽度为 2rem&#xff0c;但是 hello 并没有…

RocketMQ的适用场景有哪些?

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一波电子书籍资料&#xff0c;包含《Effective Java中文版 第2版》《深入JAVA虚拟机》&#xff0c;《重构改善既有代码设计》&#xff0c;《MySQL高性能-第3版》&…

基于单片机的自动循迹小车(论文+源码)

1.系统设计 此次基于单片机的自动循迹小车的设计系统&#xff0c;结合循迹模块来共同完成本次设计&#xff0c;实现小车的循迹功能&#xff0c;其其整体框架如图2.1所示。其中&#xff0c;采用STC89C52单片机来作为核心控制器&#xff0c;负责将各个传感器等模块链接起来&…

qt槽函数的四种写法

槽函数的四种写法 一,Qt4写法 不推荐这种写法,如果SLGNAL写错了,或者信号名字,槽函数名字写错了.编译器检查不出来,导致程序无响应,引起不必要的误解 connect(ui.btnOpen,SLGNAL(clicked),this,SLOT(open()));二,Qt5写法 推荐使用这种写法&#xff0c;信号名字、槽函数名字…

uniapp使用Canvas实现电子签名

来源&#xff1a; 公司的一个需求&#xff0c;需要给新注册的会员和客商需要增加签署协议功能&#xff1b; 之前的思路&#xff1a; 1、使用vue-signature-pad来实现电子签名&#xff0c;但是安卓手机不兼容&#xff1b; 2、uniapp插件市场来实现&#xff0c;但是对HBuilderX…