qidao123.com技术社区-IT企服评测·应用市场

标题: 【Linux】环境变量(图文) [打印本页]

作者: 知者何南    时间: 4 天前
标题: 【Linux】环境变量(图文)
目录

一、main函数的参数解释:
1、argc和argc的解释
2、为什么要如许设置?
3、注意:
4、命令行计算器:
二、认识环境变量
三、见见环境变量
1、实行一个程序的前提
2、指令:echo $PATH

3、为什么系统自带的指令运行时不用加 " ./ "
4、环境变量:PWD
5、环境变量:USER
6、检察所有环境变量:env
7、创建新的环境变量的指令:export
8、总结:
9、main函数的第三个参数
10、bash维护的环境变量表
11、不使用命令行参数传参,如何获取环境变量?
12、获取环境变量的第三种方法:environ
四、本地变量
1、set+回车,可以检察系统中所有变量,包罗环境变量和本地变量
2、移除环境变量 / 本地变量指令:unset
五、问题:bash进程只有用户登录系统后才存在,而所有环境变量都在bash进程的上下文中,但当我们关闭连接后又重启时,这些环境变量会恢复到默认值,那这些环境变量是从哪里来的呐?

   前些天发现了一个巨牛的人工智能学习网站,普通易懂,风趣幽默,忍不住分享一下给各人
  点击跳转到网站
  一、main函数的参数解释:

1、argc和argc的解释

   平时我们写C语言时,main函数一般都是不带参数的,但其实main也有参数,先来介绍前两个参数:
  
  

  main函数的参数其实就是命令行的参数:
  (1)第一个参数argc是第二个参数argv数组的大小;
  (2)第二个参数argv是用来保存命令行输入的参数的;
  通过下述代码测试:
  1.   1 #include<stdio.h>
  2.   2 int main(int argc,char* argv[])
  3.   3 {
  4.   4     for(int i = 0;i < argc;i++)
  5.   5     {
  6.   6         printf("argv[%d]:%s\n",i,argv[i]);
  7.   7     }
  8.   8     
  9.   9     return 0;
  10. 10 }                    
复制代码
当我们运行该可实行文件时,背面如果带有参数,则背面这些参数就会被argv数组接收保存,这个操纵是bash做的:
  

    这些命令行提示符都是bash给我们输出的:
  

  bash还会将我们输入"./myprocess a b c ",以空格为分隔符,将每一段当做字符串存在argv数组中,同时以NULL结尾,所以我们还可以如许打印:
  1.   1 #include<stdio.h>
  2.   2 int main(int argc,char* argv[])
  3.   3 {
  4.   4     for(int i = 0;argv[i];i++)
  5.   5     {
  6.   6         printf("argv[%d]:%s\n",i,argv[i]);
  7.   7     }
  8.   8
  9.   9     return 0;
  10. 10 }
  11. ~        
复制代码
因为argv是以NULL结尾,所以当for循环遇到NULL就会自动结束。
  2、为什么要如许设置?

   场景之一就是可以使一个程序通过命令行传入差别参数从而实现差别功能:
  1.   1 #include<stdio.h>
  2.   2 #include<string.h>
  3.   3 int main(int argc,char* argv[])
  4.   4 {
  5.   5     if(argc > 2)
  6.   6     {
  7.   7         printf("输入了多个参数,输入无效\n");
  8.   8         return 0;
  9.   9     
  10. 10     }
  11. 11     if(strcmp("-1",argv[1])==0)
  12. 12     {   
  13. 13         printf("执行-1功能\n");
  14. 14     }
  15. 15     else if(strcmp("-2",argv[1]) == 0)
  16. 16     {   
  17. 17         printf("执行-2功能\n");
  18. 18     }
  19. 24     return 0;
  20. 25 }
复制代码

  3、注意:

   我们平时使用的指令(如ls,pwd),都带有选项(如ls -a),而大部分指令都是C/C++写的,就是通过main的参数到达的差别选项实现差别功能,这些选项也是命令行参数
  

  命令行参数就是linux指令选项的基础!
  4、命令行计算器:

   通过main参数的功能,可以实现一个简易版命令行计算器:
  

  二、认识环境变量

   (1)环境变量不但有一个,而是有很多,而且环境变量相互之前没有关系。
  (2)环境变量一般是系统内置的具有特别用途的变量。
  (3)定义变量的本质其实就是开辟空间,在运行期间我们的程序也能开辟空间。
  (4)操纵系统(bash)使用C语言写的程序,它能在运行中开辟空间。系统的环境变量本质就是系统自己开辟的空间,只是用环境变量给这份空间定名和内容。
  三、见见环境变量

   1、实行一个程序的前提

    实行一个程序的前提是要在系统里面找到这个程序,所以平时我们运行程序时需要在可实行程序名前面加" ./ ",否则系统会提示找不到

  但是我们使用shell自带的指令就不需要带./,如ls、pwd等等。
  2、指令:echo $PATH



    该指令是用来检察系统默认去搜索的各个路径:
  

  注意" : "是路径之间的分割符。
  3、为什么系统自带的指令运行时不用加 " ./ "

   我们自己写的程序想要像系统指令那样不用加" ./ ",有两种方法:
  (1)可以将自己的可实行文件拷贝到指令echo $PATH所展示的恣意一个路径下。但是这种方法会污染系统的路径,所以建议使用第二种方法。
  (2)将自己的可实行程序的路径放到PATH中,指令格式如下图:
  

  注意要将红框中的" PATH "带上,因为这个指令会直接覆盖原PATH内容,而$PATH代表的就是原有PATH内容,所以需要加上。
  此时运行我们自己的程序也不需要加" ./ "了:
  

  若不小心将原有PATH内容覆盖了:
  

  此时系统自带的指令就都不可以使用了,此时只需要要重启shell,即可恢复原有PATH内容。
  4、环境变量:PWD

   系统pwd指令怎么知道当前我在哪个路径?
  

  就是因为添加了PWD环境变量,这个环境变量会记录我的当前路径。
  可以通过下面指令检察:
  

  5、环境变量:USER

   该环境变量记录的是当前登录的用户:
  

  6、检察所有环境变量:env

   

  7、创建新的环境变量的指令:export

   

  

  8、总结:

   环境变量就是当你进入系统时,存储和通报系统配置信息、控制程序运行环境等重要数据的,方便你之后去访问。
  9、main函数的第三个参数

   讲到环境变量就可以谈谈main函数的第三个参数:char* env[ ]
  

  env数组和argv数组都是用来存储数据的,只是env存储的是环境变量
  10、bash维护的环境变量表

   在系统看来其实这些环境变量就是一行一行字符串:
  

  bash内部有个env表(与main函数的第三个参数类似),每个元素就是用来存储每一行环境变量的首地址,通过这个表来维护环境变量。而且环境变量是具有全局属性,可以被子进程继承下去。
  所以我们知道bash会维护两张表,一张是命令行参数的argv表,一张是env表,如许我们才能给main函数传参。
  11、不使用命令行参数传参,如何获取环境变量?

   通过一个系统调用:
  1. char *getenv(const char *name);
复制代码
参数传的是环境变量名,函数返回环境变量的内容。
  示例代码:
  
  1.   1 #include<stdio.h>
  2.   2 #include<string.h>
  3.   3 #include<stdlib.h>
  4.   4 #include<unistd.h>
  5.   5 int main(int argc,char* argv[])
  6.   6 {
  7.   7
  8.   8     const char* username = getenv("USER");
  9.   9     if(username)printf("%s\n",username);
  10. 10     else printf("None\n");
  11. 11
  12. 12     return 0;
  13. 13 }  
复制代码

    通过这个系统调用,我们就可以通过获取环境变量进行筛选,比如该程序只能被限定用户使用,如许限定后,纵然是root用户也不能实行该程序:
  1. 1 #include<stdio.h>
  2.   2 #include<string.h>
  3.   3 #include<stdlib.h>
  4.   4 #include<unistd.h>
  5.   5 int main(int argc,char* argv[])
  6.   6 {
  7.   7
  8.   8     const char* username = getenv("USER");
  9.   9     if(username != "HF")printf("你的用户名为:%s,你没有权限访问这个程序\n",username);
  10. 10     else printf("你可以执行\n");
  11. 11
  12. 12     return 0;
  13. 13 }
复制代码

  12、获取环境变量的第三种方法:environ

   environ范例是" char** ",这是内部定义的一个全局变量,我们知道char二级指针可以看成一个char指针数组,所以environ其实跟env表差不多,每一行都是环境变量的首地址:
  

  使用environ获取环境变量的示例代码:
  1.   1 #include<stdio.h>
  2.   2 #include<string.h>
  3.   3 #include<stdlib.h>
  4.   4 #include<unistd.h>
  5.   5 int main(int argc,char* argv[])
  6.   6 {
  7.   7
  8.   8     //通过environ获取环境变量
  9.   9     extern char** environ;
  10. 10     for(int i = 0;environ[i];i++)
  11. 11     {
  12. 12         printf("%s\n",environ[i]);
  13. 13     }
  14. 14
  15. 15
  16. 16     return 0;
  17. }
复制代码
因为是env表以NULL结尾,所以for循环的循环条件可以像上述如许写。
  

  四、本地变量

   除了环境变量,其实照旧本地变量,定义本地变量的方法直接像下述那样在命令行写,也是通过echo $xxx检察:
  

  1、set+回车,可以检察系统中所有变量,包罗环境变量和本地变量

2、移除环境变量 / 本地变量指令:unset

   

  五、问题:bash进程只有用户登录系统后才存在,而所有环境变量都在bash进程的上下文中,但当我们关闭连接后又重启时,这些环境变量会恢复到默认值,那这些环境变量是从哪里来的呐?

   答案:这些环境变量是从磁盘的某些脚本文件或者配置文件来的。
   

  六、关于环境变量的相关代码

   该小点内容来自豆包AI:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. // 使用 getenv 函数获取环境变量的值
  5. void get_env_value(const char *name) {
  6.     char *value = getenv(name);
  7.     if (value != NULL) {
  8.         printf("The value of %s environment variable is: %s\n", name, value);
  9.     } else {
  10.         printf("The %s environment variable is not set.\n", name);
  11.     }
  12. }
  13. // 使用 environ 全局变量访问所有环境变量
  14. void list_all_environment_variables() {
  15.     char **env = environ;
  16.     while (*env != NULL) {
  17.         printf("%s\n", *env);
  18.         env++;
  19.     }
  20. }
  21. // 使用 putenv 函数设置环境变量
  22. void set_env_with_putenv(const char *name, const char *value) {
  23.     char new_env[100];
  24.     snprintf(new_env, sizeof(new_env), "%s=%s", name, value);
  25.     if (putenv((char *)new_env) == 0) {
  26.         get_env_value(name);
  27.     } else {
  28.         printf("Failed to set the environment variable using putenv.\n");
  29.     }
  30. }
  31. // 使用 setenv 函数设置环境变量
  32. void set_env_with_setenv(const char *name, const char *value) {
  33.     if (setenv(name, value, 1) == 0) {
  34.         get_env_value(name);
  35.     } else {
  36.         printf("Failed to set the environment variable using setenv.\n");
  37.     }
  38. }
  39. // 使用 unsetenv 函数删除环境变量
  40. void delete_env(const char *name) {
  41.     get_env_value(name);
  42.     if (unsetenv(name) == 0) {
  43.         get_env_value(name);
  44.     } else {
  45.         printf("Failed to delete the environment variable.\n");
  46.     }
  47. }
  48. // 子进程中环境变量的继承
  49. void child_process_inherit_env(const char *name, const char *value) {
  50.     if (setenv(name, value, 1) == 0) {
  51.         pid_t pid = fork();
  52.         if (pid == 0) {
  53.             // 子进程
  54.             char *value_in_child = getenv(name);
  55.             if (value_in_child != NULL) {
  56.                 printf("The value of %s in child process is: %s\n", name, value_in_child);
  57.             }
  58.             _exit(0);
  59.         } else if (pid > 0) {
  60.             // 父进程
  61.             wait(NULL);
  62.         } else {
  63.             perror("fork");
  64.         }
  65.     }
  66. }
  67. int main() {
  68.     // 获取 PATH 环境变量的值
  69.     get_env_value("PATH");
  70.     // 列出所有环境变量
  71.     printf("All environment variables:\n");
  72.     list_all_environment_variables();
  73.     // 使用 putenv 设置环境变量
  74.     set_env_with_putenv("MY_VARIABLE", "hello");
  75.     // 使用 setenv 设置环境变量
  76.     set_env_with_setenv("ANOTHER_VARIABLE", "world");
  77.     // 删除环境变量
  78.     delete_env("MY_VARIABLE");
  79.     // 子进程中环境变量的继承
  80.     child_process_inherit_env("INHERITED_VARIABLE", "from_parent");
  81.     return 0;
  82. }
复制代码

  




免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 qidao123.com技术社区-IT企服评测·应用市场 (https://dis.qidao123.com/) Powered by Discuz! X3.4