目录
变量
全局变量
局部变量
变量的设置
环境变量是什么?
常见的环境变量
PATH变量
main函数参数
变量
Linux变量分为自定义变量和环境变量 环境变量具有继承性,自定义变量不会被子进程给继承。v
- 环境变量又分为全局变量和局部变量。
- 环境变量有继承性,父进程的子进程同样拥有。
全局变量
需要修改配置文件,变量永久生效
局部变量
使用export命令声明即可,变量在关闭shell时失效。
变量的设置
- 变量与变量的内容用=相隔开
- 且等号两两边不能直接接空格
- 变量的名称可以是英文字母与数字,但开头不能用数字
myval=100 该变量为自定义变量
- 若该变量为扩增变量内容时,可用 ”$变量名称“ 累加内容。
例如:PATH=$PATH:/home/sjp 其中PATH这个变量多加了:/home/sjp 这个内容。
- 如果要想让其它子程序执行,则需要以export开头将变量导入到环境变量中
export myval 将我们的自定义变量myval导入到环境变量中
- 【unset 变量名称】 取消变量
- 通常大写字符为系统默认的变量,自己定义的变量可以用小写
- set 查看所有的变量,包括环境变量
- env 查看所有的环境变量
环境变量是什么?
环境变量可以使系统运行环境配置更加简单灵活,可以通过设置环境变量给进程传递参数信息。
常见的环境变量
PATH:指定命令的搜索路劲:
HOME:当前用户的主工作目录(即Linux登录时,默认的目录),cd ~去的就是我们的主
SHELL:当前shell,它的值是通常是/bin/shell
PATH变量
创建一个hello.c文件:
#include<stdio.h>
int main()
{
printf("hello sjp\n");
return 0;
}
当我们把这个文件编译链接形成我们的可执行程序hello。
[sjp@iZwz97d32td9ocseu9tkn4Z lesson13]$ make
gcc -c hello.c
gcc -o hello hello.o
hello是我们的可执行程序,相当于一个命令,当我们直接敲hello去运行的时候,发现运行不了,为什么呢?
原因是命令行解释器bash找不到这个指令,因为我们没把hello这个指令的路径给它,它就不知道从哪里找,所以要想运行它可以在hello前面带 { ./ } , { ./ }是代表当前目录下,所以我们要运行一个可执行程序为什么经常要在可执行程序前面带{ ./ } 的原因。
还有是将hello的绝对路劲给它,这样我们也是可以运行hello这个可执行程序。
可是我们要想让这个hello这个指令在前面不带任何路劲的东西,就可以我们的bash也能够找到它,那应该怎么做呢?
我们可以参考一下我们平时敲的指令是怎么做的,例如 ls cd等等指令,这些指令在执行的时候前面是没有加任何路劲的东西,因为它们的的路径被包含再PATH。
我们先来看一下PATH这个环境变量的包含的内容:
[sjp@iZwz97d32td9ocseu9tkn4Z lesson13]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/sjp/.local/bin:/home/sjp/bin
echo $NAME //NAME是你的变量名称 查看变量包含的内容
我们可以看到$PATH的内容包含着一条条路劲,每条路劲是由 冒号间隔着( :) ,例如/usr/local/bin是一条路径,上面总共有7条路径。
我们在看一下ls这个指令是在哪一条路劲底下:
这一看是不是就明白了许多,这个路径就包含在PATH变量的里面:
其实当我们执行ls指令的时候,bash会通过PATH里面包含的路劲一条一条的找这个指令,找到了就执行,找不到就bash就会返回【command not found】,也就是说要想让hello在前面不带任何路劲下,就能执行,我们只需要PATH包含hello的路径就可以。
那么问题来了,怎么将hello的路径导入到PATH里面呢?
我们先找到hello在哪个路径底下
[sjp@iZwz97d32td9ocseu9tkn4Z lesson13]$ pwd
/home/sjp/lesson13
pwd是查看路劲的命令。我们可以看到hello在/home/sjp/lesson13下,然后我们在把这条路径导入到PATH,如下:
[sjp@iZwz97d32td9ocseu9tkn4Z lesson13]$ export PATH=$PATH:/home/sjp/lesson13
export是设置环境变量的命令
$PATH是保留原来PATH的内容,然后在添加【:路径】,这样可以让PATH的内容添加新的路径。
我们再查看一下PATH的内容:
[sjp@iZwz97d32td9ocseu9tkn4Z lesson13]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/sjp/.local/bin:/home/sjp/bin:/home/sjp/lesson13
看最后面,/home/sjp/lesson13确实添加到我们的PATH里面去了。
再敲hello这条指令看一下能不能运行起来
果然,跟我们的预期是一样的。
如果我们把PATH这个环境变量给清空后在执行指令后:
[sjp@iZwz97d32td9ocseu9tkn4Z 9_19]$ export PATH=
[sjp@iZwz97d32td9ocseu9tkn4Z 9_19]$ echo $PATH
[sjp@iZwz97d32td9ocseu9tkn4Z 9_19]$ ls
-bash: ls: No such file or directory
PATH的等号的右边什么都没有,就直接把PATH给清空掉了。
这时候我们再去执行ls指令的时候,bash就找不到该指令,这也证明了PATH是指定了执行文件查找的路劲。
当你可能会说,你把PATH指令给清空了,那你岂不是得用一条一条的路劲再去配置PATH变量
其实不用那么麻烦,只要我们重新登录我们bash就可以了,这时候配置文件就就会重新给我们的PATH进行配置,因为命令export命令的环境变量是暂时的,关闭shell就会被清空掉,而我们配置文件中的环境变量是永久有效的。
总结:
PATH环境变量是指定执行文件到它包含的的路径下一条一条的寻找。
export可以设置新的环境变量,但是它只是暂时的。
SHELL:
查看具体的SHELL是什么,在linux系统下的具体的SHELL是bash
[sjp@iZwz97d32td9ocseu9tkn4Z ~]$ echo $SHELL
/bin/bash
env:是environment的简称,可以查看所有的环境变量
main函数参数
在了解main函数之前,我们得先思考一个问题:
ls等指令是怎样通过选项或者参数来执行不同行为?
例如 ls -l是列出文件和目录的所有信息(不包括隐藏文件的信息) ls -a是是列出所有目录和文件(包括隐藏文件)
对于我之前写过很多的c语言与c++程序,每一个程序都会写一个main函数,但是我之前写的main函数都是没有参数的,但后来我发现main函数也是可以有参数,在main函数中可以传这3个参数
main(int argc,char*argv[ ],char* envp[ ])
那这三个参数有什么用呢?
我们先看一下下面这个程序,这个程序是将我们的argv数组中的字符指针给打印出来。
1 #include<stdio.h>
2
3 int main(int argc,char* argv[])
4 {
5 for(int i=0;i<argc;i++)
6 {
7 printf("atgv[%d]:%s\n",i,argv[i]);
8 }
9
10 return 0;
11 }
argc是一个字符指针数组。
经过编译后形成我们的test可执行程序,当我们在命令行输入./test后;
我们发现数组的第一个字符指针指向的内容是我们在命令行输入的./test
我们再输入./test -a在看:
数组中的第一个字符指针指向./test 第二个字符指针指向-a。
再输入./test -a -b
数组中的第一个字符指针指向./test ,第二个字符指针指向-a,第三个字符指针指向我们的-b。
由此我们可以得出char*argv[ ]这个字符指针数组中的指针是是指向我们命令行中的输入一个一个的字符串,每一个字符串是以空格相隔开的,该数组最后一个元素是NULL。argc代表的是这个字符指针数组有多少个元素(字符指针)。
./test -a -b 是不是看起来会不会很眼熟?
这不是跟我们之前写的ls -a -l指令这些指令非常相似,当我们执行指令的时候,ls的字符地址放在
字符指针数组的第一个元素当中,-a放在第二个元素当中,-l放在第三个元素当中。
我们再写一个程序test:当我们假如参数-a 的时候 test就输出 i like you 加入参数 -b 的时候就输出 i hate you,没有加参数就输出hello sjp。
1 #include<stdio.h>
2 #include<string.h>
3 int main(int argc,char* argv[])
4 {
5 if(argc==2)
6 {
7 if(strcmp(argv[1],"-a")==0)
8 {
9 printf("i like you\n");
10 }
11 else if(strcmp(argv[1],"-b")==0)
12 {
13 printf("i hate you\n");
14 }
15 }
16 else
17 {
18 printf("hello sjp\n");
19 }
20 return 0;
21}
我们来测试一下:
现在我们明白指令是怎样通过选项去执行不同的行为了吧,是不是很有意思。
说到这里我们就明白了main函数前两个参数是什么呢?
那第三个参数char* envp[ ]到底是什么呢?
envp也是一个char*类型的指针数组,envp中的指针指向的我们系统中一个个的环境变量,最后一个元素也为NULL。
envp必须先有 前面int argc,char* argv[]这两个参数才有效,不能单独传envp这个参数,不然跟我们的预想不一样。
我们写一个test程序测试一下这个envp这个指针数组指向的内容是什么?
代码如下:
29int main(int argc,char* argv[],char* envp[])
30 {
31 int i=0;
32 while(envp[i])
33 {
34 printf("envp[%d]:%s\n",i,envp[i]);
35 i++;
36 }
37 return 0;
38 }
我们可以看到envp这个数组包含这么多的指针,当中每个指针指向的是系统中的环境变量。
所以说,每个程序中都有一个main函数,当我们的程序加载到内存中变成我们的进程,调用的该进程的父进程就会默认的传环境变量表(envp)给子进程的main函数,这时候,子进程就可以通过环境变量表(envp)去查找环境变量。还有一些进程可以(创建自己的环境变量)。所以,当我们登录bash,系统就会传环境变量表给我们的bash,当bash去执行指令的时候,bash会通过PATH路劲去查找相应的指令程序,然后运行该指令。
好啦,今天的分享就到这里,如果你觉得这篇文章不错的话,希望你可以给我点个赞。你的支持将是我最好的反馈。
点个赞呗~
完!