这段C语言程序展示了如何通过 main 函数接收和打印命令行参数
使用一个for循环遍历从0到argc-1的所有索引,argc 表示命令行传入的参数数量。
在循环体内部,printf 函数用于打印每个参数的索引和内容。argv[i] 是一个指向字符的指针,指向第i个参数的字符串
为什么要有命令行参数:
本质:命令行参数本质是交给我们程序的不同的选型,用来定制不同的程序功能。命令中会携带很多的选项。
1 #include<stdio.h>
2 #include<sys/types.h>
3 #include<unistd.h>
4 #include<string.h>
5
6 int main(int argc,char *argv[])
7 {
8 if(argc!=2)
9 {
10 printf("Usage:%s -[a,b,c,d]\n",argv[0]);
11 return 1;
12 }
13 if(strcmp(argv[1],"-a")==0)
14 {
15 printf("this is function1\n");
16 }
17 else if(strcmp(argv[1],"-b")==0)
18 {
19 printf("this is function2\n");
20 }
21 else if(strcmp(argv[1],"-c")==0)
22 {
23 printf("this is function3\n");
24 }
25 else if(strcmp(argv[1],"-d")==0)
26 {
27 printf("this is function4\n");
28 }
29
30 return 0;
31 }
再看一组代码
父进程的数据,默认能被子进程看到并访问
命令行中启动的程序都会变成进程,其实都是bash的子进程
环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数 如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。 环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性
常见环境变量
查看环境变量方法:
系统中很多的配置,在我们登录Linux系统的时候,已经被加载到bash进程中(内存)。默认我们查到的环境变量是内存级的
bash在执行命令的时候,需要先找到命令,因为未来要加载
当在 Bash 或任何其他 shell 中执行一个命令时,shell首先需要找到该命令对应的可执行文件。这个查找过程依赖于一系列环境设置和内置规则,主要涉及以下几个步骤:
cd
, echo
, history
等。如果是内置命令,Bash 会直接执行,不会在文件系统中寻找。
PATH
环境变量指定的目录列表来查找命令。PATH
变量包含了一系列目录,这些目录用冒号(:
)分隔,Bash 会按照这些目录的顺序去搜索可执行文件。例如,如果你的 PATH
是 /usr/local/bin:/usr/bin:/bin
,Bash 会首先检查/usr/local/bin
目录,如果没有找到,再依次检查 /usr/bin
和 /bin
。
PATH
中的某个目录找到了匹配的可执行文件,Bash 会加载并执行它。如果在所有列出的目录中都没有找到可执行文件,Bash 会返回一个错误,通常是“command not found”。
ls可以直接使用,我们的命令必须带上./
,是因为没有进行配置环境,ls实在/usr/bin目录下的
sudo cp testStatus /usr/bin/
我们可以将此命令拷贝到/usr/bin目录下
但是不建议这样做
我们可以将我们当前目录,添加到环境变量里面
这样直接赋值会使其他指令无法正常使用,我们这样改变了它所有路径
重新登录一次路径又恢复,所以我们说默认我们查到的环境变量是内存级的
正确方法:
PATH=$PATH:/home/dyx/test_static
那么最开始的环境变量呢?它不是在内存中,而是在系统对应的配置文件中
常见环境变量
[dyx@VM-8-13-centos test_static]$ echo $SHELL
/bin/bash
[dyx@VM-8-13-centos test_static]$ echo $HISTSIZE
3000
$SHELL
$SHELL
表示当前用户默认的登录 shell。/bin/bash
表明默认 shell 是 Bash。这是 Linux 中最常见的 shell,提供了强大的功能和灵活的脚本选项。$HISTSIZE
$HISTSIZE
定义了 Bash 历史记录中可以保持的命令数量的上限。3000
表明 Bash 历史记录可以保存最多 3000 条命令。这个设置帮助用户回溯和查看他们之前执行过的命令。和环境变量相关的命令
echo
: 显示某个环境变量值
export
: 设置一个新的环境变量如果不用export我们创建的叫做本地变量,env显示不出来但是echo可以查到
env
: 显示所有环境变量unset
: 清除环境变量
set
: 显示本地定义的shell变量和环境变量
environ 是一个环境变量的列表,实际上它是一个全局的、包含所有环境变量的字符串数组。每个字符串都是一个键值对,格式为 KEY=value。这个数组由操作系统在程序启动时创建,用于存储有关程序运行环境的信息
1 #include<stdio.h>
2 #include<sys/types.h>
3 #include<unistd.h>
4 #include<string.h>
5
6
7 int main()
8 {
9 extern char ** environ;
10 int i=0;
11 for(;environ[i];i++)
12 {
13 printf("env[%d]->%s\n",i,environ[i]);
14 }
15 return 0;
16 }
libc中定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以在使用时 要用extern声明
for(;environ[i];i++)
:循环遍历 environ 数组,直到遇到 NULL 结束符。每次循环索引 i 自增1,以便访问环境变量数组中的下一个元素
每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串
环境变量默认也是可以被子进程拿到的!
环境变量们默认在bash内部
[dyx@VM-8-13-centos test_static]$ echo $PATH
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/dyx/.local/bin:/home/dyx/bin:/home/dyx/test_static
所以我们再执行这个命令,bash就在env表里面寻找名为PATH的环境变量并打印
我们也可以使用main的第三个参数来获取环境变量,对应env表
#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;
}
子进程再创建子进程,bash的环境变量都能被子进程拿到,所以说环境变量具有系统级的全局属性
还可以通过下面方式获取环境变量
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("%s\n", getenv("PATH"));
return 0;
}
三种方法:
在 Bash 或其他 shell 中,有两类主要的命令:内建命令(built-in commands)和外部命令(external commands)。理解 export
和 echo
作为内建命令的含义,涉及到它们的作用、执行方式以及为什么它们被设计为内建命令。
内建命令是直接由 shell 自身提供并执行的命令,不依赖于外部程序文件。这些命令是 shell 程序的一部分,因此执行时不需要创建新的进程。由于这个原因,内建命令通常执行得更快,并且能直接访问 shell 的内部数据结构。
export
和 echo
是内建命令export
export
命令用于将 shell 变量标记为环境变量,使得子进程能够继承这些变量。如果 export
是外部命令,那么它在独立进程中运行,无法修改创建它的 shell 的环境,这会使它无法完成其设计的功能。export PATH=/usr/local/bin:$PATH
,这个命令直接修改了当前 shell 的环境变量。如果 export
是外部程序,它会修改自己的副本环境,并在程序结束时消失,对父 shell 没有任何影响。你可以使用 type
命令在 Bash 中检查一个命令是否是内建的。例如:
type export
type echo
这些命令会告诉你 export
和 echo
是内建命令。输出可能会类似于:
export is a shell builtin
echo is a shell builtin
本地变量只在本bash内部有效,无法被子进程继承下去,导成环境变量,此时才能够被获取
本地变量与环境变量的区别及其行为:
export
命令在 Bash 中设置,这使得它们不仅在当前 shell 中有效,还可以被任何子进程继承。如果你在一个 Bash 会话中创建一个环境变量,然后启动一个子进程(如另一个 Bash 实例或任何其他程序),这个子进程将能够访问那个环境变量。假设你在 Bash 中设置了一个本地变量和一个环境变量:
# 设置本地变量
localvar="I am a local variable"
# 设置环境变量
export envvar="I am an environment variable"
如果你从这个 Bash 会话中启动另一个 Bash 会话并尝试访问这两个变量:
echo $localvar # 这将不会输出任何东西,因为 localvar 是本地变量
echo $envvar # 这将输出 'I am an environment variable'
只有 envvar
被输出,因为它是一个环境变量,被导出到新的子进程中。