当前位置: 首页 > news >正文

【Linux】进程概念(四)(命令行参数和环境变量) - 详解

目录

  • 前言
  • 一、命令行参数
  • 二、环境变量
    • 1. 基本概念
    • 2. 常见环境变量
      • echo $ NAME :查看某个环境变量
      • env 显示所有环境变量
        • dev/pts/0 字符设备
        • OLDPWD 保存上一次所处路径
    • 3. 多方法获取环境变量
      • 使用main函数
      • 通过函数获取单个环境变量
      • 全局指针获取
      • 子进程如何获得环境变量
      • 实践
    • 4. 环境变量的全局性
  • 三、内建命令引入

前言

书接上文【Linux】Linux进程概念(三)(进程状态,僵尸进程,孤儿进程,进程优先级)详情请点击查看。今天继续讲解【Linux】进程概念(四):(命令行参数和环境变量)

一、命令行参数

命令行参数是程序运行时从命令行传递给程序的参数,命令行参数允许用户在启动程序时提供额外的信息或配置选项

问题引入:main函数是否有参数?可以有几个参数?具体是哪几个参数?

  • 现在我们直接编写一段C语言代码来回答上面的问题,main函数是有参数的,我们一定见过下面代码main函数的参数,但是argv指向的字符串到底是什么呢?
    在这里插入图片描述
  • 我们来编写一个代码来打印出数组指向的字符串 在这里插入图片描述
  • 从上面的结果可以知道,argv[0] 是程序名,argv[1-n]是程序运行时命令行传递给程序的程序名后面的选项,有了这些我们就可以通过不同的选项来达到不同的功能
#include <stdio.h>                                            #include <string.h>    int main(int argc, char* argv[])    {  if(argc != 2){printf("传入参数错误,使用-v1/-v2/-v3\n");return 1;}if(strcmp(argv[1], "-v1") == 0)printf("功能1\n");else if(strcmp(argv[1], "-v2") == 0)printf("功能2\n");else if(strcmp(argv[1], "-v3") == 0)printf("功能3\n");elseprintf("功能不支持\n");return 0;                                                                                                            }

在这里插入图片描述

  • 我们使用指令ls、ls -l、ls -a -l 等,指令的本质就是C语言程序,通过在命令行输入不同的选项(选项本质就是字符串)可以以一定方式传递给ls内部的main函数,在ls内部实现的时候,就可以根据不同的选项实现类似功能的不同表现形式
    在这里插入图片描述
  • 在命令行输入相关指令或者运行自己的代码之后(ls -l、./testArg -v1),是谁拿到了这个字符串信息:答案是父进程bash拿到了,父子进程共享数据和代码,所以子进程也能拿到参数信息,但是如何传给argv数组,后面程序替换时再具体讲解

在argv数组中存储字符串,最后一位保存的是NULL
在这里插入图片描述
因此打印argv数组中字符串,不仅可以使用上上面的方法,还可以使用下面代码来打印

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

总结:

  1. 命令行参数至少有一个(程序名)
  2. argv[0] 对应是程序名
  3. 有几个子串(串与串之间空格隔开),argc就等于几

二、环境变量

1. 基本概念

环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数,环境变量通常具有某些特殊作用,同时它还具有全局属性

2. 常见环境变量

  1. PATH:指定命令的搜索路径(操作系统查找可执行命令是在环境变量PATH中查找的
  • 对于指令ls、pwd等直接在命令行输入就可以执行,但是自己的可执行程序直接a.out会找不到,原因就是指令直接保存在系统路径/usr/bin路径下,输入指令后会去系统路径去找,找到了就执行,没有找到就会报错:没有找到该执行文件
  • 所以如果是自己的程序执行,可以使用./a.out来执行,如果不想带路径,那么就可以把当前的可执行程序路径加入到环境变量中
  • 加入指令为:expert PATH=$PATH:路径
  1. HOME:指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
  2. SHELL:当前Shell,它的值通常是/bin/bash

echo $ NAME :查看某个环境变量

  1. PATH环境变量以冒号(:)为分割符
    在这里插入图片描述

env 显示所有环境变量

在这里插入图片描述

dev/pts/0 字符设备
OLDPWD 保存上一次所处路径
  • OLDPWD是保存上一次所处路径,因此 cd - 才能返回上一路径,cd -实质就是cd $OLDPWD
    在这里插入图片描述

在进入操作系统时,系统会默认自动初始化, 执行pwd、进入Linux操作系统默认进入的家目录等,之所以能知道当前在哪个路径、家目录在哪,都是因为有环境变量的存在

3. 多方法获取环境变量

使用main函数

在命令行参数我们知道了,main函数有argc和argv两个参数,现在我们在来引入另外一个参数:env

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

结果如下:
在这里插入图片描述

  • char* env[]和char* argv[]结构是一样的,都是保存的字符串数据,且最后一个都是保存的NULL

通过函数获取单个环境变量

在这里插入图片描述

  1. 使用getenv函数来获取某个环境变量
#include <stdio.h>#include <string.h>#include <stdlib.h>int main(int argc, char* argv[], char* env[]){char* path = getenv("PATH");printf("PATH:%s\n", path);return 0}

在这里插入图片描述

全局指针获取

  1. C语言提供了一个全局指针
  2. environ是一个二级指针,指向的是环境变量的环境变量表
    在这里插入图片描述
#include <stdio.h>#include <string.h>#include <stdlib.h>int main(int argc, char* argv[], char* env[]){extern char ** environ;int i = 0;for(;  environ[i]; i++){printf("environ[%d] : %s\n", i, environ[i]);}return 0:}

子进程如何获得环境变量

  • 获得环境变量的是父进程bash,并形成的环境变量表,环境变量表是父进程数据,子进程继承了父进程的代码和数据

总结:

  • bash有两张表:命令行参数表(一直在变)、环境变量表(比较稳定),因为命令行参数一直在变,这两张表是内存级的
  • 命令行参数bash能从命令行获取,但是bash的环境变量又是从哪里来呢?从系统的配置文件中来,
    在这里插入图片描述

实践

  1. 实现一个程序只有当前用户(本人)才能执行代码功能
#include <stdio.h>#include <stdlib.h>#include <string.h>int main(){char* who = getenv("USER");if(strcmp(who, "gy")){printf("不是指定用户,不能执行, %s\n", who);return 1;}printf("这是一个只有我自己能执行的程序\n");return 0;}

在这里插入图片描述
在这里插入图片描述
2.实现pwd

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

在这里插入图片描述

  • 从前面的学过的知识我们可以知道,进程会记录下自己的工作路径cwd,bash也有自己的cwd,且保存在task_strcut中,因此子进程会以父进程为模板创建,所以子进程的pwd从父进程bash来。但是父进程的cwd又怎么获得的呢?
  • 使用函数getcwd,系统调用获得当前pwd来更新环境变量
    在这里插入图片描述
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>int main(){char pwdbuf[128];char *pwd = getcwd(pwdbuf, sizeof(pwdbuf));printf("%s\n", pwd);return 0;}

在这里插入图片描述

注意:
环境变量大部分从配置文件中来,也有少部分是启动之后动态获取或者创建的

4. 环境变量的全局性

我们所运行的进程是子进程,bash本身在启动的时候会从操作系统的配置文件中读取环境变量信息,子进程会继承父进程交给子进程的环境变量,bash是所有进程的父进程,bash创建的子进程有可能再创建子进程,那么此时的进程关系就形成了一颗多叉树的形状,那么对应由于子进程要继承父进程的环境变量,而bash又是所有进程的父进程,那么bash中的环境变量在全部进程中都会有一份,那么此时环境变量就具有全局属性

本地变量,即在bash命令行中定义出的变量是本地变量,本地变量只在本bash内部有效,不会被子进程继承,本地变量不同于环境变量,本地变量不归属环境变量,同样环境变量不归属本地变量

  1. export 变量名(= ?):设置一个新的环境变量
  2. unset 变量名:清除环境变量
  3. 本地变量可以通过export将自己变为环境变量
  4. 当本地变量使用export变成环境变量之后,可以通过unset将环境变量再变回本地变量
  5. 可以使用set查看环境变量和本地变量
    在这里插入图片描述

三、内建命令引入

在这里插入图片描述

  1. 观察上图小编在bash命令行中定义了一个本地变量myset,本地变量myset不会被子进程继承,那么根据小编之前的理论,指令是一个二进制可执行程序,那么echo的本质就是创建了一个子进程,但是为什么echo这个子进程可以查看本地变量myset的值呢?
  2. 究其原因是大部分命令是可执行程序,需要通过创建子进程的性质来执行。但是在Linux中,还有一部分命令执行的时候本身没有风险,需要bash自己执行,这样的命令叫做内建命令
http://www.jsqmd.com/news/313685/

相关文章:

  • MySQL--库的操作、数据类型、表的操作
  • Spring 框架: IOC、DI、AOP 三大核心
  • 运行报表:支撑IT外包公司为客户交付全栈网络报表分析方案
  • 季度管理升级:助力设备商为客户交付季度协同管理升级方案
  • aiohttp+asyncio 实现高并发异步爬虫
  • Thinkphp和Laravel+办公管理系统_
  • HTML元素+网页布局区块概念汇总表
  • Thinkphp和Laravel儿童性教育新闻文章论坛网站_
  • matlab simulink 使用ros2 的sub和pub需要注意的事项,以及部署事项(注意事项)
  • 人工智能数据分析科学家:20个月系统培养大纲 (1.0版)【20260128】002篇
  • 热销榜单:2026年抗菌抗病毒无纺布供应商推荐
  • Excel CHOOSE函数全攻略:从基础选择到高级数据重组的全能工具
  • Excel INDIRECT函数深度解析:动态引用的终极武器
  • 04基于观测器的线性多智能体事件触发一致性
  • Reddit营销:如何在Reddit写出“像用户一样”的营销贴?、
  • SQL 注入已死?WAF 绕过实战:我是如何攻破这个“固若金汤”的防火墙的
  • AIGC设计:内容生成与场景落地的核心方法与实践指南
  • AI绘图:快速出好图的核心技巧与常见误区
  • 2026毕设ssm+vue旅游分享平台论文+程序
  • 2026毕设ssm+vue旅游服务软件论文+程序
  • 2026毕设ssm+vue旅游出行系统论文+程序
  • 2026毕设ssm+vue旅游打卡系统论文+程序
  • ArcGIS Python零基础脚本开发教程---1.1 Describe 函数
  • 探秘Silane-PEG8-DBCO,硅烷-聚乙二醇8-二苯并环辛炔:三功能连接分子的设计与应用
  • 2026毕设ssm+vue旅游管理系统论文+程序
  • 向量数据库到底香不香?这篇选型指南帮你不再踩坑
  • 全网热议!2026年知名全自动砖机公司排名推荐,发现高品质固废与液压砖机厂家
  • 铁轨表面缺陷检测这事儿听起来挺硬核,但用MATLAB玩起来其实有点意思。咱们直接撸代码说人话,先搞张铁轨灰度图读进来
  • 【RAG】99-AI大模型应用RAG工程培训总体介绍
  • Linux环境编程第四天笔记