2024-10-13-A 文件与fd

【1】命令行参数实际上是 shell 自己去解析,在自己进程上下文中维护的一张全局的表。

【2】环境变量也是 shell 会从系统的配置文件中获取得到的

【3】我们的命令行参数和环境变量是如何传入到被替换的程序中的(也就是即将要执行的命令,不管是系统的还是自己的)?答:在调用层,操作系统通过系统调用接口传递给被调用进程的 main 函数,而被调用函数设置了 argv 和 argc 这样的参数,通过传递参数即可获取。

【4】内建命令:shell 自己调内部的函数,没有创建子进程执行。

【5】本地和环境变量的差别:环境变量本质就是 shell 自己维护一张全局变量的表,通过地址空间或 execvpe 把自己的环境信息传递给目标被替换进程。本地变量:在 shell 当中也是维护了一张表,可以把本地变量当字符串,不需要通过接口等传递,子进程看不到。

一、echo $?

$? 是一个特殊的变量,它保存了上一个命令的退出状态码。而 echo $? 的作用是将这个退出状态码打印出来,让用户可以查看。

为什么需要进程等待?一是回收僵尸形态,二是获取子进程的退出信息(可选)。

bool CEBuiltCommand(){
	//......

	else if(strcmp(gargv[0], "echo") == 0){
		//echo hello
		//echo $?
		//echo $PATH
		if(gargv[1][0] == '$'){
			if(gargv[1][1] == '?'){
				printf("%d\n", lastcode);
				lastcode = 0;
			}
		}
		else{
			printf("%s\n", gargv[1]);
			lastcode = 0;
		}
		return true;
	}
	else{
		lastcode = 3;
	}
	return false;
}

二、简化命令行当前路径显示

三、文件预备

1. 文件 = 内容 + 属性

访问文件之前,必须先打开它【为何要打开?】,没打开时文件位于磁盘上。

        访问一个文件的时候,是谁在访问?实际是进程在访问。

        打开它是让文件加载到内存中,OS必须要管理加载到进程中的文件。

        如何管理?先描述再组织!内核中,文件 = 文件的内核结构 + 文件的内容

        管理进程的:struct task_struct。研究打开的文件就是在研究进程和文件的关系。

被打开的文件 ➡️ 内存;没被打开的文件 ➡️ 磁盘。

2. C语言的 I/O 操作

2.1. fopen

"w" (echo >)
Truncate file to zero length or create text file for writing. The stream is positioned at the beginning of the file.

"a" (echo >>)
Open for appending (writing at end of file). The file is created if it does not exist. The stream is positioned at the end of the file.

2.2. 标准输入输出

「一个程序在默认启动时就会打开三个输入输出流」➡️「进程默认会打开三个输入输出流」

stdin 标准输入 键盘

stdout 标准输出 显示器

stderr 标准错误 显示器

2.3. 打印内容到显示器的几种方法
printf("hello world\n");
fprintf(stdout, "os\n");
fwrite("cplusplus\n", 1, 10, stdout);
fputs("linux\n", stdout);

四、文件类系统调用

我们使用的C文件接口, 底层一定要封装对应的文件类系统调用!

1. open()
NAME
       open, creat - open and possibly create a file or device

SYNOPSIS
       #include <sys/types.h>
       #include <sys/stat.h>
       #include <fcntl.h>

       int open(const char *pathname, int flags);
       int open(const char *pathname, int flags, mode_t mode);

int flags: 32个 bite 位,位图
宏:O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_APPEND 只有一个比特位值为1
可以任意组合,如 O_WRONLY | O_CREAT

O_TRUNC 清空;O_APPEND 追加

第3个参数 mode 是用于 设置权限。
为何设置为0666,最后生成的文件权限却是664?umask(0002)的缘故。

返回值: open()  and  creat() return the new file descriptor, or -1 if an error occurred (in which case, errno is set appropriately).

#include <unistd.h>
       ssize_t write(int fd, const void *buf, size_t count);
       int close(int fd);

fopen/fclose/fread/fwrite ➡️ C库函数

open/close/read/write ➡️ 系统调用

2. fd

「进程默认会打开三个输入输出流」

stdin 标准输入 键盘 0

stdout 标准输出 显示器 1

stderr 标准错误 显示器 2

【注】字符串以 \n 结尾是C语言的规定,和文件没关系,所以 write() 里 strlen() 不需要 +1。

fd 实际上是数组下标,在系统层面,fd 是访问文件的唯一方式

【Q】什么是 FILE 和 FILE*

C语言封装的结构体 struct FILE,FILE* 是其对应的结构体指针。

#include <stdio.h>
#include <unistd.h>

int main(){
	printf("stdin: %d\n", stdin->_fileno);
	FILE* fp = fopen("test.txt", "w");	
	printf("stdout: %d\n", stdout->_fileno);
    printf("fp: %d\n", fp->_fileno);
	printf("stderr: %d\n", stderr->_fileno);
	return 0;
}

输出结果:

stdin: 0
stdout: 1
fp: 3
stderr: 2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值