文章目录
1.>
echo “hello” > file.txt //没有文件 创建新文件 覆盖式写入
2. cat
cat file.txt
打开file.txt
文件,读取其内容,并将这些内容输出到标准输出。
类似于C语言中fopen函数 打开文件后可以使用fread等函数操作
cat < file.txt
将文件file.txt
的内容作为cat
命令的标准输入(stdin)。
将原来指向键盘输入缓冲区的指针重定向到文件(没有执行打开文件的操作)
3.系统命令
这条命令 uname -a
的输出提供了您当前Linux系统的详细信息。具体来说,这条输出信息说明了以下几点:
- 系统名称:
Linux
,表明这是一个Linux系统。 - 主机名:
hcss-ecs-79af
,服务器名。 - 内核版本:
5.4.0-170-generic
,内核版本。Linux内核是操作系统的核心,管理着硬件和软件资源。这里的版本号5.4.0
是主版本号,-170
可能是针对Ubuntu系统进行的特定修订或补丁版本,而generic
表明这是一个适用于大多数硬件配置的通用内核版本。 - 内核编译日期和时间:
#188-Ubuntu SMP Wed Jan 10 09:51:01 UTC 2024
,这部分信息提供了内核编译的日期(2024年1月10日,星期三,UTC时间)和编译编号(#188),以及这是由Ubuntu团队(SMP表示对称多处理,即支持多CPU)编译的版本。 - 硬件架构:
x86_64
,这表示您的系统是基于x86-64架构的,也就是常说的64位处理器架构。x86_64
是x86
架构的64位扩展,也称为AMD64或Intel 64。 - GNU/Linux:最后,这表示您的系统遵循GNU项目(GNU’s Not Unix)的开源原则和理念,并运行在Linux内核之上。GNU项目提供了许多核心工具和库,这些工具和库与Linux内核一起构成了现代Linux系统的基础。
总之,这条命令的输出让您了解了您当前Linux系统的基本情况和配置。
bash和shell和kernel
- Kernel:操作系统的核心,负责管理硬件资源和提供核心服务。
- Shell:命令行解释器,提供了一个用户与操作系统交互的界面。
- Bash:一种广泛使用的shell,提供了丰富的命令集和编程功能,是Linux系统中默认的shell之一。
权限只被认证一次
“权限只被认证一次”可以理解为每次用户尝试对文件或目录进行访问时,系统都会独立地验证用户的权限。
粘滞位引入
这个场景涉及到了Linux系统中的文件权限和sudo命令的使用,以及它们如何影响文件和目录的操作。我会尽量用通俗易懂的方式来解释。
前提知识
-
文件权限:在Linux中,每个文件或目录都有三组权限,分别对应文件的所有者(owner)、所属组(group)和其他人(others)。每组权限包括读(r)、写(w)和执行(x)。
-
sudo命令:sudo命令允许普通用户以超级用户(通常是root)的身份执行命令。这意味着,即使一个操作通常需要管理员权限,普通用户也可以通过sudo来执行它。
场景解释
在这个场景中,有一个目录和一个文件,文件的初始权限设置为rw- r-- r--
(即所有者可以读写,所属组可以读,其他人可以读)。现在,有一个普通用户和一个root用户(或通过sudo获得root权限的普通用户)在这个目录下。
为什么普通用户(无w权限)可以删除文件?
- 当普通用户尝试删除文件时,他们实际上是在尝试修改目录(即从中移除一个条目)。这个操作要求用户对目录有写权限(w),而不是对文件本身。
- 在这个场景中,尽管普通用户对文件没有写权限,但他们可能(如果目录权限允许)对目录有写权限。因此,他们可以删除目录中的文件。
为什么普通用户通过sudo设置文件权限为000后仍能删除文件?
- 使用sudo命令后,普通用户以root身份执行命令。root用户拥有对系统的完全访问权限,包括对所有文件和目录的读写执行权限。
- 因此,即使文件权限被设置为000(即所有人都没有读写执行权限),root用户(或通过sudo的普通用户)仍然可以执行任何操作,包括删除文件。
结论
这个场景的关键点在于理解文件权限和目录权限的区别,以及sudo命令如何允许用户以更高的权限执行操作。普通用户能够删除文件,通常是因为他们对包含该文件的目录有写权限,而不是因为他们对文件本身有写权限。而使用sudo命令后,用户可以执行任何操作,因为sudo赋予了他们root权限。
粘滞位是干什么的?粘滞位只能给目录设置
实现这么一个场景
- 多个用户共享一个目录 可以在这个目录下rwx
- 但是自己只能删自己 不能删除别人的文件
1. 保护文件免受非授权删除或修改
- 当一个目录被设置了粘滞位后,只有【文件的所有者、目录的所有者或超级用户(root)】才能删除或重命名该目录下的文件。这有效地防止了其他用户(即使他们具有对该目录的写权限)误删除或篡改不属于他们的文件。
2. 应用于公共目录
- 粘滞位常被应用于如
/tmp
这样的公共目录。/tmp
目录通常用于存储临时文件,这些文件可能由多个用户创建。通过设置粘滞位,可以确保每个用户只能删除或修改自己创建的文件,从而维护了公共目录的秩序和安全性。
3. 提高系统安全性
- 通过限制非授权用户对文件的操作,粘滞位有助于减少系统因误操作或恶意攻击而遭受的损害。这对于保护敏感数据和系统稳定性至关重要。
4. 适用于网络共享环境
- 在网络共享环境中,粘滞位同样可以发挥作用。在共享文件服务器上的共享目录中设置粘滞位,可以防止非目录所有者的用户对文件进行修改,从而保护共享资源的安全性和完整性。
5. 使用chmod命令设置
- 在Linux中,可以使用
chmod
命令来设置目录的粘滞位。具体命令为chmod +t directory
,其中directory
表示要设置粘滞位的目录名称或路径。执行该命令后,该目录的权限模式将包含粘滞位标志(通常显示为t
或T
)。
6. 注意事项
- 粘滞位只对目录起作用,对普通文件没有影响。
- 粘滞位只能保护目录中的文件和子目录不被删除或重命名,但不能阻止其他用户往该目录中添加新的文件或子目录。
- 如果一个目录被设置了粘滞位,但是该目录的所有者或超级用户没有相应的权限,那么该目录下的文件和子目录仍然可能被删除或重命名。
vim加注释
批量添加注释: 命令行模式下 进入块可视模式 选中想添加注释语句的首字符 输入大写i 输入// 按esc返回
stat系统调用
struct stat {
dev_t st_dev; /* 设备ID */
ino_t st_ino; /* inode号 */
mode_t st_mode; /* 文件类型和权限 */
nlink_t st_nlink; /* 硬链接数量 */
uid_t st_uid; /* 用户ID */
gid_t st_gid; /* 组ID */
dev_t st_rdev; /* 设备ID(如果是设备文件) */
off_t st_size; /* 文件大小(以字节为单位) */
blksize_t st_blksize; /* 块大小 */
blkcnt_t st_blocks; /* 分配的块数 */
time_t st_atime; /* 最后访问时间 */
time_t stmtime; /* 最后修改时间 */
time_t st_ctime; /* 最后状态改变时间 */
};
#include <sys/stat.h>
int stat(const char *pathname, struct stat *statbuf);
在使用 stat
系统调用时,可以结合一些宏来解释返回的文件状态信息。以下是一些与 stat
相关的宏:
-
文件类型宏(File Type Macros):
S_ISREG(mode)
: 判断文件是否为常规文件。S_ISDIR(mode)
: 判断文件是否为目录。S_ISCHR(mode)
: 判断文件是否为字符设备文件。S_ISBLK(mode)
: 判断文件是否为块设备文件。S_ISFIFO(mode)
: 判断文件是否为管道(FIFO)文件。S_ISLNK(mode)
: 判断文件是否为符号链接。S_ISSOCK(mode)
: 判断文件是否为套接字。
-
权限宏(Permission Macros):
S_IRUSR
,S_IWUSR
,S_IXUSR
: 用户权限读、写、执行。S_IRGRP
,S_IWGRP
,S_IXGRP
: 用户组权限读、写、执行。S_IROTH
,S_IWOTH
,S_IXOTH
: 其他用户权限读、写、执行。
-
文件模式位掩码(File Mode Bit Masks):
S_IFMT
: 文件类型位掩码(用于从st_mode
中提取文件类型)。S_IFREG
,S_IFDIR
,S_IFCHR
,S_IFBLK
,S_IFIFO
,S_IFLNK
,S_IFSOCK
: 不同文件类型的位掩码。
查看代码行数
在 Ubuntu 中可以使用以下命令查看代码行数:
-
单文件行数
wc -l 文件名
-
统计目录下所有代码文件的行数
find 路径 -name "*.cpp" -o -name "*.h" | xargs wc -l
-
仅输出总行数
find 路径 -name "*.cpp" -o -name "*.h" | xargs cat | wc -l
-
结合
cloc
工具
安装cloc
后可更详细统计:sudo apt install cloc cloc 路径
它会显示文件类型、代码行数、注释行数等信息。
信号产生方式
信号的发送是由操作系统负责的,而信号的接收是由进程负责的
信号是一种异步的通信方式,进程无法预测信号何时到达。进程可能正在处理优先级更高,更重要的任务,所以信号的处理工作可能不是立即执行的。进程会临时记录下对应的信号,方便后续进行处理。
当进程崩溃时,操作系统会将进程的内存映像写入到核心转储文件{文件名为core.pid}中。核心转储文件可以用于分析程序崩溃的原因。
-
终端按键产生
-
Ctrl+C:发送SIGINT(2)信号,通常用于中断(Interrupt)进程。
-
Ctrl+\:发送SIGQUIT(3)信号,通常用于退出(Quit)进程并生成core文件
-
Ctrl+Z:发送SIGTSTP(20)信号,通常用于挂起暂停(Suspend)进程,可以被忽略或捕捉。
-
Ctrl+S:发送SIGSTOP(19)信号,用于挂起暂停(Stop)进程的执行,无法被忽略、处理或阻塞。
-
Ctrl+Q:发送SIGCONT(18)信号,用于继续(Continue)被19, 20号信号停止的进程。
Ctrl+D键组合会发送一个特殊的字符(ASCII码为0x04)给正在运行的程序。即EOF(End of File)字符,它表示输入流的结束。EOF是特殊字符,不是信号!
-
-
系统调用发送
- int kill(pid_t pid, int sig);
- int raise(int sig);
- void abort(void);
-
软件条件产生
- 读端fd被关闭,write操作会产生SIGPIPE信号
alarm
函数用于设置一个定时器,当定时器到期时,会向当前进程发送SIGALRM
信号- 当一个子进程终止或被暂停时,内核会向其父进程发送
SIGCHLD
信号
-
硬件异常产生
- 进程执行除以0的指令,CPU的状态寄存器(硬件)会产生异常,内核将这个异常解释为SIGFPE信号发送给进程。
- 进程访问了非法内存地址,在将虚拟地址转化为物理地址的过程中,内存管理单元MMU(硬件)会产生异常,内核将这个异常解释为SIGSEGV信号发送给进程。
信号处理
从内核态返回用户态前,进行信号的检测和处理
- 信号处理在内核态 因为:管理信号的数据结构都在进程PCB内,而进程PCB属于内核数据。
- 信号处理在完成内核态代码后返回用户态前:内核态代码重要度/优先级更高
信号捕捉与处理
如果信号的处理方法是默认或忽略,则直接在内核态完成相应的处理动作(终止进程、暂停进程、清除pending标志),不需要切换到用户态。
如果信号的处理方法是自定义捕捉,则切换到用户态执行信号处理程序,完成后再次陷入内核,清除对应信号的pending标志,最后返回用户态继续执行用户程序。
为什么要切换到用户态执行信号处理函数呢?因为信号处理函数是用户提供的,如果以内核态执行用户代码的话,由于内核态具有完全的访问权限,用户代码可能会修改系统的重要数据,从而导致系统资源和硬件设备遭到破坏。
SIGCHILD信号
-
忽略信号(默认):SIGCHLD信号的默认处理方法就是忽略(ign)。但是子进程会变为僵尸进程一直等待父进程获取其退出状态。
-
忽略信号(手动):我们还可以通过signal或sigaction函数手动的选择忽略SIGCHLD信号(SIG_IGN),这样的话系统会直接回收子进程资源,释放僵尸进程。不再需要父进程等待子进程了。这通常用于父进程不关心子进程退出状态的情况。
-
捕捉信号:父进程可以通过注册一个SIGCHLD信号处理函数来捕捉SIGCHLD信号。当子进程终止或停止时,操作系统会调用该信号处理函数。
-
阻塞信号:父进程可以选择在某些时候阻塞SIGCHLD信号,以延迟对子进程状态改变的处理。这可以通过调用sigprocmask函数来设置信号屏蔽字来实现。
不可重入函数
函数体内使用了静态的数据结构。
函数体内调用了malloc()或free()函数。
函数体内调用了标准I/O函数,因为标准I/O库很多实现都以不可重入的方式使用全局数据结构。
函数体内访问了全局变量。
函数进行了浮点运算,在许多的处理器/编译器中,浮点一般都是不可重入的。
printf()内部包含了semTake操作,在中断服务程序中不能有阻塞操作,因此也被视为不可重入函数。