目录
前言
1. 命令行参数
什么是命令行参数?
2. 环境变量
常见的环境变量
如何修改环境变量?
获取环境变量
环境变量的组织方式
拓展问题
导入环境变量
3. 本地变量*
总结
前言
在使用Linux指令的时候, 都是指令后边根命令行参数, 每个指令本质都是一个一个的可执行程序, 我们自己编译形成的可执行程序在运行时需要指定路径, 为什么Linux指令不需要, 并且指令的命令行参数又是如何读取的, 我们自己的可执行程序能读取命令行参数吗? 本文将会通过命令行参数与环境变量来解答这些问题;
1. 命令行参数
什么是命令行参数?
命令行参数是用户在命令行界面中输入的附加信息,用于向可执行程序传递参数或选项。
举个例子 :
我们常使用的 ls 指令, 就是一个可执行程序, 而后边跟的参数 "-a" "-l" 这些都属于是命令行参数;
我们如何获取命令行中的参数?
在C/C++中, 可以通过main函数的两个参数 (argc和argv) 获取;
编写一个简单的小程序来获取并打印命令行参数:
#include<stdio.h>
#include<stdlib.h>
#include<unistd.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;
}
argc表示参数的数量,argv是一个字符串数组,包含了每个参数的具体数值
通过这个原理,我们可以根据传进来的参数做出判断,来进行相对应的操作,进而达到指令的效果这里我们也可以明白: Linux中的指令可以支持各种的命令行选项,到底是什么原理
2. 环境变量
Linux中的指令其实也就是一个个的可执行程序, 那么问题来了,为什么我们执行我们自己的可执行程序时需要带 /而操作系统中的指令却不需要? 这里就需要引入一个新的概念: 环境变量
环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
./其实是告诉操作系统可执行文件在当前路径,帮助操作系统找到可执行程序,系统的指令也可以指定路径执行,那么为什么系统指令不需要指定文件路径?只有一种解释,这些可执行程序一定存在着默认的搜索路径,在Linux环境变量中有着PATH这个变量,它存放的就是可执行程序的默认搜索路径;
常见的环境变量
- PATH : 指定命令的搜索路径
- HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
- SHELL : 当前Shell,它的值通常是/bin/bash
使用指令查看环境变量:
- 查看指定环境变量
echo $NAME //NAME:你的环境变量名称
// 比如我要查看PATH这个环境变量
echo $PATH
- 查看当前系统中的环境变量
env
要想我们自己的可执行程序也可以不指定路径直接运行, 只需要把我们的可执行程序移到环境变量指定的路径 或者 把可执行程序的路径添加到环境变量中;
如何修改环境变量?
- 添加路径:
PATH=$PATH : 可执行程序路径
//$PATH表示原有内容,:表示追加
注意:PATH=可执行文件路径会覆盖原有的内容
添加可执行程序的路径后,再执行可执行文件就不需要指定路径了;
- 去除添加的路径:
去除路径:可以使用覆盖的方法进行去除,PATH=修改后的PATH进行覆盖
如果不小心把环境变量清空也不要担心,默认更改环境变量只限于本次登录,只需要重新登录即可恢复
- 取消环境变量(或本地变量)
unset 环境变量名
获取环境变量
前边以经提到了一种获取环境变量的方式(指令), 还有另外三种获取环境变量的方法:
- 系统调用 (getenv)
char *who = getenv("USER");
if(strcmp(who, "root") != 0)
{
printf("%s,是一个非法用户\n",who);
return 1;
}
- main函数的第三个参数
#include <stdio.h>
int main(int argc, char *argv[], char *env[])
{
int i = 0;
for(; env[i]; i++)
{
printf("%s\n", env[i]);
}
return 0;
}
- 通过第三方变量environ获取
#include <stdio.h>
int main(int argc, char *argv[])
{
extern char **environ;
int i = 0;
for(; environ[i]; i++)
{
printf("%s\n", environ[i]);
}
return 0;
}
libc中定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以在使用时 要用extern声明
环境变量的组织方式
每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串, 最后以NULL结尾;
拓展问题
- 每次普通用户的默认路径都是/home/XXX,root用户就是root/为什么?
这与环境变量的初始化有关;
登录的时候:
- 输入用户名和密码
- 认证
- 形成环境变量(不止一个)根据用户初始化HOME=/root,HOME=/home/XXX
- cd $HOME
- 为什么修改的环境变量每次重新登录都会恢复?
命令行启动的进程都是shell或bash的子进程,命令行参数和环境变量,都是父进程bash传递的;
bash的环境变量信息可以由命令行参数的形式,直接传递给直系的子进程(被子进程继承下去)
我们直接更改的是bash进程内部的环境变量信息,然而每次登录时都是新的bash进程,每次启动时bash就会从某个地方读取形成自己的环境变量信息;
- bash的环境变量信息从哪里来?
bash的环境变量信息全部都来自系统中的一个配置文件: .bash_profile(脚本配置文件)在每个用户的家目录中,会有一个隐藏文件,.bash profile每次登陆时bash进程都会读取.bash_profile配置文件中的内容,,为bash形成一张环境变量表信息;
导入环境变量
方法一:
- MYENV=变量数据 (本地变量)
- export MYENV
方法二:
- export MYENV= 变量数据
我们每次所修改的环境变量(包含自己导入的), 每次登录都会失效, 那有什么办法让它长期(永久)有效?
打开bash环境变量的配置文件.bash profile:
在内部像export PATH一样,使用export导入我们自己的环境变量,这样每次重启连接时,bash就会读取加入的环境变量
补充:
单一的靠.bash profile中的导入其实并不足以获取全部的环境变量, shel脚本中就可以看出,它还依靠着.bashrc这个文件,打开这个文件,发现它还依靠着:/etc/bashrc,从这几个文件中读取完,才可以形成完整的环境变量信息;
3. 本地变量*
如果只使用MYENV=1000000,不使用export;这时定义的变量就是本地变量;
- 本地变量只在bash内部有效,不会被子进程继承下去;
- 环境变量通过让所有的子进程继承的方式,实现自身的全局性;
想要让本地变量被子进程获取到只能转为环境变量:export MYENV
为什么说这个?
其实就是想要告诉大家一个 "奇怪" 的现象:
我把PATH清空, 然后我使用 ls 这些命令都失效了, 但是我使用echo却还可以继续使用这是为什么?
在Linux中存在着两种命令:
- 常规命令: shell fork(创建子进程)让子进程执行的 (如:Is、mkdir、touch等);
- 内建命令: shell内部建立的命令, shell内部的函数(不创建子进程, 由bash自己执行);
shell内部的函数, 当然可以读取shell内部定义的变量啦!
输出环境变量和本地变量:set
总结
系统中会存在大量的环境变量,每个变量都有自己的特殊用途,用来完成特定的系统功能; 理解环境变量可以让我们直观的了解系统的配置和运行环境,进一步理解系统的工作原理和功能。这有助于我们更好地与操作系统交互, 让操作系统不再陌生神秘; 好了以上便是本文的全部内容, 希望对你有所帮助, 感谢阅读!