Linux进程与文件系统

进程与文件系统

cd ../ cd / 之类的命令

让bash自己执行的命令,称之为内建命令/内置命令

几乎所有的环境变量的命令,都是内建命令。

在Linux中,内建命令是指已经集成在shell程序中的命令,它们的执行不需要加载外部程序,可以直接在命令行上运行。这些内部命令的执行速度通常比外部命令更快,因为它们不需要去磁盘加载外部程序。

例如,在Bash shell中,常见的内部命令包括:

  • cd:切换当前工作目录
  • echo:输出文本或变量内容
  • pwd:打印当前工作目录路径
  • export:设置环境变量
  • alias:创建一个命令别名
  • history:查看执行过的命令历史记录
  • source:执行指定文件中的命令

可以使用内建命令的好处是它们快速,并且可以与系统的环境变量和其他属性进行交互,并且更容易维护。

一般来说,与环境变量有关的命令都是内建命令,一般用户自定义的环境变量,在bash中要用户自己来进行维护,不要用一个经常被覆盖的缓冲区来保存环境命令。让它能够持续保存下来

chdir()函数是C语言和C++中的一个标准库函数,用于改变当前工作目录。这个函数位于头文件<unistd.h>中。

函数原型如下:

int chdir(const char *path);

其中,path为要改变工作目录为的目录路径。如果改变成功返回0,如果失败返回-1。

下面是一个使用chdir()函数的简单例子:

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

int main() {
    int ret;
    char *cur_dir = NULL;
    
    /* 获取当前路径 */
    cur_dir = getcwd(cur_dir, 0);
    printf("当前工作目录:%s\n", cur_dir);
    free(cur_dir);
    
    /* 改变当前目录 */
    ret = chdir("/");
    if (ret == -1) {
        printf("chdir错误,错误号:%d\n", errno);
        return -1;
    }
    printf("当前工作目录:%s\n", getcwd(NULL, 0));
    
    return 0;
}

这个程序首先调用getcwd()函数获取当前工作目录,并输出。然后使用chdir()函数将当前工作目录改为根目录。再次调用getcwd()函数获取当前工作目录,并输出。

这个程序成功地将当前工作目录改为了根目录。

需要注意的是,chdir()函数并不能改变其他进程的工作目录。如果需要改变其他进程的工作目录,常常需要使用其他的通信方式,例如使用管道、Socket等。

文件描述符

文件读写

在Linux中,open和write和close是常用的文件操作函数,可以用于打开、写入和关闭文件。

1. open函数:open函数用于打开文件。函数原型如下:

#include <fcntl.h>
int open(const char *path, int flags, mode_t mode);

其中,path是要打开的文件路径+文件名,flags是打开文件的方式,mode是文件权限参数。常见的打开方式包括:

  • O_RDONLY:只读模式打开文件
  • O_WRONLY:只写模式打开文件
  • O_RDWR:可读可写模式打开文件
  • O_APPEND:追加模式打开文件
  • O_WRONLY 和 O_CREAT不会清空原本的文件内容
  • O_CREAT:如果文件不存在,则创建文件

需要在先将写入操作进行,然后再进行以下操作

  • 0_TRUNC清空已有文件内容

例如,使用O_WRONLY方式打开文件:

int fd = open("myfile.txt", O_WRONLY|O_CREAT|O_TRUNC, 0644);

注意:

在表示权限的时候要注意系统自带的掩码,它会屏蔽掉你不想要的权限;如需修改系统自带的掩码,可以使用umask()函数,系统采用就近原则。默认情况下,掩码初始值是022,这表示文件默认权限为666 & ~022,即文件默认权限是644,目录默认权限是777 & ~022,即目录默认权限是755

mode_t umask(mode_t mask);

umask的使用案例:

mode_t old_mask = umask(0); // 保存旧的掩码值
umask(0022); // 设置新的掩码值

2. write函数用于向已经打开的文件中写入数据。函数原型如下:

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

其中,fd是已经打开的文件描述符,buf是要写入的数据的缓冲区地址,count是要写入的数据大小。例如,写入数据到文件:

char* str = "Hello, world!";
ssize_t num = write(fd, str, strlen(str));

3. read函数:read函数用于从已经打开的文件中读取数据。函数原型如下:

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

其中,fd是已经打开的文件描述符,buf是要读取数据的缓冲区地址,count是要读取的数据大小。例如,从文件中读取数据:

char buffer[1024];
//这里我们无法做到按行进行读取,这里是进行整体读取
ssize_t numbytes = read(fd, buffer, sizeof(buffer) - 1);

使用系统接口来进行IO的时候,一定要注意\0问题

4. close函数:close函数用于关闭文件。函数原型如下:

#include <unistd.h>
int close(int fd);

其中,fd是已经打开的文件描述符。例如,关闭文件:

close(fd);

需要注意的是,在编程中使用这些函数时,需要确保文件打开和关闭的正确性,以及写入数据的大小和实际需要写入的数据是否一致。

5. lseek()是在Linux/Unix系统中用于改变文件读写指针位置(文件偏移量)的系统调用。在打开文件时,对每个进程都会创建一个文件表结构,其中包含有文件偏移量和文件状态标志等信息。lseek()可以操作该文件偏移量,一般用于随机访问文件。

lseek()函数的定义为:

#include <sys/types.h>
#include <unistd.h>

off_t lseek(int fd, off_t offset, int whence);

其中,参数fd是文件描述符,表示要操作的文件;偏移量offset表示要将文件指针移到的位置,可以是正数、负数或零;参数whence表示移动的基准位置,它可以取以下三种值:

  • SEEK_SET:从文件开头开始偏移,即偏移量为文件起始位置加上offset。
  • SEEK_CUR:从当前文件位置开始偏移,即偏移量为当前文件位置加上offset。
  • SEEK_END:从文件末尾开始偏移,即偏移量为文件长度加上offset。

如果lseek()调用成功,则会返回移动后的文件偏移量;如果发生错误,则返回-1,并设置全局变量errno存放错误码。

使用系统接口来进行IO的时候,一定要注意 \0 的问题

我们所谓的IO类read,write函数,本质是拷贝函数(用户空间和内核空间进行数据的来回拷贝)。

什么时候刷新到磁盘中指定的位置,由OS自主决定

我们使用OS的本质:都是通过进程的方式进行OS的访问的。

在进程的眼中,它只能看到文件,对它来说一切都是struct_file,所以才有Linux中的"一切皆文件"

进程中,文件描述符的分配规则:在文件描述符中,最小的,没有被使用的数组元素,分配给新文件。

文件描述符fd(open)返回值的本质就是数组下标,实际上就是放入到了文件描述符表中

系统默认打开的这三个文件占用了0,1,2的下标,我们打开文件只能占用3以及以后的坐标。

 

标准输出和标准错误都会向显示器打印,但是其实是不一样的

进程中,文件描述符发分配规则:在文件描述符表中,找到最小且没有被使用的数组元素,分配给新文件

重定向

重定向原理

在上层无法感知的情况下,在OS内部,更改进程对应的文件描述符表中,特定下标的指向!!!

在Linux中,重定向是一种将命令的输入或输出从标准位置(比如屏幕或键盘)更改为其他位置的方法。有两种常见类型的重定向:

  1. 标准输出重定向:将命令的输出从标准输出(通常是屏幕)发送到文件中或向其他进程传递。
  2. 标准输入重定向:将命令的输入从标准输入(通常是键盘)更改为来自文件或其他进程的输出。
  3. 在Linux中,标准错误(stderr)是指在命令执行过程中产生的错误信息。与标准输出不同,标准错误通常默认打印到屏幕上,但是我们可以使用标准错误重定向将其重定向到其他位置,以便更好地进行错误处理。

将命令输出到文件

使用 > 符号可以将命令的标准输出重定向到一个文件中。例如,我们可以用以下命令将ls命令的输出保存到一个文件中:

ls > file.txt

1. 将命令输出追加到文件末尾

使用 >> 符号可以将命令的标准输出追加到一个文件的末尾。例如,我们可以用以下命令将ls命令的输出追加到一个文件的末尾:

ls >> file.txt

2. 将文件作为命令的输入

使用 < 符号可以将文件作为命令的输入。例如,我们可以用以下命令将一个文件的内容作为输入传递给cat命令:

cat < file.txt

3. 将命令错误输出重定向到文件

使用 2> 符号可以将命令的标准错误输出重定向到一个文件中。例如,我们可以用以下命令将错误输出保存到一个文件中:

2>error.log

OS一般如何让用户给自己传递标志位的?

我们可以用一个bit位表示一个标志位,这样一个int类型至少可以传递32个标记位,都是够用了,其实就是位图。

缓冲区:

a、显示器采用的刷新策略:行缓冲

普通文件采用的刷新策略:全缓冲

b、为什么要有缓冲区?

节省调用者的时间 系统调用也是要花费时间的!

c、缓冲区在哪个位置?

在你进行fopen调用的时候,会得到返回的FILE结构体的指针,缓冲区就在这个指针所指向的结构体当中!!!

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值