Linux:命令行参数和环境变量

文章目录

  • 命令行参数
  • 环境变量
    • 环境变量的概念
    • 常见的环境变量
    • PATH
  • 环境变量表
  • 本地变量和环境变量
  • 命令分类

本篇主要解决以下问题:

  1. 什么是命令行参数
  2. 命令行参数有什么用
  3. 环境变量是什么
  4. 环境变量存在的意义

命令行参数

在学习C语言中,对于main函数当初的写法是没有任何参数的,但是实际上,main函数是可以有参数的,比如下面的写法:

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

因此这里将内容打印出来,看看这当中是什么内容

程序运行结果如图所示

[test@VM-16-11-centos 10_15]$ vim myproc.c
[test@VM-16-11-centos 10_15]$ make
gcc -o myproc myproc.c
[test@VM-16-11-centos 10_15]$ ./myproc 
0:./myproc

其实,命令行参数是用来支持各种指令级别的命令行选项的设置,例如这里的argv数组中,存储的字符串其实就是用户写的命令,而如果现在我在运行程序的时候带上选项

[test@VM-16-11-centos 10_15]$ ./myproc -a -b -c -d
0:./myproc
1:-a
2:-b
3:-c
4:-d

会发现打印的信息就是以用户写的指令开始进行分割,然后把信息放到数组中,从中其实看出,用户在运行程序的时候写的命令或者是带的选项都可以被main函数读取并且传参,函数体内部就可以利用这个机制实现不同的选项带来的结果

比如,Linux中有ls命令,用来查看文件夹中的内容,如果使用的是ls -a或者是ls -l这些选项,就会产生不同的结果,实际上这样的结果也是通过这个原理,通过读取argv数组中的内容就可以实现各种目的

这里其实可以模拟实现一个touch命令:

#include <stdio.h>
#include <string.h>int main(int argc, char* argv[])
{if (argc == 2){if (strcmp(argv[0], "./myproc") == 0){FILE* pf = fopen(argv[1], "w");if (pf == NULL){perror("fopen fail\n");return 1;}fclose(pf);}else  {printf("commend error,you should use ./myproc [name]\n");}}else{printf("commend error,you should use ./myproc [name]\n");}return 0;
}

运行结果如下所示:

[test@VM-16-11-centos 10_15]$ ./myproc test.txt
[test@VM-16-11-centos 10_15]$ ll
total 20
-rw-rw-r-- 1 test test   64 Oct 15 15:36 Makefile
-rwxrwxr-x 1 test test 8568 Oct 15 15:57 myproc
-rw-rw-r-- 1 test test  602 Oct 15 15:57 myproc.c
-rw-rw-r-- 1 test test    0 Oct 15 15:57 test.txt

这样就模拟实现了一个touch指令,只不过现在还有一个问题,在实际使用touch指令的时候,我并不需要带前面的这个./,而是直接可以运行,那么为什么呢?

这就涉及到了环境变量的问题:

环境变量

首先,不管是在什么系统什么环境中,要执行一个命令,必须要找到相应的可执行程序,这是一定的,那么由此可以引出环境变量的概念:

环境变量的概念

  • 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数,如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找
  • 环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性

常见的环境变量

  1. PATH:指定命令的搜索途径
  2. HOME:指定用户的主工作目录
  3. SHELL:当前Shell,一般是/bin/bash

那么现在查看touch命令的位置

[test@VM-16-11-centos 10_15]$ which touch
/usr/bin/touch

从中可以看出,touch命令确实是被放在了这个地方,而正是由于它被放在了这个文件夹内,因此在运行的时候会默认在这个路径下搜索运行,因此,如果我们把前面定义的myproc程序放到对应的目录下,那么当执行命令的时候,会优先到对应的目录下搜索,因此也就不需要指定是在当前路径,而是会选择去一个默认路径,如果基于这样的理论,就可以找到对应的内容了

[test@VM-16-11-centos 10_15]$ sudo mv myproc /usr/bin
[test@VM-16-11-centos 10_15]$ myproc test1.txt
[test@VM-16-11-centos 10_15]$ ll
total 8
-rw-rw-r-- 1 test test  64 Oct 15 15:36 Makefile
-rw-rw-r-- 1 test test 600 Oct 15 16:08 myproc.c
-rw-rw-r-- 1 test test   0 Oct 15 16:09 test1.txt
-rw-rw-r-- 1 test test   0 Oct 15 15:57 test.txt

从中可以看出,确实创建成功了,也就是说上面的理论是正确的

PATH

PATH路径中,存在的路径就是上面所说的默认搜索路径,如果我们能想办法让路径增加呢?也就是说,能否通过增加PATH中的值,就能达到在默认路径下搜索文件了,在Linux中存在一个export命令可以修改PATH路径,下面来进行执行

[test@VM-16-11-centos 10_15]$ export PATH=$PATH:/home/test/10_15
[test@VM-16-11-centos 10_15]$ myproc test1.txt
[test@VM-16-11-centos 10_15]$ ll
total 20
-rw-rw-r-- 1 test test   64 Oct 15 15:36 Makefile
-rwxrwxr-x 1 test test 8568 Oct 15 16:19 myproc
-rw-rw-r-- 1 test test  600 Oct 15 16:08 myproc.c
-rw-rw-r-- 1 test test    0 Oct 15 16:21 test1.txt

从中可以看出,已经成功的将PATH路径添加到这里了,于是在程序的默认搜索路径中就多了/home/test/10_15路径,bash会在这个路径下进行搜索执行的命令

但是同时有一个问题,当退出Linux机器重新访问后,PATH文件中的路径又恢复成了原来的信息文件,综上可以总结出一些信息:

Linux机器在登陆的时候会发生什么?

  1. 输入用户名和密码
  2. 进行认证
  3. 形成环境变量,比如PATHPWDHOME这些
  4. 根据用户名进行一定的初始化
  5. cd ¥HOME

这样,就可以根据不同的用户进入不同的目录中,实现不同的权限级别的信息了

环境变量表

在引入环境变量表的概念前,先看环境变量

和环境变量相关的命令:

  1. echo: 显示某个环境变量值
  2. export: 设置一个新的环境变量
  3. env: 显示所有环境变量
  4. unset: 清除环境变量
  5. set: 显示本地定义的shell变量和环境变量

在这里插入图片描述
上图展示了系统中的环境变量,实际上在main函数的参数中,是有第三个参数的,而这个参数提供的就是环境变量表,也就是说,系统在启动程序的时候,是可以选择给main函数进程提供两张表的:

  1. 命令行参数表
  2. 环境变量表

下面做实验来证明环境变量表的存在性:

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

在这里插入图片描述
此时运行出的结果和前面基本相同,从中也印证了前面说的原理,在进程启动的时候,系统会提供两个表供使用

思考

命令行启动的进程都是shell/bash的子进程,这是前面进行进程学习的时候知道的,但是问题在于子进程的命令行参数和环境变量是从哪里来的?答案是父进程来的,那么父进程的环境变量信息又是从哪里来的呢?

此时要和前面的内容进行一些联系,为什么每一次重新登陆,都会为用户形成新的bash解释器,并且新的bash解释器会形成自己的环境变量表信息呢?这是由于它从配置文件中读取到了这些信息

由此可以得出一个结论:环境变量信息是以脚本配置文件的形式所存在的

每一次登陆的时候,bash进程会从一个叫做.bash_profile文件中读取内容,由此为bash进程创建一张环境变量表信息,由此bash在创建其他进程的时候,就可以传递环境变量信息了

查看环境变量

# .bash_profile# Get the aliases and functions
if [ -f ~/.bashrc ]; then. ~/.bashrc
fi# User specific environment and startup programsPATH=$PATH:$HOME/.local/bin:$HOME/binexport PATH

本地变量和环境变量

上面最后演示了环境变量的读取文件,那么这里引入了一个新的概念叫做本地变量,那么本地变量应该如何进行理解?

直接用实验来论证:

首先创建一个本地变量:

[test@VM-16-11-centos ~]$ MYENV="hello"
[test@VM-16-11-centos ~]$ echo $MYENV
hello

此时创建出的是一个本地变量,但是本地变量并没有被放到环境变量中,因此在环境变量中也是搜索不到这个本地变量的:

[test@VM-16-11-centos ~]$ env | grep MYENV
# 无输出结果

此时需要用一个命令:export->可以将本地命令转到环境变量中去

[test@VM-16-11-centos ~]$ export MYENV
[test@VM-16-11-centos ~]$ env | grep MYENV
MYENV=hello

此时,在环境变量中就找到了这个配置文件,那么在main函数中是否会存在呢?

[test@VM-16-11-centos 10_18]$ ./myproc |grep MYENV
13:MYENV=hello

也找到了这个变量,就进一步的论证了,环境变量表是由bash传递给子进程的

现在重启Linux机器:

# 找不到内容了
[test@VM-16-11-centos ~]$ env | grep MYENV
# 运行结果也找不到对应的内容
[test@VM-16-11-centos ~]$ ~/10_18/myproc | grep MYENV

这是由于,在登陆Linux服务器后,会根据配置文件中的信息对bash进行初始化,而此时并没有进行初始化信息,因此就需要对配置文件进行一些修改:

# .bash_profile# Get the aliases and functions
if [ -f ~/.bashrc ]; then. ~/.bashrc
fi# User specific environment and startup programsPATH=$PATH:$HOME/.local/bin:$HOME/bin# 增加配置信息
MYENV=hello  
export MYENV  export PATH

此时继续重新启动

[test@VM-16-11-centos ~]$ env | grep MYENV
MYENV=hello
[test@VM-16-11-centos ~]$ ~/10_18/myproc | grep MYENV
12:MYENV=hello

找到了对应的内容,由此引出本地变量和环境变量:

**本地变量:**只在bash进程内部有效,不会被子进程继承下去
**环境变量:**通过让所有子进程继承的方式,实现自身的全局性

由此得出一个结论:环境变量是具有全局性的

命令分类

看下面的实验:

# 将PATH变量设置为空
[test@VM-16-11-centos ~]$ export PATH=""
# 以下命令均不能使用
[test@VM-16-11-centos ~]$ ll
-bash: ls: No such file or directory
[test@VM-16-11-centos ~]$ touch
-bash: touch: No such file or directory
[test@VM-16-11-centos ~]$ mkdir
-bash: mkdir: No such file or directory
# pwd仍然可以使用
[test@VM-16-11-centos ~]$ pwd
/home/test

为什么呢?

Linux中的命令分类:

  1. 常规命令:shell通过fork让子进程执行的
  2. 内建命令:shell命令行的一个函数,可以直接读取shell内部定义的本地变量

而在上面的测试中,像lsmkdir这样的命令,都是shell通过fork创建子进程来执行的,而这里的PATH路径已经被用户破坏了,因此找不到搜索的路径,因此找不见是当然的事,但是为什么pwd可以找到?这是由于pwd这样的命令是内建命令,这是shell命令行的一个函数,可以直接读取shell内部的本地变量,因此就可以找到对应的值进行输出了

本篇是关于命令行参数和环境变量的,要清楚环境变量的组织形式:

在这里插入图片描述
会提供一个environ指针,这个指针会指向一张环境表,环境表是一个字符指针数组,每一个指针都会有一个字符串

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

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

相关文章

【数据结构】830+848真题易错题汇总(自用)

【数据结构】830848易错题汇总(10-23) 文章目录 【数据结构】830848易错题汇总(10-23)选择题填空题判断题简答题&#xff1a;应用题&#xff1a;算法填空题&#xff1a;算法设计题&#xff1a;(待补) 选择题 1、顺序栈 S 的 Pop(S, e)操作弹出元素 e&#xff0c;则下列(C )是正…

Android中使用Glide加载圆形图像或给图片设置指定圆角

一、Glide加载圆形头像 效果 R.mipmap.head_icon是默认圆形头像 ImageView mImage findViewById(R.id.image);RequestOptions options new RequestOptions().placeholder(R.mipmap.head_icon).circleCropTransform(); Glide.with(this).load("图像Uri").apply(o…

最新Tuxera NTFS2024破解版mac读写NTFS磁盘工具

Tuxera NTFS for Mac是一款Mac系统NTFS磁盘读写软件。在系统默认状态下&#xff0c;MacOSX只能实现对NTFS的读取功能&#xff0c;Tuxera NTFS可以帮助MacOS 系统的电脑顺利实现对NTFS分区的读/写功能。Tuxera NTFS 2024完美兼容最新版本的MacOS 11 Big Sur&#xff0c;在M1芯片…

Oracle数据库 ORA-28001: the password has expired解决方法

今天在用dbvisualizer登录数据库的时候&#xff0c;报了the password has expired的错误&#xff0c;于是上网查了一下原因&#xff0c;是因为数据库密码过期了&#xff0c;因为默认的是180天。 解决方法&#xff1a; 1&#xff09;用系统用户登录 #在cmd终端输入&#xff1…

基于晶体结构优化的BP神经网络(分类应用) - 附代码

基于晶体结构优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于晶体结构优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.晶体结构优化BP神经网络3.1 BP神经网络参数设置3.2 晶体结构算法应用 4.测试结果…

【单片机基础】使用51单片机制作函数信号发生器(DAC0832使用仿真)

文章目录 &#xff08;1&#xff09;DA转换&#xff08;2&#xff09;DAC0832简介&#xff08;3&#xff09;电路设计&#xff08;4&#xff09;参考例程&#xff08;5&#xff09;参考文献 &#xff08;1&#xff09;DA转换 单片机作为一个数字电路系统&#xff0c;当需要采集…

UE5 运行时生成距离场数据

1.背景 最近有在运行时加载模型的需求&#xff0c;使用DatasmithRuntimeActor可以实现&#xff0c;但是跟在编辑器里加载的模型对比起来&#xff0c;室内没有Lumen的光照效果。 图1 编辑器下加载模型的效果 图2 运行时下加载模型的效果 然后查看了距离场的数据&#xff0c;发现…

华为智选SF5,AITO问界的车怎么样

#华为智选 #赛力斯SF5 #aito问界m5 #aito问界m7 #华为汽车 华为的车&#xff0c;后杠焊两点&#xff0c;拉车的时候&#xff0c;拖车钩断了&#xff0c;后杠拉出来了&#xff0c;这质量可以吗&#xff1f;是否应该全部召回&#xff1f;M5&#xff0c;M7是不是也这样&#xff1f…

蓝桥杯(跳跃 C++)

思路&#xff1a; 1、根据题目很容易知道可以用深度搜索、广度搜索、动态规划的思想解题。 2、这里利用深度搜素&#xff0c;由题目可知&#xff0c;可以往九个方向走。 3、这里的判断边界就是走到终点。 #include<iostream> using namespace std; int max1 0; int …

增加并行度后,发现Flink窗口不会计算的问题。

文章目录 前言一、现象二、结论三、解决 前言 窗口没有关闭计算的问题&#xff0c;一直困扰了很久&#xff0c;经过多次验证&#xff0c;确定了问题的根源。 一、现象 Flink使用了window&#xff0c;同时使用了watermark &#xff0c;并且还设置了较高的并行度。生产是设置了…

微服务负载均衡实践

概述 本文介绍微服务的服务调用和负载均衡&#xff0c;使用spring cloud的loadbalancer及openfeign两种技术来实现。 本文的操作是在微服务的初步使用的基础上进行。 环境说明 jdk1.8 maven3.6.3 mysql8 spring cloud2021.0.8 spring boot2.7.12 idea2022 步骤 改造Eu…

Windows下定时下载Linux服务器的数据库备份文件(pscp+bat脚本+定时任务)

下载传输软件pscp Download PuTTY: latest release (0.79) 创建bat执行脚本 echo 删除旧的备份文件 del D:\db_bk\*.dbecho 下载新的备份文件 D:\Programs\pscp -P 22 -pw youPassword youName192.168.1.1:/home/backup/test.db D:\db_bk\ 设置定时任务 1.使用任务计划程…

Halcon 中查看算子和函数的执行时间

1、在Halcol主窗口的底栏中的第一个图标显示算子或函数的执行时间&#xff0c;如下图&#xff1a; 2、在Halcon的菜单栏中选择【窗口】&#xff0c;在下拉框中选择【打开输出控制台】&#xff0c;进行查看算子或函数的执行时间&#xff0c;如下图&#xff1a;

音视频技术开发周刊 | 315

每周一期&#xff0c;纵览音视频技术领域的干货。 新闻投稿&#xff1a;contributelivevideostack.com。 OpenAI科学家最新演讲&#xff1a;GPT-4即将超越拐点&#xff0c;1000倍性能必定涌现&#xff01; GPT-4参数规模扩大1000倍&#xff0c;如何实现&#xff1f;OpenAI科学家…

Spring核心扩展点BeanDefinitionRegistryPostProcessor源码分析

我们知道&#xff0c;只要在一个Java类上加上Component、Service、Controller等注解&#xff0c;就可以被加载到Spring容器中&#xff0c;除了以上方式&#xff0c;加了Bean和Import好像也可以将对象添加到Spring容器中&#xff0c;究竟Spring是如何实现这些功能的呢&#xff1…

Redis 主从复制,哨兵,集群——(1)主从复制篇

目录 1. Redis 主从复制是什么&#xff1f; 2. Redis 主动复制能干嘛&#xff1f; 2.1 读写分离 2.2 容灾恢复 2.3 数据备份 2.4 水平扩展支撑高并发 3. Redis 主从复制配置项 3.1 配从库不配主库 3.2 权限密码配置 3.3 基本操作命令 4. 案例演示 4.1 案例说明 4.…

tika解压遇到压缩炸弹如何继续解压

1.问题 项目中要对10层压缩的zip、7z等文件用tika解压遇到错误&#xff1a;tika zip bomb detected 也就是说tika认为这是个压缩炸弹。 “压缩炸弹”是一个压缩包文件的木马程序&#xff0c;通常只有几百KB&#xff0c;解压后会变成上百MB或者上GB庞然大物。把你本地磁盘占满…

迁移conda环境后,非root用户执行pip命令和jupyter命令报错/bad interpreter: Permission denied

移动conda环境&#xff0c;在移动的环境执行pip和jupyter 报错-bash: /data/home/用户名/anaconda3/envs/llm/bin/pip: /root/anaconda3/envs/llm/bin/python: bad interpreter: Permission denied 报错信息 一、原因 原因是当前的这个data/home/用户名/anaconda3/envs/环境名…

2022年亚太杯APMCM数学建模大赛A题结晶器熔剂熔融结晶过程序列图像特征提取及建模分析求解全过程文档及程序

2022年亚太杯APMCM数学建模大赛 A题 结晶器熔剂熔融结晶过程序列图像特征提取及建模分析 原题再现&#xff1a; 连铸过程中的保护渣使钢水弯液面隔热&#xff0c;防止钢水在连铸过程中再次氧化&#xff0c;控制传热&#xff0c;为铸坯提供润滑&#xff0c;并吸收非金属夹杂物…

37 WEB漏洞-反序列化之PHPJAVA全解(上)

目录 PHP反序列化演示案例&#xff1a;先搞一把PHP反序列化热身题稳住-无类问题-本地在撸一把CTF反序列化小真题压压惊-无类执行-实例最后顶一把网鼎杯2020青龙大真题舒服下-有类魔术方法触发-实例 https://www.cnblogs.com/zhengna/p/15661109.html 代码在线测试平台&#xff…