🔥个人主页:Quitecoder
🔥专栏:linux笔记仓
目录
- 01.命令行参数
- 02.环境变量
- 环境变量与程序结合(理解)
- 内建命令的定义
- 为什么 `export` 和 `echo` 是内建命令
- 本地变量
- 环境变量
- 示例
01.命令行参数
这段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 }2930 return 0;31 }
再看一组代码
父进程的数据,默认能被子进程看到并访问
命令行中启动的程序都会变成进程,其实都是bash的子进程
02.环境变量
环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性
常见环境变量
- PATH : 指定命令的搜索路径
- HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
- SHELL : 当前Shell,它的值通常是/bin/bash
查看环境变量方法:
- echo $NAME //NAME:你的环境变量名称
系统中很多的配置,在我们登录Linux系统的时候,已经被加载到bash进程中(内存)。默认我们查到的环境变量是内存级的
bash在执行命令的时候,需要先找到命令,因为未来要加载
当在 Bash 或任何其他 shell 中执行一个命令时,shell首先需要找到该命令对应的可执行文件。这个查找过程依赖于一系列环境设置和内置规则,主要涉及以下几个步骤:
内置命令 首先,Bash 会检查要执行的命令是否是一个内置命令。内置命令是 Bash 自带的,不需要额外的可执行文件,例如
cd
,echo
,history
等。如果是内置命令,Bash 会直接执行,不会在文件系统中寻找。哈希表(命令缓存) 如果不是内置命令,Bash 接下来会查看其哈希表(如果已经启用的话)。哈希表存储了先前找到的命令路径,以减少寻找同一命令的时间。通过这个缓存机制,如果命令已被之前执行过一次,Bash可以快速定位到命令的位置。
环境变量PATH 如果命令不在哈希表中,Bash 会利用
PATH
环境变量指定的目录列表来查找命令。PATH
变量包含了一系列目录,这些目录用冒号(:
)分隔,Bash 会按照这些目录的顺序去搜索可执行文件。例如,如果你的PATH
是/usr/local/bin:/usr/bin:/bin
,Bash 会首先检查/usr/local/bin
目录,如果没有找到,再依次检查/usr/bin
和/bin
。找到命令执行 一旦在
PATH
中的某个目录找到了匹配的可执行文件,Bash 会加载并执行它。如果在所有列出的目录中都没有找到可执行文件,Bash 会返回一个错误,通常是“command not found”。权限检查 找到可执行文件后,Bash 还会检查当前用户是否有权限执行该文件。如果没有执行权限,将返回权限错误。
ls可以直接使用,我们的命令必须带上./
,是因为没有进行配置环境,ls实在/usr/bin目录下的
sudo cp testStatus /usr/bin/
我们可以将此命令拷贝到/usr/bin目录下
但是不建议这样做
我们可以将我们当前目录,添加到环境变量里面
这样直接赋值会使其他指令无法正常使用,我们这样改变了它所有路径
重新登录一次路径又恢复,所以我们说默认我们查到的环境变量是内存级的
正确方法:
PATH=$PATH:/home/dyx/test_static
那么最开始的环境变量呢?它不是在内存中,而是在系统对应的配置文件中
常见环境变量
- PATH : 指定命令的搜索路径
- HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
- SHELL : 当前Shell,它的值通常是/bin/bash
[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 的环境,这会使它无法完成其设计的功能。- 举例来说,当你在 Bash 中执行
export PATH=/usr/local/bin:$PATH
,这个命令直接修改了当前 shell 的环境变量。如果export
是外部程序,它会修改自己的副本环境,并在程序结束时消失,对父 shell 没有任何影响。
-
echo
echo
命令用于输出其参数到标准输出。虽然可以实现为外部命令,但作为内建命令,echo
可以更快地执行,并可以直接处理 shell 特有的功能,如展开 shell 变量、转义字符等。- 例如,执行
echo $HOME
时,echo
内建命令可以直接访问并展开$HOME
环境变量,显示当前用户的主目录路径。
你可以使用 type
命令在 Bash 中检查一个命令是否是内建的。例如:
type export
type echo
这些命令会告诉你 export
和 echo
是内建命令。输出可能会类似于:
export is a shell builtin
echo is a shell builtin
本地变量只在本bash内部有效,无法被子进程继承下去,导成环境变量,此时才能够被获取
本地变量与环境变量的区别及其行为:
本地变量
- 定义和作用域:本地变量在 Bash 中定义时只在当前 shell 会话中有效。它们不能被任何启动的子 shell 或调用的子进程继承。这意味着当你在一个 Bash 会话中设置一个本地变量,它对任何从这个 shell 派生的新进程都是不可见的,除非显式地传递给它们。
- 用途:本地变量通常用于临时存储数据,比如循环计数器或局部计算值,这些值不需要超出其定义的脚本或命令序列。
环境变量
- 定义和作用域:环境变量通过使用
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
被输出,因为它是一个环境变量,被导出到新的子进程中。