【Linux】命令行参数和环境变量

devtools/2024/9/24 11:01:02/

一、命令行参数

我们平时写的main函数都是没有参数的,但其实下面的写法也是正确的。在使用时它的参数可带可不带,如果带上我们要明白其含义。

int  main(int argc, char *argv[]);   //argv代表一个指针数组,argc代表指针数组中的元素个数

  1#include<stdio.h>2 #include<unistd.h>3 int main(int argc, char *argv[])4 {5  for(int i = 0; i < argc; i++)6  {7    printf("argv[%d] -> %s\n",i,argv[i]);8  }9 }                                                                                                                                                                 

 我们在命令行处输入以下内容结果如下:

 可以看出当在命令行处只输入路径+可执行程序名时,argc = 1,argv[0] -> 路径+程序名;当输入两个参数,数组就会有两个元素,0号下标仍指向程序名。

为什么要有命令行参数呢?本质就是交给我们程序的不同选项,用来定制不同的程序功能。命令行会携带很多的选项。

这样说可能还会有些不明白,看看下图。我们常用的ls指令也是如此,携带不同的后缀就显示出不同形式的信息。

谁做到的呢?--bash

由上图可以看出父进程的数据可以默认被子进程看到并访问。

验证代码如下:

  1 #include<stdio.h>2 #include<unistd.h>3 4 int g_val = 100;5 6 int main()7 {8   printf("I am father process,pid:%d,ppid:%d,g_val:%d\n",getpid(),getppid(),g_val);9   sleep(5);10   int id = fork();11   if(id == 0)12   {13     while(1)14     {15       printf("I am child process,pid:%d,ppid:%d,g_val:%d\n",getpid(),getppid(),g_val);16       sleep(1);17     }18   }19   else20   {21    while(1)22    {23     printf("I am father process,pid:%d,ppid:%d,g_val:%d\n",getpid(),getppid(),g_val);24     sleep(1);25    }26  }27 }

 为什么两次执行后父进程的ppid一直保持不变,我们使用指令查看一下ppid为11515的进程是谁。结果查出是bash。命令中启动的程序,都会变成进程,并且其实是bash的子进程。

二、环境变量

为什么我们执行自己的程序时需要加上路径呢?可不可以像系统指令一样不加路径使用呢?

        在Linux中,存在着一些全局的设置,这些设置表明,告诉命令行解释器,应该去哪些路径下去寻找可执行程序。                      

PATH就是一个环境变量,$PATH用来打印环境变量的内容。

系统中的很多配置,在我们登录Linux系统时就已经被加载到了bash进程中。bash在执行命令的时候,需要先找到命令,因为未来要加载。

上图可以看出PATH中并没有test.exe所在路径,所以并不能直接执行它。

要想像执行命令一样执行程序,只能修改配置文件。

//通过以下指令打开文件后将要添加的路径加入其中

vim .bash_profile

vim .bashrc

vim /etc/bashrc

env指令 --> 显示所有的环境变量

        1.HOME  --> 用户的家目录

        2.PWD  --> 用户当前所处路径

        3.SHELL --> 打印出bash进程的路径和程序名

        4.HISTSIZE --> Linux会默认记录用户输入的最新的1000条历史命令

echo $XXX --> 打印环境变量内容

export name=value --> 导入环境变量

        导入时不加export时,变量仍会被导入,但是使用env并不会显示出该变量,而使用echo $XXX却能查找的,将这种称为本地变量。

unset name --> 取消环境变量

理解:

环境变量本身具有系统级的全局属性,因为环境变量本身会被子进程继承下去。

我们获得环境变量的方式有两种

//方式一int main(int argc,int *argv[], char *env[]){extern char **environ;for(int i = 0; environ[i];i++){printf("env[%d]->%s\n",i,environ[i]);}}
//方式二int main(int argc,int *argv[], char *env[]){extern char **environ;for(int i = 0; environ[i];i++){printf("env[%d]->%s\n",i,environ[i]);}}

但是得到的结果都是env[0]->XDG_SESSION_ID=26753 、env[1]->HOSTNAME=iZ0jlec5mvndmhan316glmZ 这种形式,对我们来说看起来不方便,每次还要自己分解字符串。还有一种方式,通过函数getenv(环境变量名)来获得环境变量的内容,用例如下。

 int main(){char *path = getenv("PATH");if(path == NULL)return 1;printf("path:%s\n",path);}

        我们可以通过export指令来导入环境变量。export是指令,在执行的时候应该创建子进程,又因为进程具有独立性,父进程是不能看见子进程的定义的变量及对数据的修改的,那么这样的话echo $HELLO指令执行后应该什么也找不到的,即不应该被bash看到所导的变量。那为什么会有下面的结果呢?因为指令export和echo都被称为内建命令,由bash亲自执行。除内建命令外其余80%的命令都是通过bash创建子进程执行的。

验证:

将环境变量PATH置为空后,ls、touch等指令不能执行,export、echo指令仍可执行。

当我们在命令行直接建立一个变量时,使用echo指令可以查看其内容,为什么使用env指令却查找不到呢?

虽然这个变量不能查出来,但并不代表它真的没有,它仍在bash进程内部存在,只不过并没有被当做环境变量来看待。通过下面的代码发现也不能找到该变量。

 int main(){char *path = getenv("HELLO");                                                 if(path == NULL)return 1;printf("path:%s\n",path);}

我们知道子进程会继承父进程的环境变量表,运行结果表明HELLO不在环境变量表里。此时HELLO是本地变量

将HELLO导入为环境变量

export HELLO

再执行代码,便可查找出了。

本地变量(只能被内建命令找到)只在本bash内有效,无法被子进程继承下去。只有将本地变量导成环境变量才可能被获取。


http://www.ppmy.cn/devtools/8759.html

相关文章

Centos安装软件失败There are no enabled repos.

这个错出现的原因可能是&#xff1a;没有先安装wget源&#xff0c;就把源给备份了 解决方案&#xff1a; 下载对应版本repo文件, 放入/etc/yum.repos.d/里&#xff0c;下载地址&#xff1a;CentOS镜像使用帮助 查看自己CentOS的版本&#xff0c;下载对应的repo文件&#xff…

VS安装教程

文章目录 VS安装步骤 VS安装步骤 &#xff08;1&#xff09; 下载VS2022社区版&#xff08;根据情况选择自己需要的版本下载&#xff09;&#xff0c;下载的方式&#xff0c;可以通过微软官方下载。https://visualstudio.microsoft.com/zh-hans/downloads/?cidlearn-onpage-d…

Gateway网关跨域问题

一、模拟跨域问题 通过vscode打开&#xff0c;模拟跨域问题的前端资料&#xff0c;在黑马视频中老师那个命令我似乎是不行的&#xff0c;应该是还没下载相关操作指令&#xff0c;但是可以通过下载一个插件来实现启动&#xff08;Live Server&#xff09;。 下载好后右键&#…

Java项目实现图形验证码(Hutool)

项目架构&#xff1a; 使用SpringCloudmysqlmybatis-plus需要将数据库中的数据导出到Excel文件中 前端为Vue2 业务场景&#xff1a; 登录时使用验证码登录 1.1 打开hutool, 搜索 图片验证码 1.2后端编写生产验证码方法 1.3前端 1.3.1展示验证码 1.3.2 前端方法 1.3.2.1UU…

linux进阶篇:ftp的概念特点及安装配置过程

Linux搭建ftp服务&#xff1a;ftp的应用案例及其概念特点 一、ftp介绍 &#xff08;File Transfer Protocol&#xff0c;文件传输协议&#xff09;是一种在互联网中进行文件传输的协议&#xff0c;基于客户端/服务器模式。它使用TCP/IP协议进行通信&#xff0c;默认使用20和2…

【前端】3. CSS【万字长文】

CSS 是什么 层叠样式表 (Cascading Style Sheets). CSS 能够对网页中元素位置的排版进行像素级精确控制, 实现美化页面的效果. 能够做到页面的样式和结构分离. CSS 就是 “东方四大邪术” 之化妆术. 基本语法规范 选择器 {一条/N条声明} 选择器决定针对谁修改 (找谁)声明决…

kali linux 的语言切换为中文

前言&#xff1a; 为了解决很多同学看不懂英文的问题&#xff0c;出一个linux语言切换中文的教程。 教程&#xff1a; 第一步&#xff1a; 打开Terminal&#xff0c;输入命令&#xff1a; sudo dpkg-reconfigure locales 第二步&#xff1a; 选择语言&#xff0c;使用空格键…

Vue快速入门

一、准备工作 1.下载node.js 配置npm 直接去官网下载https://nodejs.org/en/download 建议使用v18版本&#xff0c;一直next即可&#xff0c;下载完毕。打开命令窗口输入node -v 如下图显示&#xff0c;表示安装成功。 2.使用cnpm下载vue cli cnpm install -g vue/cli 下…