• [技术干货] Linux 中的定时利器:Crontab 用法详解
    在 Linux 系统中,有一个非常强大的工具叫做 crontab,它可以让我们轻松地实现定时任务的设置和管理。无论是定期备份数据、清理临时文件,还是执行其他自动化任务,crontab 都能发挥巨大的作用。一、什么是 CrontabCrontab 是一个用于在 Linux 系统中设置定时任务的工具。它允许用户指定在特定的时间间隔或特定的时间点执行特定的命令或脚本。Crontab 基于 cron 守护进程运行,该守护进程会在系统启动时自动启动,并定期检查 crontab 文件以确定是否有需要执行的任务。二、Crontab 的基本语法Crontab 的语法相对简单,但需要一些时间来熟悉。一个典型的 crontab 条目由五个时间字段和一个要执行的命令组成。这五个时间字段分别表示分钟、小时、日、月和星期几。例如,以下是一个简单的 crontab 条目:收起plaintext复制* * * * * /path/to/command这个条目表示每分钟执行一次/path/to/command命令。每个时间字段可以使用以下几种格式:具体的值:例如,“5” 表示在第 5 分钟执行任务。范围:例如,“1-5” 表示在第 1 分钟到第 5 分钟之间执行任务。步长:例如,“*/5” 表示每隔 5 分钟执行任务。列表:例如,“1,3,5” 表示在第 1 分钟、第 3 分钟和第 5 分钟执行任务。三、设置 Crontab 任务编辑 Crontab 文件 可以使用crontab -e命令来编辑当前用户的 crontab 文件。这个命令会打开一个文本编辑器,你可以在其中添加、修改或删除 crontab 条目。添加任务 要添加一个新的任务,只需在 crontab 文件中添加一行新的条目。例如,如果你想每天凌晨 2 点执行一个备份脚本,可以添加以下条目:收起plaintext复制0 2 * * * /path/to/backup_script.sh保存和退出 编辑完成后,保存文件并退出编辑器。Cron 守护进程会自动读取新的 crontab 文件,并在指定的时间执行任务。四、查看和管理 Crontab 任务查看当前用户的 Crontab 任务 可以使用crontab -l命令来查看当前用户的 crontab 任务列表。删除任务 要删除一个任务,可以再次使用crontab -e命令,然后删除相应的条目。保存文件后,Cron 守护进程会自动更新任务列表。查看 Crontab 日志 Cron 守护进程会将任务的执行情况记录在系统日志中。你可以使用tail -f /var/log/syslog命令来实时查看系统日志,以了解 crontab 任务的执行情况。五、注意事项命令路径 在 crontab 条目中指定的命令或脚本的路径必须是绝对路径。如果使用相对路径,Cron 守护进程可能无法找到该命令或脚本。环境变量 Cron 守护进程在执行任务时使用的环境变量与用户登录时的环境变量不同。因此,在 crontab 条目中执行的命令或脚本可能需要显式地设置一些环境变量,以确保它们能够正常运行。权限问题 确保你有足够的权限来执行 crontab 条目中指定的命令或脚本。如果需要以其他用户的身份执行任务,可以使用sudo命令或设置适当的权限。六、实际应用场景系统维护任务 定期清理临时文件、备份重要数据、检查系统磁盘空间等。自动化任务 例如,每天定时发送邮件报告、自动更新软件等。监控任务 定期检查系统状态、网络连接等,并在出现问题时发送警报。
  • 深入理解 Linux 中的 SELinux:用法与优势
    在 Linux 系统的安全领域中,SELinux(Security-Enhanced Linux)是一个强大的工具,它为系统提供了更高级别的安全保障。今天,我们就来深入探讨一下 SELinux 的用法。一、SELinux 简介SELinux 是一种基于强制访问控制(MAC)的安全机制,它通过对系统中的主体(如用户、进程)和客体(如文件、目录、端口等)进行严格的访问控制,来增强系统的安全性。与传统的自主访问控制(DAC)不同,SELinux 不依赖于用户的主观判断,而是根据预设的安全策略来决定主体对客体的访问权限。二、SELinux 的工作模式SELinux 有三种工作模式:Enforcing(强制模式):在这种模式下,SELinux 会严格按照安全策略进行访问控制。如果主体对客体的访问违反了安全策略,访问将被拒绝。Permissive(宽容模式):在这种模式下,SELinux 会记录违反安全策略的访问行为,但不会阻止这些访问。这对于调试和了解系统的安全状况非常有用。Disabled(禁用模式):在这种模式下,SELinux 被完全关闭,系统将恢复到传统的 DAC 访问控制模式。三、SELinux 的用法查看 SELinux 状态 可以使用sestatus命令来查看当前系统中 SELinux 的状态。该命令会显示 SELinux 的工作模式、策略类型等信息。切换 SELinux 工作模式 可以通过修改/etc/selinux/config文件中的SELINUX=参数来切换 SELinux 的工作模式。例如,将SELINUX=enforcing改为SELINUX=permissive可以将 SELinux 从强制模式切换到宽容模式。修改完后,需要重新启动系统才能使更改生效。管理 SELinux 策略 SELinux 的策略决定了主体对客体的访问权限。可以使用semanage命令来管理 SELinux 策略。例如,可以使用semanage port -a -t http_port_t -p tcp 8080命令来将端口 8080 标记为 HTTP 端口,允许 HTTP 服务使用该端口。处理 SELinux 违规 如果在系统运行过程中出现了 SELinux 违规行为,可以使用audit2allow命令来分析审计日志,并生成相应的策略模块,以允许特定的访问行为。例如,如果某个进程无法访问某个文件,可以使用audit2allow -a命令来分析审计日志,并生成相应的策略模块,然后使用semodule -i <module_name>.pp命令来安装该策略模块。四、SELinux 的优势增强系统安全性 SELinux 通过严格的访问控制,可以有效地防止恶意软件和攻击者对系统的攻击。它可以限制进程的权限,防止进程对系统资源的非法访问,从而提高系统的安全性。提高系统稳定性 SELinux 可以防止进程之间的非法交互,从而减少系统崩溃和错误的发生。它可以确保系统中的各个组件按照预设的安全策略进行交互,提高系统的稳定性。便于系统管理 SELinux 的策略可以集中管理,管理员可以通过修改策略文件来控制整个系统的安全策略。这使得系统管理更加方便和高效。
  • [技术干货] 解决生产环境遇到的curl和yum命令报错问题【转】
    1.背景生产环境进行了漏洞扫描检测出sshd服务的版本漏洞(CVE-2024-6387),给出的解决方案是升级最新版本的sshd服务即最新版本9.8,升级sshd服务需要依赖openssl,在升级的同时也将openssl版本进行了升级,升级的openssl版本是openssl-1.1.1l。使用的操作系统是银河麒麟V10SP2 arm64。2.过程升级完成后ssh服务测试正常使用没有问题但是curl和yum命令执行时分别出现了如下报错curl: relocation error: /lib64/libcurl.so.4: symbol SSLv3_client_method version OPENSSL_1_1_0 not defined in file libssl.so.1.1 with link time referenc根据报错分析是升级openssl的版本和现有的版本的libcurl.so.4的文件不兼容导致,因此也查询了资料进行了修复,但是都没有效果,最终决定重新编译安装curl命令试试。编译安装curl命令如下step1:下载curl源码包1wget https://curl.se/download/curl-8.8.0.tar.gzstep2:解压1tar xf curl-8.8.0.tar.gzstep3:编译(使用刚才升级的openssl作为依赖)12cd curl-8.8.0/./configure --prefix=/usr/src --with-ssl=/usr/local/sslstep4:安装1make && make install编译安装完成后会在/usr/src/目录下生成4个目录/usr/src/{bin,include,lib,share},curl命令的可执行文件在bin目录下,我们可以进行测试一下:测试curl命令可以正常使用,但是yum命令还不行此时我们可以查看新编译安装的curl命令的lib目录/usr/src/lib目录下有libcurl.so.4软连接的文件我们将原机器的libcurl.so.4文件进行备份,用新编译的文件进行一个替换操作12345[root@ths01 ~]# ls -l /lib64/libcurl.so.4lrwxrwxrwx 1 root root 16 Jun  8  2020 /lib64/libcurl.so.4 -> libcurl.so.4.6.0[root@ths01 ~]# mv /lib64/libcurl.so.4.6.0 /lib64/libcurl.so.4.6.0_bak[root@ths01 ~]# chmod +x libcurl.so.4.8.0[root@ths01 ~]# mv libcurl.so.4.8.0 /lib64/libcurl.so.4.6.0此时们再次使用curl和yum命令就会恢复正常
  • [互动交流] CodeArts IDE支持Linux系统不?
    CodeArts IDE支持Linux系统不?我看申请了云主机是ubuntu,预装了CodeArts IDE for JAVA不知道哪里有CodeArts IDE的Linux安装包下载?
  • [技术干货] 【Linux】缓冲区和文件系统-转载
    一、缓冲区 1.1 概念 要理解什么是缓冲区,先看这段代码  #include <stdio.h> #include <string.h> #include <unistd.h>   int main() {     const char *fstr = "fwrite\n";     const char *str = "write\n";       printf("printf\n");     fprintf(stdout, "fprintf\n");     fwrite(fstr, strlen(fstr), 1, stdout);     write(1, str, strlen(str));       fork();     return 0; }   执行程序,会向终端打印四行内容   但是如果我们把程序输出的内容重定向到一个普通文件中,会打印多少行呢?   此时变成了7行内容,其中printf、fprintf和fwrite打印了两次,为什么?  我们可以看到,在程序的最后创建了一个子进程,所以肯定是因为子进程所以才会重复打印  并且重复打印的接口都是库函数,而系统调用接口write并没有打印两次  在前面的学习中,我们已经初步认识了什么是缓冲区,这里简单回顾一下  实际上我们在对一个文件进行写入时并不是直接写入到文件中的,而是先写入到缓冲区,缓冲区再根据不同的方式将其内容刷新到文件中  缓冲区有三种刷新方式:  无缓冲,即一进行写入就对缓冲区进行刷新,一个一个字符写入 行缓冲,遇到\n才对缓冲区进行刷新,一行一行写入 全缓冲,缓冲区满了才进行刷新,一堆一堆写入 一般我们在向显示器文件进行写入时采用的策略是行缓冲,即遇到\n就打印一行;而对于普通文件系统则采用全缓冲策略。缓冲区的存在能够减少消耗,提高效率  而我们还知道,子进程虽然会继承父进程的代码和数据,不过一旦一方修改了数据,就会发生写时拷贝  而缓冲区不同的刷新方式配合上写时拷贝,你是否已经知道为什么会发生重复打印了呢?  没错,因为向显示器文件中打印的时候采用行缓冲策略,所以缓冲区中不会有内容堆积,遇到\n就刷新一次缓冲区  所以在最后创建子进程时父进程的缓冲区空空如也,所以子进程的缓冲区也是空的  但是,如果重定向到了普通文件,此时就要采用全缓冲策略,所有的内容都堆积在缓冲区中  子进程创建时继承了父进程包含一大堆内容的缓冲区,而父进程在退出时刷新缓冲区的时候发生写时拷贝,不会影响到子进程的缓冲区,此时子进程再进行写入,就导致部分内容被写入了两次  但是为什么write不会重复写呢?  1.2 用户缓冲区和内核缓冲区 我们观察到,在向普通文件中打印时,库函数被打印了两次,而只有系统调用接口write打印了一次  为什么?  实际上C语言中的库函数写入的缓冲区是C语言提供的用户级缓冲区,而write这种系统调用接口直接写入的是内核的缓冲区  父子进程间的写时拷贝局限于用户态,不会影响到内核缓冲区  C语言的部分文件操作接口封装了系统调用接口write,库函数首先将内容写入到用户级缓冲区,然后根据不同的刷新方式调用write将内容写入到内核的缓冲区  我们再来看一段代码  #include <stdio.h> #include <string.h> #include <unistd.h>   int main() {     const char *fstr = "fwrite\n";     const char *str = "write\n";       printf("printf\n");     fprintf(stdout, "fprintf\n");     fwrite(fstr, strlen(fstr), 1, stdout);     write(1, str, strlen(str));     close(1); // 关闭标准输出流       return 0; }  将打印的内容重定向到普通文件,此时发现只有write被打印了   这也是因为close关闭文件描述符时只会把内核缓冲区中的内容刷新到文件中,所以库函数向用户缓冲区写入的内容采用全缓冲还停留在用户缓冲区内,而write向内核缓冲区写入的内容被刷新到了文件中  C语言提供的用户缓冲区在哪呢?前面我们见过C语言提供的FILE结构体,存放了文件描述符等内容,其内部还有对应文件的缓冲区字段和维护信息  语言都属于用户层,C语言提供的FILE结构体自然也属于用户,所以其内部的缓冲区属于用户级缓冲区  二、磁盘的结构 磁盘是计算机主要的存储介质,可以存储大量的二进制数据,并且断电后也能保持数据不丢失。早期计算机使用的磁盘是软磁盘(Floppy Disk,简称软盘),如今常用的磁盘是硬磁盘(Hard disk,简称硬盘)   文件在没被打开的时候,是以二进制形式存储在硬盘中的,而硬盘又是如何存储这些二进制数据的呢?  机械硬盘的内部结构:   一个硬盘里可能堆叠了多张盘片,盘片的每一面都有一个磁头,这些所有的磁头都是连在同一个磁头臂上的,所以只能共同移动。磁头和盘面不接触  盘片表面涂有磁性物质,通过输入不同的电流方向,来改变不同部位的磁性,从而就能区分出0和1  而一个盘面又分为许多不同半径的同心圆,每个圆环是一个磁道,磁道的内部又分为许多的扇区  每个扇区能够存储的内容大小一样,其中,最内侧磁道上的扇区面积最小,因此数据密度最大  每张盘片的大小相同,而在不同的盘片中处于相同位置(同样半径)的磁道组成了柱面   磁盘被访问的最基本单元是扇区,一个扇区一般是512字节  因此,我们可以把磁盘看作由无数个扇区构成的存储介质  既然有了扇区,要把数据保存到磁盘中或取出数据,首先要解决的问题是:如何定位一个扇区  要定位一个扇区,我们得先知道要保存到哪一面(即哪个磁头),和哪一个磁道(柱面)  因此产生了CHS寻址方式:依据柱面(磁道)、磁头、扇区来查找数据位置  首先定位对应数据所在的盘面,移动对应盘面的磁头 ;磁头臂带动磁头在盘面上移动,就是定位磁道的过程;而主轴带动盘片旋转,则是定位扇区的过程  如果我们像磁带一样把磁盘的所有盘面展开成一个线性的结构,那么整个磁盘就像是一个由无数扇区构成的数组,每个扇区就有自己独立的编号,我们称为LBA地址   现在我们可以把磁盘视为一个数组,只需要知道每个盘面有多少个扇区,每个磁道有多少个扇区,我们就可以通过某个扇区的下标找到其对应的磁头、磁道、扇区了  例如我们假设一个盘面有20000个磁道,一个磁道有400个扇区   通过计算,我们就可以把LBA地址转化为CHS地址了  三、文件系统 3.1 初识“块”和inode 一个文件如果为空,那么它存储在磁盘中是否不会占用空间呢?答案是否  文件不单单包含文件内容,还包含文件属性。文件的内容由一个个数据块存储,而文件的属性则需要一个名为inode的结构保存  数据块(block)的大小通常为4KB,即8个扇区组成一个块。块是文件存取的最小单位,即操作系统在读取硬盘时不会一个个扇区存取,这样影响效率,而是最少取一个块。文件的属性则由名为inode的结构存储,其内部存放了inode编号、文件类型、文件权限等属性  每个数据块也有编号,因为文件的内容存储在许多的数据块中,inode中一定会有一个数组存储该文件的所有块编号。但是如果块很多,一个数组大小不一定存的下这么多编号  为了让数组存下整个文件的所有块编号,数组后几个位置存在多级索引,具体实现为其编号对应的块中存储的不是文件内容,而是其他块的编号。在逻辑上体现为一颗多叉树的结构   需要注意的是,inode中的属性不包含文件名,每个inode都有自己唯一的编号,系统中标识一个文件只看inode编号  我们也可以通过 ls -li 命令来查看一个文件的inode编号:   除此之外,我们还可以通过stat命令来获取更详细的文件属性信息:   3.2 磁盘分区和文件系统 我们发现,即使我们的电脑里只有一块硬盘,但也能分出很多个区,即我们电脑中的C盘、D盘等,并且我们还可以自己设置这些分区的大小   但是这些分区还是太大了,不便于管理,因此我们再将一个分区划分为多个块组   在Linux的ext2文件系统中,Boot Block(引导块)位于分区的开头,占用1024字节,用于存放开机管理程序  而每个Block group又细分为   其中:  Super Block(超级块):存放文件系统本身的结构信息,主要有block和inode的总量、未使用的block和inode的数量、单个block和inode的大小、最近一次写入数据的时间等等。Super Block对于文件系统而言是至关重要的,所以ext2文件系统会在多个块组中保存超级块的信息 Group Descriptor Table(GDT):块组描述符表,描述块组的属性信息 Block Bitmap(块位图):记录Data blocks中哪些数据块已被使用,哪些数据块未被使用 inode Bitmap(inode位图):记录inode的使用情况 inode Table(inode表):存放inode Data blocks:存放数据块 所以对一个文件的增删查改,实际上就是对文件系统的操作   新建一个文件,在inode位图中找到最近一个未被使用的位置来分配inode并初始化信息,然后根据文件的大小分配数据块并修改inode位图和块位图结构  删除一个文件,将文件所属的inode位图和块位图中的位置修改为0即可(删除即允许被覆盖)  查找一个文件,通过其路径(哪个盘)就可以找到所在分区,然后根据inode编号知道其属于哪个块组的,在inode的位图中确认其是否存在,确认存在就在inode表中取出其inode中的信息并载入内存,通过这些信息找到文件所属的数据块,将这些块拼接得到文件内容  修改一个文件,还是先找到其inode,然后修改对应的属性,如果文件大小发生变动还需要决定是否新增数据块或删除数据块并修改位图  但是问题来了:我是用户,只用文件名,我怎么知道文件的inode编号?  在Linux下一切皆文件,目录也是文件,也有自己的内容和属性,和自己的inode编号  而目录的内容,就是该目录下文件的文件名与inode编号的映射关系!  这也解释了为什么同一目录下不能有同名文件,就像map中不能有相同的key一样  但是,要找一个文件得先知道其目录的inode编号,但是其目录的inode编号又被这个目录的父目录管理着,还得知道父目录的inode编号...一路下去我们就得先从根目录开始找起  这样的方式一定程度上会影响效率,所以系统把我们常访问的目录存到dentry缓存中  简单的介绍了一下文件系统,如有错误欢迎在评论区指出  完. ————————————————                              版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。                          原文链接:https://blog.csdn.net/Eristic0618/article/details/141161151 
  • [技术干货] 【Linux】解锁Shell脚本编写秘籍,编程高手之路等你开启-转载
     1. 打印命令行提示符  #include<stdlib.h>  char* HostName() //获取主机名 {     char* ret = getenv("HOSTNAME");      if(ret) return ret;     else return (char*)"None"; }   char* UserName() //获取用户名 {     char* ret = getenv("USER");     if(ret) return ret;     else return (char*)"None";                                                          }      char* CurrentWorkdir() //获取当前工作目录 {     char* ret = getenv("PWD");     if(ret) return ret;     else return (char*)"None"; }  int main() {     //打印命令行提示符      //读取环境变量的内容 / 调用函数(gethostname获取主机名、getcwd获取当前工作目录)     printf("[%s@%s %s]#", UserName(), HostName(), CurrentWorkdir()); } 2. 获取用户输入的命令行字符串 可以使用scanf读取字符串吗? 答:不能,scanf用于从标准输入(键盘)读取格式化输入,读取字符串时,scanf会在遇到空白字符(空格、换行符\n、制表符\t等)时停止读取,并将读取的字符串存储到字符数组中。 char* fgets(char* str, int size, FILE* stream); 功能:从指定的文件流stream中读取一行(直到遇到换行符\n、文件结束符EOF、已读取了n-1个字符为止),并将读取的字符串(包括换行符,如果有的话)存储在str指向的数组中,并在数组的末尾添加’\0’来标记字符串的结束。  优点:可以限制读取的字符数,防止缓冲区溢出,并且可以读取包含空格的字符串。  缺点:如果读取的行比指定的长度n还要长,则多余的字符会被留在输入缓冲区中。  文件流stream是程序用于输入和输出的基本抽象,stdin为标准输入流(键盘)、stdout为标准输出流(控制台或终端)、stderr为标准错误输出流。   #include<stdlib.h>  #define SIZE 1024  int Interative(char* in)  {     printf("[%s@%s %s]#", UserName(), HostName(), CurrentWorkdir());                                                           fgets(in, SIZE, stdin);       in[strlen(in) - 1] = '\0';  //移除换行字符\n          return strlen(in) - 1;  //处理空串""情况 }  int main() {     char CommandLine[SIZE]; //存储用户输入的命令行字符串      while(1)     {         //打印命令行提示符+获取用户输入的命令行字符串                                               int n =  Interative(CommandLine);           if(n == 0) continue;  //空串,用户继续输入     }      return 0; } char* getcwd(char* buf,size_t size);   #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h>  #define SIZE 1024  char* argv[SIZE]; //相当于main函数的命令行参数表,末尾一定要以NULL结尾  int BuiltinCmd() {     int ret = 0; //用于判断是否为内建命令,不是,则为0、是,则为1     if(strcmp("cd", argv[0]) == 0)     {         ret = 1;          char* target = argv[1]; //需要切换的路径         if(!target) target = getenv("HOME"); //cd,表示切换到家目录中         chdir(target); //更改当前工作目录                  char tmp[SIZE];  //存储获取到的当前工作目录的绝对路径         char pwd[SIZE];  //存储更改后的环境变量PWD的内容         getcwd(tmp, SIZE);  //获取当前工作目录的绝对路径                                      snprintf(pwd, SIZE, "PWD=%s", tmp); //多变一,拼接              putenv(pwd); //修改环境变量PWD的内容     }      return ret; }  int main() {     char CommandLine[SIZE];       while(1)     {         //1.打印命令行提示符+获取用户输入的命令行字符串                                               int n =  Interative(CommandLine);           if(n == 0) continue;  //空串,用户继续输入          //2.分割命令行字符串         Split(CommandLine);          //3.处理内建命令         n = BuiltinCmd();         if(n) continue;     }      return 0; } 4.5. export int BuiltinCmd() {     int ret = 0;      if(strcmp("export", argv[0]) == 0)     {         ret = 1;         if(argv[1])         {              putenv(argv[1]);                                             }       }          return ret; } 问:为什么第一次export新增环境变量成功,但再输入了其他指令,这个新增的环境变量就不见了?  因为argv为字符指针数组,执行完export后,再输入其他指令,则argv中原有的内容就会被其他指令所覆盖。 char env[SIZE]; //相当于环境变量表,存储新增的环境变量  int BuiltinCmd() {     if(strcmp("export", argv[0]) == 0)     int ret = 0;      {         ret = 1;         if(argv[1])         {             strcpy(env, argv[1]); //将新增的环境变量的内容,拷贝到环境变量表中             putenv(env);                                          }       }          return ret; } 4.6. echo char env[SIZE]; //相当于环境变量表,存储新增的环境变量  int BuiltinCmd() {     if(strcmp("echo", argv[0]) == 0)      {                                                                ret = 1;         if(!argv[1])  //echo:打印一个空行             printf("\n");         else if(argv[1][0] != '$')              printf("%s\n", argv[1]); //echo aaaa:打印aaaa         else          {             if(argv[1][1] == '?')             {                 printf("%d\n", exit_code); //echo $?:打印退出码                 exit_code = 0; //便于在执行echo $?时,退出码=0             }             else                  printf("%s\n", getenv(argv[1] + 1)); //echo $USER:打印环境变量的内容         }     }      return ret; } 5. 执行命令 1.Shell脚本编写,bash执行命令时,通常会创建子进程,让子进程执行程序替换。  原因:a. bash是命令行解释器,需要一直执行命令,若让父进程进行替换,执行命令,则父进程就会退出;b. 进程之间具有独立性,子进程进行替换,对父进程无影响。 5.1. 创建子进程进行程序替换 #include<stdlib.h> #include<string.h> #include<sys/types.h> #include<sys/wait.h>  #define SIZE 1024 #define SP " "  char* argv[SIZE];  int exit_code;  //全局变量,存储子进程的退出码,便于echo $?直接输出退出码  void Execute() {     pid_t id = fork();              if(id == 0)     {         execvp(argv[0], argv); //程序替换,执行命令         exit(1);  //子进程退出     }        int status = 0;     pid_t rid = waitpid(id, &status, 0); //父进程等待,进行回收子进程的资源     if(rid > 0)     {         exit_code = WEXITSTATUS(status); //正常退出,获取子进程的退出码     }                                                                               }  int main() {     char CommandLine[SIZE];       while(1)     {         //1.打印命令行提示符+获取用户输入的命令行字符串                                               int n =  Interative(CommandLine);           if(n == 0) continue;  //空串,用户继续输入          //2.分割命令行字符串         Split(CommandLine);          //4.执行命令(创建子进程,进行替换)         Execute();     }      return 0; }  6. 重定向 为什么要宏定义多个整数,定义全局变量redir_type? 重定向有三种类型:输出重定向>、追加重定向>>、输出重定向。  我们需要在命令行参数中,查找是否有重定向,如果有重定向,就需要获取重定向的类型,从而在根据重定向的类型执行对应的指令。  所以我们用宏定义多个整数,来表示重定向的类型; 定义一个全局变量redir_type,用来记录获取到的重定向的类型  #define NoneRedir -1 #define StdinRedir 0 #define StdoutRedir 1 #define AppenRedir 2  char* filename = NULL; int redir_type = -1; 1 2 3 4 5 6 7 8 通常来说,重定向由三部分组成:要执行的命令 重定向符号 文件名(如:ls -l > log.txt)。 我们需要获取两部分内容:将要执行的命令进行分割,获取重定向文件。 char* filename = NULL; 1 执行流程:首先判断是否包含重定向(checkRedir);再把我们要执行的命令进行分分割(将重定向字符设置为’\0’,这样strtok只能切割要执行的命令);最后让子进程执行重定向操作。 #define IsSpace(buf, pos) do{while(isspace(buf[pos])) pos      ++;}while(0) 1 while(0)目的:可以在使用宏定义的函数处,结尾加上分号(;)可以消除宏和函数之间的这部分差异,让宏看起来更像个函数。  //用宏定义多个整数,来表示重定向的类型 #define NoneRedir -1 #define StdinRedir 0 #define StdoutRedir 1 #define AppenRedir 2  char* filename = NULL; //记录文件名 int redir_type = -1;  //记录重定向类型  //去除命令行参数中的空格(连续空格) #define IsSpace(buf, pos) do{while(isspace(buf[pos])) pos++;}while(0)  //检查是否包含重定向符号 void CheckRedir(char* in) {     filename = NULL;     redir_type = -1;          int pos = strlen(in) - 1; //从命令行参数字符串后面往前找     while(pos >= 0)     {         if(in[pos] == '>')          {             if(in[pos - 1] == '>') //追加重定向             {                 redir_type = 2;                                           in[pos - 1] = '\0'; //便于将要执行的命令分割开                 pos++; //当前pos位置不是空格,isspace函数为假,直接返回                 IsSpace(in, pos);  //跳过空格                 filename = in + pos; //获取文件名                 break; //记录完毕,就立即退出              }              else   //输出重定向              {                  redir_type = 1;                  in[pos] = '\0';                  pos++;                  IsSpace(in, pos);                               filename = in + pos;                  break;              }         }         else if(in[pos] == '<') //输入重定向         {             redir_type = 0;             in[pos] = '\0';             pos++;             IsSpace(in, pos);             filename = in + pos;             break;         }         else          {              pos--;         }     } }  void Split(char* in) {     CheckRedir(in); //在分割之前,先判断是否包含重定向符号          int i = 0;     argv[i++] = strtok(in, SP);  //首次调用     while(argv[i++] = strtok(NULL, SP)); //后续调用      if(strcmp("ls", argv[0]) == 0)      {        argv[i-1] = (char*)"--color";   //加上后,ls显示内容,颜色为auto                           argv[i] = NULL; //argv以NULL结尾,便于子进程在进程程序替换时参数的传递     } }  void Execute() {     pid_t id = fork();              if(id == 0)       {         //让子进程执行重定向         int fd = -1;                                              if(redir_type == StdinRedir)         {             fd = open(filename, O_RDONLY);             dup2(fd, 0);  //改变文件描述符的执行,从而实现输入、输出重定向         }         else if(redir_type == StdoutRedir)         {             fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666);             dup2(fd, 1);         }         else if(redir_type == AppenRedir)         {             fd = open(filename, O_WRONLY|O_CREAT|O_APPEND      , 0666);             dup2(fd, 1);         }            execvp(argv[0], argv); //程序替换,执行命令         exit(1);  //子进程退出     }        int status = 0;     pid_t rid = waitpid(id, &status, 0); //父进程等待,进行回收子进程的资源     if(rid > 0)     {         exit_code = WEXITSTATUS(status); //正常退出,获取子进程的退出码     }                                                                               } 7. 总代码 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<sys/types.h> #include<sys/wait.h> #include<ctype.h> #include<sys/stat.h> #include<fcntl.h>  #define SIZE 1024 #define SP " "  char* argv[SIZE];  char env[SIZE]; //相当于环境变量表,存储新增的环境变量  int exit_code;  //全局变量,存储子进程的退出码,便于echo $?直接输出退出码  //以下都和重定向有关 //用宏定义多个整数,来表示重定向的类型 #define NoneRedir -1 #define StdinRedir 0 #define StdoutRedir 1 #define AppenRedir 2  char* filename = NULL; //记录文件名 int redir_type = -1;  //记录重定向类型  //去除命令行参数中的空格(连续空格) #define IsSpace(buf, pos) do{while(isspace(buf[pos])) pos++;}while(0)  char* HostName() //获取主机名 {     char* ret = getenv("HOSTNAME");      if(ret) return ret;     else return (char*)"None"; }   char* UserName() //获取用户名 {     char* ret = getenv("USER");     if(ret) return ret;     else return (char*)"None";                                                          }      char* CurrentWorkdir() //获取当前工作目录 {     char* ret = getenv("PWD");     if(ret) return ret;     else return (char*)"None"; }  int Interative(char* in)  {     printf("[%s@%s %s]#", UserName(), HostName(), CurrentWorkdir());                                                           fgets(in, SIZE, stdin);       in[strlen(in) - 1] = '\0';  //移除换行字符\n          return strlen(in) - 1;  //处理空串""情况 }  //检查是否包含重定向符号 void CheckRedir(char* in) {     filename = NULL;     redir_type = -1;          int pos = strlen(in) - 1; //从命令行参数字符串后面往前找     while(pos >= 0)     {         if(in[pos] == '>')          {             if(in[pos - 1] == '>') //追加重定向             {                 redir_type = 2;                                           in[pos - 1] = '\0'; //便于将要执行的命令分割开                 pos++; //当前pos位置不是空格,isspace函数为假,直接返回                 IsSpace(in, pos);  //跳过空格                 filename = in + pos; //获取文件名                 break; //记录完毕,就立即退出              }              else   //输出重定向              {                  redir_type = 1;                  in[pos] = '\0';                  pos++;                  IsSpace(in, pos);                               filename = in + pos;                  break;              }         }         else if(in[pos] == '<') //输入重定向         {             redir_type = 0;             in[pos] = '\0';             pos++;             IsSpace(in, pos);             filename = in + pos;             break;         }         else          {              pos--;         }     } }  void Split(char* in) {     CheckRedir(in); //在分割之前,先判断是否包含重定向符号          int i = 0;     argv[i++] = strtok(in, SP);  //首次调用     while(argv[i++] = strtok(NULL, SP)); //后续调用      if(strcmp("ls", argv[0]) == 0)      {        argv[i-1] = (char*)"--color";   //加上后,ls显示内容,颜色为auto                           argv[i] = NULL; //argv以NULL结尾,便于子进程在进程程序替换时参数的传递     } }  int BuiltinCmd() {     if(strcmp("echo", argv[0]) == 0)      {                                                                ret = 1;         if(!argv[1])  //echo:打印一个空行             printf("\n");         else if(argv[1][0] != '$')              printf("%s\n", argv[1]); //echo aaaa:打印aaaa         else          {             if(argv[1][1] == '?')             {                 printf("%d\n", exit_code); //echo $?:打印退出码                 exit_code = 0; //便于在执行echo $?时,退出码=0             }             else                  printf("%s\n", getenv(argv[1] + 1)); //echo $USER:打印环境变量的内容         }     }     else if(strcmp("cd", argv[0]) == 0)     {         ret = 1;          char* target = argv[1]; //需要切换的路径         if(!target) target = getenv("HOME"); //cd,表示切换到家目录中                  chdir(target); //更改当前工作目录                  char tmp[SIZE];  //存储获取到的当前工作目录的绝对路径         char pwd[SIZE];  //存储更改后的环境变量PWD的内容         getcwd(tmp, SIZE);  //获取当前工作目录的绝对路径                                      snprintf(pwd, SIZE, "PWD=%s", tmp); //多变一,拼接              putenv(pwd); //修改环境变量PWD的内容     }     else if(strcmp("export", argv[0]) == 0)     int ret = 0;      {         ret = 1;         if(argv[1])         {             strcpy(env, argv[1]); //将新增的环境变量的内容,拷贝到环境变量表中             putenv(env);                                          }       }      return ret; }  void Execute() {     pid_t id = fork();              if(id == 0)       {         //让子进程执行重定向         int fd = -1;                                              if(redir_type == StdinRedir)         {             fd = open(filename, O_RDONLY);             dup2(fd, 0);  //改变文件描述符的执行,从而实现输入、输出重定向         }         else if(redir_type == StdoutRedir)         {             fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666);             dup2(fd, 1);         }         else if(redir_type == AppenRedir)         {             fd = open(filename, O_WRONLY|O_CREAT|O_APPEND      , 0666);             dup2(fd, 1);         }            execvp(argv[0], argv); //程序替换,执行命令         exit(1);  //子进程退出     }        int status = 0;     pid_t rid = waitpid(id, &status, 0); //父进程等待,进行回收子进程的资源     if(rid > 0)     {         exit_code = WEXITSTATUS(status); //正常退出,获取子进程的退出码     } }   int main() {     char CommandLine[SIZE];       while(1)     {         //1.打印命令行提示符+获取用户输入的命令行字符串                                               int n =  Interative(CommandLine);           if(n == 0) continue;  //空串,用户继续输入          //2.分割命令行字符串         Split(CommandLine);          //3.处理内建命令         n = BuiltinCmd();         if(n) continue;          //4.执行命令(创建子进程,进行替换                     Execute();     }        return 0; }  ————————————————                              版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。                          原文链接:https://blog.csdn.net/m0_74808907/article/details/142133792 
  • [技术干货] linux-查看硬盘信息命令-转载
     Linux查看硬盘信息的几种命令包括df、du、lsblk、fdisk、smartctl。  一、 df命令 df -h 是最常见的磁盘查看命令。它可以显示文件系统的总大小、已用空间、可用空间和挂载点等信息。  [root@FZCTP-DB ~]# df -h Filesystem               Size  Used Avail Use% Mounted on /dev/mapper/centos-root  110G   46G   65G  42% / /dev/mapper/centos-data  1.9T  1.5T  389G  80% /data /dev/vda2               1014M  196M  819M  20% /boot /dev/vdb1                1.0T   14G 1011G   2% /backup tmpfs                     41G   12G   30G  29% /dev/shm tmpfs                     32G  2.2G   30G   7% /run tmpfs                     32G     0   32G   0% /sys/fs/cgroup tmpfs                    6.3G   40K  6.3G   1% /run/user/0 tmpfs                    6.3G     0  6.3G   0% /run/user/1001 /dev/sr0                 4.3G  4.3G     0 100% /mnt/cdrom devtmpfs                  32G     0   32G   0% /dev “Size”表示文件系统总大小,“Used”表示已使用大小,“Avail”表示可用空间linux启动盘制作工具,“Use%”表示已使用百分比  二、du 命令 du命令是用于查看目录或文件占用磁盘空间的命令。  常用命令和选项,统计当前目录下的文件和目录占用空间  [root@FZCTP-DB ~]# du -sh * 4.0K    anaconda-ks.cfg 4.0K    Desktop 4.0K    Documents 20K     Downloads 64K     install.log 12K     install.log.syslog 11G     logs 4.0K    Music 4.0K    Pictures 4.0K    Public 436K    soft -s, --summarize                        仅显示总计,只列出最后加总的值。 -h, --human-readable                   以K,M,G为单位,提高信息的可读性。 常看指定目录下所有文件的大小(会遍历所有文件)  [root@FZCTP-DB tomcat]# du -h  apache-tomcat-9.0.36/ 6.5M    apache-tomcat-9.0.36/webapps/java/applets 16K     apache-tomcat-9.0.36/webapps/java/WEB-INF/classes/com/bstek/dorado/uploader/resolver 20K     apache-tomcat-9.0.36/webapps/java/WEB-INF/classes/com/bstek/dorado/uploader 16K     apache-tomcat-9.0.36/webapps/java/WEB-INF/classes/com/bstek/dorado/view/output 20K     apache-tomcat-9.0.36/webapps/java/WEB-INF/classes/com/bstek/dorado/view/resolver 48K     apache-tomcat-9.0.36/webapps/java/WEB-INF/classes/com/bstek/dorado/view 12K     apache-tomcat-9.0.36/webapps/java/WEB-INF/classes/com/bstek/dorado/web/resolver 16K     apache-tomcat-9.0.36/webapps/java/WEB-INF/classes/com/bstek/dorado/web 88K     apache-tomcat-9.0.36/webapps/java/WEB-INF/classes/com/bstek/dorado 36K     apache-tomcat-9.0.36/webapps/java/WEB-INF/classes/com/bstek/bdf2/export/excel 12K     apache-tomcat-9.0.36/webapps/java/WEB-INF/classes/com/bstek/bdf2/export/csv 将文件从大到小排序  du -sh *  |sort -rh 三、lsblk命令 lsblk该命令可以列出系统中所有块设备(如硬盘、SSD 等)的信息,包括设备名称、容量、挂载点等。通过这个命令可以方便地了解系统硬件配置和磁盘分区情况。  [root@FZCTP-DB ~]# lsblk NAME                                MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT sda                                   8:0    0 558.9G  0 disk  |-sda1                                8:1    0   500M  0 part /boot/efi |-sda2                                8:2    0   500M  0 part /boot `-sda3                                8:3    0 557.9G  0 part    |-vg_fzctpdb-LogVol00_swap (dm-0) 253:0    0    64G  0 lvm  [SWAP]   |-vg_fzctpdb-LogVol04_root (dm-1) 253:1    0 453.9G  0 lvm  /   |-vg_fzctpdb-LogVol03_var (dm-2)  253:2    0    20G  0 lvm  /var   |-vg_fzctpdb-LogVol02_usr (dm-3)  253:3    0    10G  0 lvm  /usr   `-vg_fzctpdb-LogVol01_tmp (dm-4)  253:4    0    10G  0 lvm  /tmp 四、fdisk命令 fdisk 命令可以显示系统中所有硬盘的分区情况,包括分区类型、容量、起始位置等信息。通过这个命令可以查看系统磁盘的物理结构和分布情况。  [root@FZ-DB ~]# fdisk -l  Disk /dev/sda: 600.1 GB, 600093712384 bytes 255 heads, 63 sectors/track, 72957 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 262144 bytes / 262144 bytes Disk identifier: 0x00000000     Device Boot      Start         End      Blocks   Id  System /dev/sda1               1       72958   586029015+  ee  GPT Partition 1 does not start on physical sector boundary.  Disk /dev/mapper/vg_fzctpdb-LogVol00_swap: 68.7 GB, 68719476736 bytes 255 heads, 63 sectors/track, 8354 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 262144 bytes / 262144 bytes Disk identifier: 0x00000000  Disk /dev/mapper/vg_fzctpdb-LogVol04_root: 487.4 GB, 487369736192 bytes 255 heads, 63 sectors/track, 59252 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 262144 bytes / 262144 bytes Disk identifier: 0x00000000  Disk /dev/mapper/vg_fzctpdb-LogVol03_var: 21.5 GB, 21474836480 bytes 255 heads, 63 sectors/track, 2610 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 262144 bytes / 262144 bytes Disk identifier: 0x00000000  Disk /dev/mapper/vg_fzctpdb-LogVol02_usr: 10.7 GB, 10737418240 bytes 255 heads, 63 sectors/track, 1305 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 262144 bytes / 262144 bytes Disk identifier: 0x00000000  Disk /dev/mapper/vg_fzctpdb-LogVol01_tmp: 10.7 GB, 10737418240 bytes 255 heads, 63 sectors/track, 1305 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 262144 bytes / 262144 bytes Disk identifier: 0x00000000 五、smartctl命令 smartctl命令是用于检测硬盘健康状态并显示相关信息的命令。它可以显示硬盘的温度、寿命预测、错误记录等信息。  [root@FZ-DB ~]# smartctl -a /dev/sda smartctl 5.43 2016-09-28 r4347 [x86_64-linux-2.6.32-696.el6.x86_64] (local build) Copyright (C) 2002-12 by Bruce Allen, http://smartmontools.sourceforge.net  Vendor:               HP       Product:              LOGICAL VOLUME   Revision:             5.52 User Capacity:        600,093,712,384 bytes [600 GB] Logical block size:   512 bytes Logical Unit id:      0x600508b1001c13ef256161d9825110ea Serial number:        PDNLH0BRH981LP   Device type:          disk Local Time is:        Wed Jun 19 10:24:12 2024 CST Device supports SMART and is Enabled Temperature Warning Disabled or Not Supported SMART Health Status: OK  Error Counter logging not supported Device does not support Self Test logging  https://www.linuxcool.com/lypkjzkmlff https://zhuanlan.zhihu.com/p/688628108 ————————————————                              版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。                          原文链接:https://blog.csdn.net/u011475248/article/details/139795422 
  • [技术干货] Linux telnet命令教程:远程控制工具(附实例详解和注意事项) -转载
     Linux telnet命令介绍 telnet(Teletype Network)是一种网络协议,用于在远程主机和本地计算机之间建立文本式连接。它最初于1969年开发,是Internet的早期协议之一。telnet命令使用TCP/IP网络通过端口23建立连接,提供了一种通过命令行界面管理远程系统的方式。  Linux telnet命令适用的Linux版本 telnet命令在大多数Linux发行版中都可以使用,但可能需要手动安装。以下是在不同Linux发行版中安装telnet的方法:  Debian/Ubuntu:使用apt包管理器安装。 [linux@bashcommandnotfound.cn ~]$ sudo apt update [linux@bashcommandnotfound.cn ~]$ sudo apt install telnetd -y 1 2 CentOS/RHEL/Fedora:使用yum或dnf包管理器安装。注意,CentOS 7和CentOS 8的安装工具可能不同。 [linux@bashcommandnotfound.cn ~]$ sudo yum update [linux@bashcommandnotfound.cn ~]$ sudo yum install telnet telnet-server -y 1 2 Linux telnet命令的基本语法 telnet命令的基本语法格式如下:  telnet [-468EKLadr] [-Xa authtype] [-b hostalias] [-e escapechar] [-l user] [-n tracefile] [ host [port] ] 1 Linux telnet命令的常用选项或参数说明 选项    说明 -4    强制使用IPv4地址 -6    强制使用IPv6地址 -8    允许8位输入数据 -E    禁止回显 -K    不自动登录到远程主机 -L    允许8位输出数据 -a    尝试自动登录 -b hostalias    使用主机别名代替真实主机名 -d    启用调试模式 -e escapechar    设置转义字符 -l user    自动登录为用户 -n tracefile    记录输入和输出信息到文件 -r    使用远程数据连接 host    指定要连接的远程主机 port    指定要连接的远程主机的端口号 Linux telnet命令实例详解 实例1:连接到远程主机 [linux@bashcommandnotfound.cn ~]$ telnet example.com 1 这个命令将连接到名为example.com的远程主机。  实例2:指定端口连接到远程主机 [linux@bashcommandnotfound.cn ~]$ telnet example.com 23 1 这个命令将连接到名为example.com的远程主机的23端口。  实例3:使用IPv4地址连接到远程主机 [linux@bashcommandnotfound.cn ~]$ telnet -4 example.com 1 这个命令将强制使用IPv4地址连接到名为example.com的远程主机。  实例4:使用IPv6地址连接到远程主机 [linux@bashcommandnotfound.cn ~]$ telnet -6 example.com 1 这个命令将强制使用IPv6地址连接到名为example.com的远程主机。  实例5:禁止回显 [linux@bashcommandnotfound.cn ~]$ telnet -E example.com 1 这个命令将禁止回显,连接到名为example.com的远程主机。  实例6:不自动登录到远程主机 [linux@bashcommandnotfound.cn ~]$ telnet -K example.com 1 这个命令将不自动登录到名为example.com的远程主机。  实例7:尝试自动登录 [linux@bashcommandnotfound.cn ~]$ telnet -a example.com 1 这个命令将尝试自动登录到名为example.com的远程主机。  实例8:使用主机别名代替真实主机名 [linux@bashcommandnotfound.cn ~]$ telnet -b example example.com 1 这个命令将使用主机别名example代替真实主机名example.com。  实例9:启用调试模式 [linux@bashcommandnotfound.cn ~]$ telnet -d example.com 1 这个命令将启用调试模式,连接到名为example.com的远程主机。  实例10:设置转义字符 [linux@bashcommandnotfound.cn ~]$ telnet -e ! example.com 1 这个命令将设置转义字符为!,连接到名为example.com的远程主机。  实例11:自动登录为用户 [linux@bashcommandnotfound.cn ~]$ telnet -l user example.com 1 这个命令将自动登录为用户user,连接到名为example.com的远程主机。  实例12:记录输入和输出信息到文件 [linux@bashcommandnotfound.cn ~]$ telnet -n tracefile example.com 1 这个命令将记录输入和输出信息到文件tracefile,连接到名为example.com的远程主机。  实例13:使用远程数据连接 [linux@bashcommandnotfound.cn ~]$ telnet -r example.com 1 这个命令将使用远程数据连接,连接到名为example.com的远程主机。  实例14:指定要连接的远程主机的端口号 [linux@bashcommandnotfound.cn ~]$ telnet example.com 8080 1 这个命令将连接到名为example.com的远程主机的8080端口。  实例15:连接到远程主机并执行命令 [linux@bashcommandnotfound.cn ~]$ echo "ls /" | telnet example.com 1 这个命令将连接到名为example.com的远程主机,并在远程主机上执行ls /命令。  Linux telnet命令的注意事项 telnet命令发送的数据不加密,因此可能容易成为黑客的目标。 如果在尝试使用telnet命令时收到bash: telnet: command not found的错误消息,可能需要安装telnet。 ————————————————                              版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。                          原文链接:https://blog.csdn.net/u012964600/article/details/136963732 
  • [技术干货] Linux:深入理解计算机软硬件体系和架构-转载
     一、硬件体系         首先我们要知道,我们最常见的计算机(笔记本)以及我们不常见的计算机(服务器)其实本质上都是一堆硬件的结合:cpu、网卡、显卡、内存、磁盘、显示器、键盘……         但他们并不是毫无章法地放在一起,硬件和硬件之间需要有效地组织成一个系统才能更好地发挥功能,我们把这个组织结构叫做冯诺依曼体系结构!  1.1 冯诺依曼体系结构介绍  a、输入设备:鼠标、键盘、摄像头、话筒、磁盘(文件读取)、网卡(网络接受)……  b、输出设备:显示器、播放器硬件、磁盘(写入文件)、网卡(网络发送)……          计算机只能识别二进制语言,所以人和计算机打交道,必须要借助输入输出设备,并且我们会发现有的设备是纯的输入或输出,而有的设备既有输入也有输出   c、存储区:内存        运行程序、读取文件、写入文件……等大部分操作都是在内存中进行的!   d、运算器:对我们的数据进行计算任务(算数运算、逻辑运算)  e、控制器:对我们的计算机硬件流程进行一定的控制        运算器和控制器统称为中央处理器(CPU)       冯诺依曼体系结构由以上五个部分组成,但我们要知道每一个硬件都是独立的个体,所以想要建立联系协同起来,必须借助“线”进行连接!!我们把它叫做总线,总线又分为系统总线和IO总线  系统总线:存储区和运算器、控制器之间的线   IO总线:存储区和输入设备、输出设备之间的线   1.2 冯诺依曼为什么要这么设计?         我们会发现一个问题就是,输入设备和输出设备并不直接跟中央处理器打交道,他们都只跟存储器打交道,所以存储器(内存)在这个过程中发挥了串联整个线路的作用!我们接下来就要分析为什么要这么去设计!!  1.2.1 提高工作效率 以下是计算机存储的金字塔层次结构:         CPU的速度是纳秒级别的,而硬盘是毫秒级别的,所以他们的速度差距太大了!!因此需要内存(微秒级别)在中间做一个和事佬。  1.2.2 串型变成并型          其实CPU和硬盘,很容易让你想到木桶效应,就是木桶能接多少水取决于他的短板,而同理计算机运行有多快似乎也应该取决于硬盘,但如果真的是这样的话,那我们加入内存的意义在哪呢?不也是会相互拖慢速度吗??           其实你会这么想的原因是,你把这套体系理解为串型了,就是单纯认为中央处理器一定要等到数据全都加载到存储器的才会去工作,其实在我们将数据从输入设备加载到存储器时,中央处理器可能并没有闲着,而是在处理别的工作!!他们是一个并型逻辑!!        举个例子:比如说二进制可执行程序其实也是文件,文件是在磁盘上存储的,我们要运行这个程序就必然要将其先读取到内存中,而当外部设备在将数据加载到内存中时,其实cpu可能正在进行其他的运算,当你把数据预先都加载到内存中的时候,cpu恰好开始执行你的代码,所以我们会发现cpu从存储器中拿数据和外部设备导入到存储器这两个过程是可以同时进行的!!所以这是并型而不是串型!!大大提高了效率!!这也是内存存在的真正价值!!  1.2.3 有利于计算机的传播         通过计算机存储的金字塔结构,我们会发现越往下成本越低、容量越大、速度越慢,这是一个有舍有得的过程,那如果我一点也不差钱,那我是不是可以全部都用寄存器?不要内存也不要磁盘?也不需要遵守冯诺依曼体系?         答案其实是应该可以做到的!!如果你特别有钱,或许真的可以让别人给你定制一个只靠寄存器的计算机,但是这个计算机必然是造价特别贵的。老百姓是用不起的!!         其实我们是否会去使用这个计算机,一方面是考虑是否易操作、性能好,另一方面也要考虑成本!!所以冯诺依曼体系中为什么要有内存,也是因为我们不仅需要中央处理器,但是为了控制成本也不得不有硬盘,所以才需要有一个速度适中、容量也适中的存储器,这样可以在不降低太多性能的前提下降低成本,能够让老百姓去使用!!         通过此时的冯诺依曼体系结构,包括开源的Linux和git,我们会发现其实一样东西是否能够被快速传播,成本是十分重要的,价格太高是不利于传播的,其实现在市面上或许也会存在很多能够造福于百姓的创造,但是可能由于成本太高无法推广给普通老百姓,所以必然也是会沉没在历史的巨轮中。比如我们看过的一个电影叫《我不是药神》,其中抗癌正版药非常贵才会让老百姓不惜犯罪也要去吃盗版药。也是这个道理!!  1.3 实际应用 冯诺依曼体系中最为关键的就是内存!!我们可以很好地解释以下知识:  1、为什么一个程序要运行必须要先加载到内存中??  ——>这是由冯诺依曼体系决定的, 程序其实就是一个二进制文件,文件就是存储在磁盘(外部设备)中的,要去中央处理器那里才能运行,所以必须要先加载到内存中!!  2、我们之前写的进度条,如果不换行的话,数据会被存储到缓存中,那么缓存在哪??  ——>根据冯诺依曼体系结构,我们可以知道缓存其实就在内存中!!  3、如果我想把实验报告通过qq发送给我的好友,如何用冯诺依曼体系来分析整个数据流??   二、OS体系       每个硬件都有他对应的功能并且能够安装冯诺依曼体系去很好地工作,但是这是远远不够的,因为什么时候需要去执行什么功能是需要有人去调控的。        举个例子:假设你是一个国家的国王,这个国家里有擅长搞经济的,有擅长打仗的,有擅长谈判的,有擅长艺术的……当你想要听声乐,你会去叫搞艺术的人过来,当国家和平时期,你会重点培养搞经济的人,当外敌来犯,如果你想和解,你会叫擅长谈判的人来,你想打仗,你就会叫擅长打仗的人来…………所以这整个逻辑都是需要有人去调控的,在计算机中也是如此。      所以可能你的电脑中同时运行了qq、qq音乐、cctalk……那我什么时候该运行先哪个,运行qq的时候,凭什么不先运行qq音乐呢??所以我们需要有一个大脑一样的角色去管理他们——OS       OS是一款可以管理软硬件资源的软件,就像人可以管理人也可以管理机器一样!!  2.1 OS存在的意义(为什么)  2.1.1 给用户提供良好(稳定、高效、安全)的运行环境        无论我们上层是什么样的,最终的行为都是在硬件上体现的,软件想要操控硬件,就必然需要一些能够与硬件建立联系的驱动程序。比如说鼠标,当你刚把数据线接上的时候,从物理上你已经连接到你的电脑上了,但是你可能还需要等待几秒才真的可以去使用,因为驱动程序一开始还没有马上被加载出来——>驱动程序是我们和硬件打交道的软件(大部分是系统自带的)         OS是一个帮助我们管理软硬件资源的角色,但这仅仅只是他的手段罢了,他的目的是为了给用户提供一个良好(稳定、高效、安全)的运行环境,但我们要知道其实普通用户是不善于和OS打交道的,所以普通用户使用的都是基于程序员开发出来的软件,所以首先是我们专业的程序员需要去跟OS打交道,然后再搞出满足普通用户需求的各种软件!!       所以后面我们要探究的就是,程序员究竟如何和OS打交道呢??   2.1.2 OS其实不信任用户        OS里面有各种各样的数据,但是OS并不信任用户!!        首先我们要理解的是,不相信你和让你使用其实是不矛盾的,举个例子:银行允许任何用户进来,但是他其实并不相信所有的用户,因为用户当中可能会有坏人,所以银行为了保护自己需要封闭起来,但是不能完全封闭,因为这样就无法给老百姓提供服务了,所以他开放了一些小小的窗口,如果你普通用户想要取钱、借贷……只能通过这个小窗口来申请!!        同理,OS也觉得自己的数据太重要了,他担心坏人恶意攻击他,也担心小白随意篡改他,无论有意无意都有可能对他造成伤害,比如说一个磁盘可能有500G,但是有人给他改成了300G;你的网络本该是良好的,但是却被改成断开……所以OS也得像银行一样,把自己封闭起来,但是留一些小小的窗口出来(在计算机中称为接口)——>所以OS的设计者用C语言写了一些内部的函数方法开放给外部,我们把它称之为系统调用!           因为这些接口都是由设计者提供的,所以他的内部自然会存在一些方法能够检测你的行为是否非法,只有合法的行为才能访问他的数据。  ——>因此未来我们想跟OS打交道,只能通过系统调用来完成!!  ——>但是系统调用本身使用难度也很大,所以就需要程序员基于系统调用去设计一些上层的软件或者接口去供普通用户使用。  2.1.3 OS和计算机语言的区别 其实语言的本质就是:头文件+库文件+编译器=可执行程序  1、所以语言实际上是基于系统调用接口之上存在的!!但是语言之间也是有区别的,比如说java、python、虚拟机等底层是用C或C++写的,所以哪怕是我们常说C/C++是偏底层的语言,但他实际上也只是在系统调用之上而已。所以我们可以有一个很好的边界认识。  2、任何语言访问硬件都需要经过操作系统,所以我们会发现,语言可能会变,但是操作系统是不会变的,因为下层如果改变的,整个上层的逻辑都会崩盘,再牛逼的软件也必须遵守这套体系。我们常说的计算机发展很快其实都指的是上层,下层的变化是不大的。  2.2 OS的管理方法(怎么做) 2.2.1 如何管理 为了能够更好地去理解管理,我们举个生活中的例子:  问题1:在学校里,校长是我们公认的管理者,我们学生是公认的被管理者,可是我们大多数人却没有见过校长,但是校长依旧可以把我们所有人都管理得很好,这是为啥???          所以首先我们可以得到一个观点1:管理者和被管理者之间是不需要见面的!!     问题2:那么管理者在不见被管理者的情况,是如何做好管理的呢??          比如说学校需要选出几个人去参加数学竞赛,我只需要知道哪几个学生的数学水平比较高就可以了,如果学校想给前10名奖学金,只需要给成绩排个序取前10名就可以了。比如我作为一个老板,我知道一个员工一年拿下了特别多的项目为公司创造了特别多的利润,业绩排名第一,我在不见到他的情况下通过他的表现就可以做出给他升职加薪的决策,所以我们会发现,对于管理者来说,只要知道管理信息,就可以在未来进行管理决策。所以管理的本质是通过对数据的管理,达到对人的管理!即使是在小公司我们和管理者能够见面,管理者关注的也无非就是管理信息。  问题3:那管理者究竟是如何拿到数据的呢??         如果是在学校,大家可能会想到辅导员(充当执行者),在管理者和被管理者其实还夹杂着执行者,因为一件事情除了决策还需要有人去执行!比如说校长想知道哪些人能够有资格去参加程序设计比赛,然后他就可以喊辅导员过来,辅导员(执行者)和学生(被管理者)走的比较近相对比较了解,或许就可以通过辅导员拿到对应的信息。这确实是有一定道理,但是如果规模比较大的话,比如大学里面,一个辅导员手下就有几百号人,一个校长手下就有几千甚至上万人……他们同时面对这么多数据,肯定忙不过来啊!!所以通过人去拿数据,不是不行,但是能力比较有限。所以我们换个角度思考,我们不就是想要知道一些基本信息吗,而学生虽然各有特点,但都是相同的属性。比如说张三和李四的学院、专业、电话、年龄、籍贯、身高、体重、各科成绩、兴趣爱好…………直接把这些我们想要知道的信息管理起来,不就可以解决这个问题了吗。你第一时间可能会想到用个excel表格,这是大部分人能想到的,但是比方说人数特别多,然后你想在对应的信息里找到比方说前5个数学最好的学生,那你可能得花费很多时间用眼睛去扫描数据,也挺累的其实,其实我们作为程序员,还有更好的办法,就是用结构体管理起来。    我们每入学一个学生,就可以新建一个学生类型,而每毕业一个学生,就可以删除一个学生类型,但是学生不只有一个啊!!所以我们需要把它管理起来,而对数据进行管理,当然就是数据结构啦!!那我们就可以在每一个学生结构体里面加一个next指针,这样就可以把所有学生的信息都串起来变成一个链表了!!所以我们就把对学生的管理转变成了对链表的管理!!!        转变为链表的管理和相比用excel有什么好处呢?? ——>对链表的管理本质上就是对链表的增删改查,所以我们可以根据链表的特点去写很多我们需要的一些接口。比方说我想找到数学成绩最好的10个学生,那么直接写一个相关的接口,而后每次我们只要调用这个接口就可以完成这件事,就不需要在excel里面一个一个去看了!!  综上我们进行一下总结:  1、管理者和被管理者是不需要见面的  2、管理者只需要得到管理信息,就可以做出管理决策,所以管理的本质是通过对数据的管理从而实现对人的管理  3、管理者一方面可以通过执行者去拿到数据,另一方面可以通过将被管理者的一些信息用结构体描述出来,然后再用数据结构组织在一起,然后再通过该数据结构的特点实现相关需求的算法来拿到数据。          在计算机体系结构里,我们的OS就相当于管理者,我们的软硬件资源就相当于被管理者,而我们的驱动程序就相当于是执行者。   2.2.2 理解先描述再组织       在理解如何管理之后,我们发现了管理者通过描述出被管理者的结构体,然后再通过数据结构组织起来,然后再实现一些相关的算法去实现管理。所以就引申出了一个概念——先描述再组织         思考一下我们以前写的通讯录应该是怎么写呢??         首先我们的通讯录里面要有人,肯定要先把人给描述出来,比如说有名字、电话、年龄……然后我们再用通讯录把这些人的对象管理起来,然后基于这个通讯录去实现一些接口:比如删除联系人、增加联系人、查找联系人……   所以我们可以得到一个结论就是:其实未来我们无论开发任何软件,其实都是按照先描述再组织的形式去思考!!        再思考一下我们学习C++的正确顺序,首先我们先是学的类与对象,这是描述,而后我们学了内存、STL,其实就是在学习怎么进行组织………所以我们学习语言的顺序也是按照先描述再组织的思路去学的!!        另外再OS中,我们还可以知道:在OS中管理任何的对象最终都可以转化为对某种数据结构的增删查改!!  2.2.3 理解库文件vs系统调用        先举个例子,假如有A和B两个校长,A校长有一个学生数学特别厉害,但是B校长没有,于是B校长就想跟A校长商量借这个同学来打比赛,但是B校长肯定不能直接去找这个学生,因为这个学生是A校长的人,他得负责,所以他必须要通过A校长的同意才行。        同理我们通过printf把“hello”打在屏幕上,其实并不是我们直接通过调用这个库函数就和硬件打交道了,而是必须要自上而下贯穿下去,也就是要通过系统调用接口然后让OS知道!!!        所以我们知道了库函数必须通过系统调用接口才能找到OS,所以库函数和系统调用是上下层的关系,库函数是基于系统调用之上的二级开发!! ————————————————                              版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。                          原文链接:https://blog.csdn.net/weixin_51142926/article/details/140936732 
  • [技术干货] 测试Linux 中定时任务 crontab 的使用详解
    Linux 中定时任务 crontab 的使用详解在 Linux 系统中,crontab 是一个非常实用的工具,用于设置定时任务。它可以让我们在特定的时间自动执行命令、脚本或程序,极大地提高了工作效率和系统的自动化程度。本文将详细介绍 crontab 的使用方法,并包含代码示例。一、crontab 简介crontab 是一个用于在特定时间执行任务的工具,它基于 cron 守护进程运行。cron 守护进程会在系统启动时自动启动,并定期检查 crontab 文件中的任务列表,以确定是否需要执行某个任务。二、crontab 的基本语法crontab 的语法格式如下:* * * * * command_to_execute其中,五个星号分别代表分钟、小时、日、月、周几。command_to_execute 是要执行的命令或脚本。例如,以下 crontab 条目表示每分钟执行一次echo "Hello, world!"命令:* * * * * echo "Hello, world!"三、crontab 的时间表示法分钟(0-59)可以使用具体的分钟数,如15表示在 15 分钟时执行任务。也可以使用通配符*表示每分钟都执行任务。还可以使用范围表示法,如10-20表示在 10 到 20 分钟之间的每分钟都执行任务。可以使用步长表示法,如*/5表示每隔 5 分钟执行一次任务。小时(0-23)与分钟的表示法类似,可以使用具体的小时数、通配符、范围表示法和步长表示法。日(1-31)可以使用具体的日期,如15表示在每月的 15 日执行任务。也可以使用通配符*表示每天都执行任务。可以使用范围表示法,如10-20表示在每月的 10 到 20 日之间的每天都执行任务。可以使用步长表示法,如*/5表示每隔 5 天执行一次任务。月(1-12)可以使用具体的月份,如5表示在 5 月执行任务。也可以使用通配符*表示每月都执行任务。可以使用范围表示法,如5-8表示在 5 月到 8 月之间的每月都执行任务。可以使用步长表示法,如*/3表示每隔 3 个月执行一次任务。周几(0-6,0 表示周日)可以使用具体的周几,如3表示在周三执行任务。也可以使用通配符*表示每周都执行任务。可以使用范围表示法,如2-4表示在周二到周四之间的每周都执行任务。可以使用步长表示法,如*/2表示每隔 2 周执行一次任务。四、crontab 的使用步骤编辑 crontab 文件使用crontab -e命令编辑当前用户的 crontab 文件。如果是第一次编辑,系统可能会提示你选择一个文本编辑器。在打开的文件中,按照 crontab 的语法格式添加任务条目。保存并退出编辑完成后,保存文件并退出编辑器。cron 守护进程会自动读取新的 crontab 文件,并按照其中的任务条目执行任务。查看 crontab 任务列表使用crontab -l命令可以查看当前用户的 crontab 任务列表。删除 crontab 任务使用crontab -r命令可以删除当前用户的所有 crontab 任务。五、代码示例以下是一些 crontab 任务的代码示例:每天凌晨 2 点执行备份脚本0 2 * * * /path/to/backup_script.sh每周一到周五的上午 9 点执行清理日志文件的脚本0 9 * * 1-5 /path/to/clean_logs_script.sh每月 1 日和 15 日的下午 3 点执行数据库备份脚本0 15 1,15 * * /path/to/database_backup_script.sh每隔 10 分钟执行一次检查服务器状态的脚本*/10 * * * * /path/to/check_server_status_script.sh六、注意事项任务执行的环境变量crontab 任务执行时的环境变量可能与用户登录时的环境变量不同。如果任务需要特定的环境变量,可以在任务条目中设置环境变量,或者在脚本中显式地设置环境变量。任务执行的输出和错误处理默认情况下,crontab 任务的输出会通过邮件发送给用户。如果任务的输出较多或者不需要邮件通知,可以将输出重定向到文件或者/dev/null。如果任务执行出现错误,可以通过查看系统日志或者邮件来确定错误原因。任务的安全性确保任务执行的命令或脚本具有足够的权限,并且不会对系统造成安全风险。避免在 crontab 任务中使用敏感信息,如密码等。如果任务需要使用敏感信息,可以将敏感信息存储在安全的地方,并在任务执行时读取。总之,crontab 是一个非常强大的工具,可以帮助我们实现系统的自动化管理。通过合理地设置 crontab 任务,我们可以提高工作效率,减少人工干预,并且确保系统的稳定运行。希望本文对大家在使用 crontab 时有所帮助。
  • [生态空间] Linux 中定时任务 rsync 的使用指南
    Linux 中定时任务 rsync 的使用指南在 Linux 系统中,rsync是一个强大的文件同步工具,可以实现本地文件系统之间或者远程服务器之间的文件同步。结合定时任务,可以实现自动化的数据备份和同步操作。本文将详细介绍在 Linux 中如何使用定时任务来执行rsync,并包含具体的代码示例。一、rsync 简介rsync(Remote Sync)是一个开源的快速文件同步工具,它可以在不同的位置之间同步文件和目录,包括本地到本地、本地到远程、远程到本地。rsync具有以下特点:高效性:只传输文件中发生变化的部分,大大减少了数据传输量和同步时间。灵活性:可以通过多种方式进行配置,包括选择要同步的文件和目录、设置传输参数等。安全性:可以使用 SSH 等加密协议进行远程同步,确保数据传输的安全。二、安装 rsync在大多数 Linux 发行版中,rsync通常已经预装。如果你的系统中没有安装rsync,可以使用以下命令进行安装:对于 Debian/Ubuntu 系统:sudo apt-get install rsync对于 CentOS/Fedora 系统:sudo yum install rsync三、rsync 的基本用法本地文件同步rsync -av /source/directory /destination/directory其中,-a选项表示归档模式,保留文件的属性和权限;-v选项表示详细输出。远程文件同步使用rsync进行远程文件同步时,需要指定远程服务器的地址和路径。例如:rsync -av /source/directory user@remote_server:/destination/directory如果远程服务器需要密码验证,可以使用-e选项指定 SSH 连接,并在命令行中输入密码。例如:rsync -av -e "ssh -p port_number" /source/directory user@remote_server:/destination/directory四、使用定时任务执行 rsync创建 rsync 脚本首先,创建一个用于执行rsync的脚本文件,例如rsync_backup.sh:#!/bin/bash SOURCE_DIR="/source/directory" DEST_DIR="/destination/directory" rsync -av $SOURCE_DIR $DEST_DIR将SOURCE_DIR和DEST_DIR替换为实际的源目录和目标目录。设置脚本可执行权限chmod +x rsync_backup.sh使用 crontab 设置定时任务使用crontab -e命令编辑定时任务列表。在打开的文件中,添加以下行:0 2 * * * /path/to/rsync_backup.sh这表示每天凌晨 2 点执行rsync_backup.sh脚本。你可以根据实际需求调整定时任务的时间设置。例如,*/5 * * * * /path/to/rsync_backup.sh表示每 5 分钟执行一次脚本。五、代码解释脚本文件rsync_backup.sh这个脚本文件定义了源目录和目标目录,然后使用rsync命令进行文件同步。rsync的-av选项确保文件以归档模式进行同步,并输出详细信息。crontab 定时任务设置crontab的时间设置格式为:分钟 小时 日 月 周几 命令。在上面的例子中,0 2 * * *表示在每天凌晨 2 点执行指定的命令。六、注意事项权限问题在进行远程文件同步时,确保你有足够的权限访问源目录和目标目录。如果使用 SSH 连接,确保你的 SSH 密钥或密码正确配置。对于本地文件同步,确保脚本文件和目标目录具有适当的权限,以便rsync能够正常执行。网络连接如果进行远程文件同步,确保网络连接稳定。如果网络连接不稳定,可能会导致同步失败或数据丢失。测试和监控在设置定时任务之前,先手动执行脚本文件,确保rsync命令能够正常工作。定期检查同步结果,确保数据备份和同步的准确性。可以使用日志文件或其他监控工具来跟踪同步过程。
  • [技术干货] Linux 中 SELinux 的使用详解
    Linux 中 SELinux 的使用详解在 Linux 系统中,SELinux(Security-Enhanced Linux)是一种强制访问控制(MAC)安全系统,它为系统提供了更高级别的安全保障。本文将详细介绍 SELinux 的使用方法,包括其基本概念、配置和管理,以及一些常见的操作示例,并包含相关代码。一、SELinux 简介SELinux 是由美国国家安全局(NSA)开发的一个 Linux 内核安全模块,它通过对系统中的主体(如用户、进程)和客体(如文件、目录、端口等)进行强制访问控制,来增强系统的安全性。与传统的自主访问控制(DAC)不同,SELinux 不依赖于用户的主观判断,而是根据系统管理员定义的安全策略来决定主体对客体的访问权限。二、SELinux 的工作模式SELinux 有三种工作模式:Enforcing(强制模式):在这种模式下,SELinux 会严格按照安全策略进行访问控制,如果违反安全策略,访问将被拒绝。Permissive(宽容模式):在这种模式下,SELinux 会记录违反安全策略的访问行为,但不会拒绝访问。这种模式通常用于调试和测试。Disabled(禁用模式):在这种模式下,SELinux 被完全禁用,系统将恢复到传统的自主访问控制模式。三、SELinux 的配置文件SELinux 的主要配置文件是/etc/selinux/config,该文件包含了 SELinux 的工作模式、策略类型等配置选项。以下是一个典型的/etc/selinux/config文件的内容:# This file controls the state of SELinux on the system. # SELINUX= can take one of these three values: # enforcing - SELinux security policy is enforced. # permissive - SELinux prints warnings instead of enforcing. # disabled - No SELinux policy is loaded. SELINUX=enforcing # SELINUXTYPE= can take one of these two values: # targeted - Targeted processes are protected, # mls - Multi Level Security protection. SELINUXTYPE=targeted在这个配置文件中,SELINUX=enforcing表示将 SELinux 设置为强制模式,SELINUXTYPE=targeted表示使用目标策略类型,即只对特定的进程和服务进行安全控制。四、SELinux 的管理工具Linux 系统提供了一些工具来管理 SELinux,其中最常用的工具是sestatus和getenforce,它们可以用来查看 SELinux 的当前状态。以下是使用这两个工具的示例:# 查看 SELinux 的状态 sestatus # 查看 SELinux 的工作模式 getenforce如果要修改 SELinux 的工作模式,可以使用setenforce命令。例如,要将 SELinux 从强制模式切换到宽容模式,可以使用以下命令:setenforce 0要将 SELinux 从宽容模式切换到强制模式,可以使用以下命令:setenforce 1五、SELinux 的策略管理SELinux 的安全策略是由一系列规则组成的,这些规则定义了主体对客体的访问权限。Linux 系统提供了一些工具来管理 SELinux 的安全策略,其中最常用的工具是semanage和audit2allow。semanage工具semanage工具可以用来管理 SELinux 的各种策略对象,如用户、角色、类型、端口等。例如,要查看当前系统中所有的 SELinux 用户,可以使用以下命令:semanage login -l要为一个目录设置特定的 SELinux 类型,可以使用以下命令:semanage fcontext -a -t httpd_sys_content_t "/var/www/html(/.*)?"这个命令将/var/www/html目录及其子目录的 SELinux 类型设置为httpd_sys_content_t,以便 Apache 服务器能够正确访问这些目录。audit2allow工具audit2allow工具可以用来分析 SELinux 的审计日志,并生成相应的策略规则,以便允许特定的访问行为。例如,如果一个进程被 SELinux 拒绝访问某个文件,可以使用以下命令来分析审计日志并生成相应的策略规则:ausearch -m avc -ts recent | audit2allow -M mypolicy这个命令将分析最近的 SELinux 审计日志,并生成一个名为mypolicy的策略模块,该模块包含了允许被拒绝访问行为的策略规则。要加载这个策略模块,可以使用以下命令:semodule -i mypolicy.pp六、SELinux 的常见问题及解决方法在使用 SELinux 的过程中,可能会遇到一些问题,以下是一些常见问题及解决方法:应用程序无法访问文件或目录如果一个应用程序无法访问某个文件或目录,可能是因为 SELinux 阻止了该访问行为。可以使用sestatus和audit2allow工具来查看 SELinux 的状态和审计日志,并根据日志信息生成相应的策略规则,以允许应用程序访问文件或目录。SELinux 阻止网络服务的访问如果一个网络服务无法正常工作,可能是因为 SELinux 阻止了该服务的网络访问。可以使用semanage工具来查看和修改网络服务的 SELinux 策略,以允许该服务进行网络访问。SELinux 导致系统性能下降在某些情况下,SELinux 可能会导致系统性能下降,特别是在处理大量文件访问或网络连接时。可以通过调整 SELinux 的策略和参数,或者将 SELinux 切换到宽容模式或禁用模式,来提高系统性能。但是,在禁用 SELinux 之前,应该确保系统已经采取了其他足够的安全措施。七、总结SELinux 是一个强大的安全系统,它可以为 Linux 系统提供更高级别的安全保障。通过合理配置和管理 SELinux,可以有效地防止系统被恶意攻击和数据泄露。在使用 SELinux 的过程中,可能会遇到一些问题,但是通过使用适当的工具和方法,可以很容易地解决这些问题。希望本文对大家在使用 SELinux 时有所帮助。
  • [技术干货] 高手必知的Linux三剑客:grep、sed、awk
    高手必知的Linux三剑客:grep、sed、awk在Linux世界中,有三把强大的文本处理工具,它们被称为"三剑客":grep、sed和awk。这些工具是Linux系统管理员和开发者的必备技能,它们能够高效地处理文本数据,进行复杂的文本搜索、替换和报告生成等任务。1. grep:文本搜索的利剑grep是一个强大的文本搜索工具,它允许用户在文件中搜索包含特定模式的行。grep的名称来源于"Global Regular Expression Print",即全局正则表达式打印。1.1 基本用法grep 'pattern' filename这条命令会在filename文件中搜索包含pattern的所有行,并打印出来。1.2 常用选项-i:忽略大小写。-v:打印不匹配的行。-n:显示匹配行的行号。1.3 示例grep -i 'error' log.txt # 忽略大小写搜索包含"error"的行 grep -v 'error' log.txt # 打印不包含"error"的行 grep -n 'error' log.txt # 显示包含"error"的行及其行号2. sed:文本编辑的快刀sed(Stream Editor)是一个流编辑器,用于对文本数据进行过滤和替换。sed可以读取输入的文本行,然后根据指定的命令对这些行进行编辑。2.1 基本用法sed 's/old/new/' filename这条命令会在filename文件中将所有出现的old替换为new。2.2 常用选项-i:直接修改文件。-n:仅打印经过sed处理的行。2.3 示例sed -i 's/old/new/g' filename # 直接在文件中替换所有old为new sed -n '2,5p' filename # 打印文件的第2行到第5行3. awk:文本报告的神枪awk是一个强大的文本处理工具,特别适合于生成报告和处理列数据。awk的名称来源于其作者的姓氏:Aho、Weinberger和Kernighan。3.1 基本用法awk '条件 {动作}' filename这条命令会在filename文件中对满足条件的行执行动作。3.2 常用选项-F:设置输入字段的分隔符。-v:向awk脚本传递变量。3.3 示例awk -F, '{print $1}' data.csv # 以逗号为分隔符,打印第一列 awk -v var="value" '{print var}' # 使用外部变量4. 实战演练:三剑客的协同作战在实际工作中,我们经常需要将grep、sed和awk结合起来使用,以实现更复杂的文本处理任务。4.1 搜索并替换假设我们需要在日志文件中搜索包含特定错误的行,并将这些行中的日期格式从YYYY-MM-DD转换为DD/MM/YYYY。grep '特定错误' log.txt | sed 's/\([0-9]*\)-\([0-9]*\)-\([0-9]*\)/\3\/\2\/\1/'4.2 生成报告使用awk可以轻松生成基于文本文件的报告。例如,如果我们有一个包含员工信息的CSV文件,我们可以使用以下命令来生成一个按部门分组的员工名单:awk -F, 'NR>1 {print $1 " - " $2 " (" $3 ") " $4}' employees.csv这里NR>1确保标题行不被打印,-F,设置逗号为字段分隔符。5. 深入探索grep、sed和awk的功能远不止于此,它们都支持正则表达式,可以进行复杂的文本匹配和处理。此外,它们还可以通过管道(|)与其他命令结合使用,实现更强大的功能。6. 结语掌握grep、sed和awk的使用,对于任何需要处理文本数据的Linux用户来说都是极其重要的。它们不仅提高了工作效率,而且让你能够编写出简洁而强大的脚本。希望这篇博客能够帮助你更好地理解和使用Linux三剑客。
  • [技术干货] 60个常见的 Linux 指令-转载
    1.ssh 登录到计算机主机 ssh -p port username@hostname username: 远程计算机上的用户账户名。 hostname: 远程计算机的 IP 地址或主机名。  -p 选项指定端口号。  2.ls 列出目录内容 ls ls -l  # 显示详细列表 ls -a  # 显示包括隐藏文件在内的所有内容 3.pwd 当前终端会话所在的完整路径 pwd 4.cd 切换当前工作目录 cd [directory] cd .. #上一级目录 cd ~ #返回当前用户主目录 5.touch 创建空文件或更新文件的时间戳 touch [options] file 1 6.echo 终端输出文本或变量值 echo [options] [string...] echo "This is a new line" > newfile.txt #写入文件 echo "Another line" >> existingfile.txt #追加到文件 string:要输出的文本或变量。  7.nano 在终端中编辑文件 nano [options] [file] # 例如:创建或编辑文件 nano myfile.txt 8.vim 文本编辑器 普通模式(Normal Mode): 默认模式,用于浏览和执行命令。 插入模式(Insert Mode): 用于文本输入。 命令行模式(Command-Line Mode): 用于输入命令(如保存、退出等)。  vim filename.txt 9.cat 查看、连接和创建文件 cat filename.txt    #显示文件内容 cat file1.txt file2.txt    #连接多个文件并显示 cat file1.txt file2.txt > combined.txt    #将多个文件合并为一个文件 cat file1.txt >> existingfile.txt    #追加内容到文件末尾 cat -n filename.txt    #显示文件内容和行号 cat -v filename.txt    #显示不可打印字符 10.shred 安全删除敏感文件 shred [options] file... 1 -u:在删除文件后删除文件名,即在销毁文件内容后删除文件本身。 -v:显示详细信息,输出进度信息。 -n:指定覆盖文件内容的次数,默认是 3 次。 -z:在覆盖后用零填充文件,以进一步掩盖删除的痕迹。  11.mkdir 创建新目录 mkdir [options] directory... 1 -p:递归创建目录。如果上级目录不存在,mkdir 会自动创建它们。 -v:显示创建目录的详细信息。 -m:设置新目录的权限(模式),以八进制表示。  12.cp 复制文件和目录 cp [options] source destination source:要复制的源文件或目录。 destination:目标路径,可以是文件或目录。 -r, --recursive:递归复制,用于复制目录及其所有内容。 -i, --interactive:交互模式,如果目标文件已存在则提示是否覆盖。 -v, --verbose:显示详细信息,输出复制操作的详细信息。  13.rm 删除文件和目录 rm [options] file... 1 -r, --recursive:递归删除,用于删除目录及其所有内容。 -f, --force:强制删除,不提示错误信息,即使文件不存在也不会报错。 -i:交互式删除,在删除每个文件之前都会询问确认。 -v, --verbose:显示详细信息,输出删除操作的详细信息。 -d:删除空目录。  14.rmdir 删除空目录 rmdir [options] directory... -p:递归删除目录,即删除指定目录及其所有空的父目录。 -v, --verbose:显示详细信息,输出删除操作的详细信息。  15.ln 创建链接 ln [options] source [target] -s, --symbolic:创建符号链接。如果不使用此选项,将创建硬链接。 -f, --force:强制创建链接,覆盖已存在的文件或链接。 -i, --interactive:交互式创建链接,如果目标已存在则提示确认。  16.clear 清除终端屏幕 clear 1 17.whoami 显示当前的用户的用户名(确定当前用户身份) whoami id    #当前用户的详细信息,包括用户 ID (UID)、组 ID (GID) 以及所属组 who    #系统中所有当前登录的用户 18.useradd 创建新用户账户(系统管理员添加新用户) sudo useradd [options] username -m:创建用户的家目录(/home/username),如果家目录不存在时。 -d:指定用户的家目录路径。 -s:指定用户的默认 shell(如 /bin/bash)。 -g:指定用户的初始主组。 -G:指定用户所属的附加组(可以指定多个组,用逗号分隔)。 -e:设置用户账户的过期日期(格式为 YYYY-MM-DD)。 -p:指定用户的密码(通常是加密后的密码,明文密码不推荐)。 -c:添加用户的注释(如全名)。 -f:指定用户账户过期后的天数,-1 表示用户账户永不过期。  19.sudo 超级用户(root)权限执行命令 普通用户执行管理员权限的任务,而不需要直接登录root用户 使用 sudo 时通常需要输入用户密码,而不是 root 密码  sudo command [options] # 以超级用户权限安装软件(例如使用 apt-get) sudo apt-get update sudo apt-get install package_name 20.adduser 创建新用户账户 sudo adduser [options] username 1 在一些 Linux 发行版中,adduser 是 useradd 的一个友好封装,功能上类似但提供了更多的默认设置和提示。 --home:指定用户的家目录路径。 --shell:指定用户的默认 shell。 --gecos:添加用户的注释(如全名)。 --ingroup:指定用户的初始主组。 --disabled-password:创建用户时不设置密码。 --disabled-login:创建用户时禁用登录。  21.su 切换用户账户 su 是 “substitute user” 或 “switch user” 的缩写,它可以让你切换到另一个用户账户,包括 root 用户。  su [options] [username] su -    #切换到 root 用户并模拟登录 su -c 'ls /home/username' username    # username 用户身份执行 ls 命令列出 /home/username 目录的内容 22.exit 退出当前终端会话或shell exit [n] n(可选):退出状态码。如果指定了状态码,exit 将返回这个状态码。默认情况下,exit 返回上一个命令的退出状态码(通常为 0 表示成功,其他值表示错误)。  23.passwd 修改用户密码 在 Unix 和 Linux 系统中,你可以使用 passwd 命令来更改自己的密码或其他用户的密码(需要管理员权限)。  sudo passwd [options] [username] username(可选):要更改密码的用户。如果省略用户名,passwd 将修改当前用户的密码。 -d:删除用户密码,使用户无法使用密码登录(仅限 root 用户)。 -l:锁定用户账户,禁止用户使用密码登录。 -u:解锁用户账户,允许用户使用密码登录。 -e:强制用户在下次登录时更改密码(即将密码设置为过期状态)。 -i:设置密码过期时间,单位为天。若设置为 0,密码会立即过期。  24.apt 处理软件包的安装、升级、删除和管理 sudo apt update    #更新软件包列表 sudo apt upgrade    #升级已安装的软件包 sudo apt full-upgrade    #升级所有软件包并处理依赖关系 sudo apt install package_name    #安装软件包 sudo apt remove package_name    #卸载软件包 25.finger 显示用户信息 在 Unix 和 Linux 系统中,finger 可以用来查看用户的基本信息、登录状态以及其他与用户相关的细节。  finger [options] [username] finger $USER    #查看当前用户的信息-l:以详细模式显示用户信息。 -s:以简洁模式显示用户信息,只包括基本信息。  26.man 查看命令、函数、配置文件和其他程序文档 man 是 “manual” 的缩写,通过它你可以访问系统的手册页(manual pages),这些手册页提供了详细的使用说明和参考信息。  man [options] command man ls    #查看命令的手册页 1 2 -k:根据关键字搜索手册页。 -f:显示命令或函数的简要说明。 -a:显示所有匹配的手册页,而不仅仅是第一个。 -P pager:指定使用的分页程序。默认是 less,但你可以指定其他分页程序,例如 more。  27.whatis 显示命令或程序的简短描述 whatis 命令依赖于系统的手册页数据库,因此如果系统没有更新数据库,或者手册页没有被正确安装,whatis 可能无法提供描述。 你可以使用 mandb 命令来更新手册页数据库,以确保 whatis 命令能提供最新的描述。  whatis [options] command 1 28.curl 从命令行传输数据 curl 是一个用于从命令行传输数据的工具,支持多种协议,如 HTTP、HTTPS、FTP、SFTP 等。它通常用于下载或上传文件、测试 API、检索网页内容等任务。  curl [options] [URL] 1 -o:将输出保存到文件中。 -O:使用 URL 中的文件名保存文件。 -d:发送 POST 请求时使用的数据。 -H:添加 HTTP 请求头。 -i:显示响应头和响应体。 -I:仅显示响应头。 -L:跟踪重定向。 -x:使用代理服务器。  29.zip 创建和管理压缩文件 zip [options] zipfile files 1 -r:递归压缩目录及其子目录和文件。 -e:为压缩文件添加密码保护。 -u:更新压缩文件,添加新文件或更新已存在的文件。 -d:从压缩文件中删除指定的文件。 -l:列出压缩文件中的内容。 -T:测试压缩文件的完整性。  30.unzip 解压缩zip文件 unzip [options] zipfile 1 -d:指定解压缩到的目标目录。 -l:列出 .zip 文件中的内容。 -t:测试 .zip 文件的完整性。 -u:更新目标文件,仅在目标文件比 .zip 文件中的文件旧时更新。 -o:覆盖现有文件而不提示。  31.less 查看文本文件 less 是一个用于查看文本文件的分页工具,可以逐页或逐行浏览文件内容。它比 more 命令功能更强大,支持在文件中向前和向后滚动、搜索和其他导航功能。  less [options] file 1 -N:显示行号。 -S:禁用自动换行,水平滚动显示长行。 -F:如果内容能在一屏内显示,则自动退出 less。 -X:禁用终端的显示控制(例如颜色),在使用管道时很有用。  32.head 显示文件的开头部分 head用于查看文件的前几行内容  head [options] file head -n 15 file.txt    #查看 file.txt 的前 15 行 1 2 33.tail 显示文件尾部的部分 tail用于查看文件的前几行内容,特别是在查看日志文件时非常有用。  tail [options] file tail -n 15 filename.txt    #指定显示的行数 tail -f filename.txt    #实时查看文件的新增内容(跟随模式) 1 2 3 33.cmp 比较两个文件内容 cmp逐字节比较文件内容,并报告文件之间的第一个不同之处。如果文件相同,则没有输出;如果不同,则输出第一个不同字节的位置和它们的不同内容。  cmp [options] file1 file2 1 file1:第一个要比较的文件。file2:第二个要比较的文件。 -l:显示所有不同字节的位置和它们的不同内容。 -i:忽略文件末尾的空白字符。 -b:显示所有不同字节的位置和它们的不同内容,以十进制显示。 -s:静默模式,不输出任何内容,仅返回退出状态码。0 表示文件相同,1 表示文件不同。 -i:指定从哪个字节开始比较。  34.diff 比较文件内容并显示差异 diff可以显示两个文件之间的不同之处,通常用于文件版本控制和差异分析。  diff [options] file1 file2 1 file1:第一个要比较的文件。file2:第二个要比较的文件。 -u:以统一格式显示差异。 -c:以上下文格式显示差异。 -q:简洁模式,仅指示文件是否不同。 -r:递归比较目录及其内容。 -w:忽略空白字符的差异。 -i:忽略大小写的差异。 -b:忽略行尾的空白字符差异。 ————————————————                              版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。                          原文链接:https://blog.csdn.net/qq_51870267/article/details/140690986 
  • [技术干货] 【Linux】Linux背景历史-转载
    Linux背景 Linux是什么? Linux(Linux Is Not UniX),一般指GNU/Linux,是一种免费使用和自由传播的类UNIX操作系统,其内核由林纳斯·本纳第克特·托瓦兹(Linus Benedict Torvalds)于1991年10月5日首次发布,它主要受到Minix和Unix思想的启发,是一个基于POSIX的多用户、多任务、支持多线程和多CPU的操作系统。  计算机的发展 计算机的发展是随着时代的更替所必须出现的一个产物,1946年2月14日埃尼阿克发明了世界上第一台计算机。在二十世纪五十年代这个时间点,刚刚结束第二次世界大战,进入美苏冷战的是一段对美国和苏联都至关重要的时期,俩个超级大国都极力追求技术突破。而计算机刚刚出现时,并不是让普通平民使用的,而是专属于国家及政府,主要用于军事用途,计算导弹的弹道轨迹。  埃尼阿克1946年2月14日发明第一台计算机 美苏冷战 技术突破 主要用于军事用途 计算导弹的弹道轨迹 摩尔定律:摩尔定律是英特尔创始人之一戈登·摩尔的经验之谈,其核心内容为:集成电路上可以容纳的晶体管数目在大约每经过18个月到24个月便会增加一倍。换言之,处理器的性能大约每两年翻一倍,同时价格下降为之前的一半。 摩尔定律是内行人摩尔的经验之谈,汉译名为“定律”,但并非自然科学定律,它一定程度揭示了信息技术进步的速度。  推动 摩尔定律 计算机小型化 技术突破 政府和军方想要继续提高实力,就需要继续推动技术进步,为此就必须向研究机构和部分实例雄厚的高效提供资源。  政府和军方 资源 研究机构 高校 产生新的技术后,就可以进行可持续的一个发展,技术人员通过出售自己的技术产权,再通过美国进入行业的兴起(华尔街),通过商人之手,最后就可以孵化出来一批产品:计算机的优化,操作系统等等。  新技术 计算机和操作系统 资源 商人 这样的可持续发展可以给普通群众带来一些伟大的产品,不错的公司以及个人商业人物。同时,可以可持续的发展使得产品逐渐扩大并卖向全球,产生大量相关行业的公司,国家政府通过企业税收、个人税收进行资金回流,如此,形成一个可持续发展的闭环。  unix发展史 1968年,一些来自通用电器公司、贝尔实验室和麻省理工学院的研究人员开发了一个名叫Multics的特殊操作系统。Multics在多任务文件管理和用户连接中综合了许多新概念。 1969-1970年,AT&T的贝尔实验室研究人员Ken Tompson和Dennis Ritchie,在采用很多Multics特点的基础上开发了UINX系统。它运行在小型机上,满足了系统对科研环境的要求。从产生开始,UNIX就是一个有价值的、高效的、多用户和多任务的操作系统。 UNIX从满足个人的设计需求开始,逐步成长为由许多不同开发商所支持的标准软件产品。 第一个UNIX版本是免费给许多知名大学的计算机系使用的。 1972年,贝尔实验室开始发放商业版本,并且给不同的用户授权使用这个系统,使用者之一是加州大学伯克莱分校的计算机系。伯克莱给系统增加了许多新的特点,后来成为了标准。 1975年伯克莱由下属部门BSD发行了自己的UNIX版本。UNIX的BSD版本成为AT&T贝尔实验室版本的主要竞争者,而其它的独立开发出的UNIX版本也开始萌生。 1980年微软公司开发了叫做Xenix的UNIX PC版本。AT&T发行了第一个商业版本。名叫System Ⅲ,后来被成为对商用软件产品良好支持的System Ⅴ所替代。 同时UNIX的BSD版本不断发展,在70年代末期,BSD UNIX成为了国防部的高科技研究机构科研项目的基础。其结果,伯克莱发行了一个叫做BSD Release 4.2的有效版本。 它包括了高级的文件管理器和基于TCP/IP网络协议的网络特点。现在TCP/IP被Internet所使用。BSD Release 4.2被许多厂商所采用,例如SUN Microsystem。 UNIX不同版本的出现导致了UNIX标准的需要,软件开发商不知道他们的程序运行在哪些版本上比较合适。 到80年代中期,两个竞争的标准出现了,一个是基于AT&T的UNIX版本,另一个是BSD版本。在今天的书店里你能发现分别适用于这两个版本的不同的UNIX的书,一些是System V,另一些集中在BSD UNIX。 AT&T建立了一个叫UNIX系统实验室的新组织,它的作用就是综合UNIX的不同版本,集中开发一个标准系统. 1991年,UNIX综合实验室综合了System V Release3,SUN OS和Xenix的所有特点,发行了System V Release 4。为了与System V Release 4 竞争,一些其它公司,如IBM和惠普Open Software Foundation(OSF)去产生自己的UNIX标准版本,继而出现了两个标准商业版本OSF版本和System Release 4. 1993年,AT&T把它的UNIX转卖给Novell公司。UNIX系统实验室成为了Novell的UNIX系统小组的一部分。Novell发行了基于System V Release 4的自己的UNIX版本UNIXWare,它可以和Novell公司的Netware系统相联。SUN公司已经把System V Release 4 融进了它的SUN OS,发行Solaris。两个相互竞争的UNIX使用的图形用户界面(一个叫Motif,另一个叫Openlook),已经合并为一个新的工作平台标准,叫做通用平台环境(CDE)。 Linux发展史 1991年10月5日,赫尔辛基大学的一名研究生Linus Benedict Torvalds在一个Usenet新闻组(comp.os.minix)中宣布他编制出了一种类似UNIX的小操作系统,叫Linux。新的操作系统是受到另一个UNIX的小操作系统——Minix的启发,该系统是由一名叫Andrew S Tanenbaum的教师开发的。读者也许猜想所发布的这个系统应该是Linux的0.01版本,实际上不是这样。真正的Linux 0.01版本并没有被发布,原因是0.01版本不实用。Linus仅仅在第一个Linux的FTP站点(ftp://nic.funet.fi)上提供过这个版本的的源代码。 Torvalds于10月5日发布的这个Linux版本被称为0.02版,它能够运行GNU Bourne Again Shell(bash)和GNU的C编译程序(gcc)以及为数不多的其它语言。Torvalds绝对没有想到他设想的一种能够针对高级业余爱好者和黑客们的操作系统已经产生,这就是人们所称的Linux。 Linux发布时的版本是0.02,后来又有0.03版,然后又跳到0.10版。因为世界各地越来越多的程序员都开始开发Linux,它已经达到0.95版。这就意味着正是公布1.0版本的时间已经为期不远了。正式的1.0版本是在1994年公布的。 伴随着计算机的发展,IBM公司是一个主要开发计算机硬件的互联网公司,IBM公司使用unix操作系统,但是起初unix是不被开源的,即是只限于企业、高校和研究机构使用的,而当时的IBM公司产生了一个名为ThinkPad的电脑。 而像微软公司在当时主要是一个开发计算机软件的公司。 当时出现了一家厂商,他们自己开发硬件和属于自己的软件,对其他计算机厂商产生巨大的影响,这家公司就是苹果公司,苹果公司在当时的影响极大,其自身产品引得许多人的购买,其产品质量非常高,价格也比较高。 苹果的崛起对微软的打击是极大的,对于微软这个只是做软件的公司来讲是及其危险的,于是微软和IBM公司先是联合起来开始着手自己的计算机系统,但是后面由于种种原因合作失败。于是微软又和因特尔公司合作,同时也和其他计算机厂商进行合作,产生了windows系统,由于合作厂商较多,导致成本就比较低,所以微软的产品主要是性价比比较高。  现在主流的电脑就是苹果的ios系统和微软的Windows系统,而Linux的使用场景主要是现阶段的Android系统的手机,手机的操作系统还有苹果的ios系统,华为的鸿蒙系统。 VS Windows的发展史。 开源 Linux是一种自由和开放源代码的类UNIX操作系统,该操作系统的内核由林纳斯托瓦兹在1991年首次发布,之后,在加上用户空间的应用程序之后,就成为了Linux操作系统。严格来讲,Linux只是操作系统内核本身,但通常采用“Linux内核”来表达该意思。而Linux则常用来指基于Linux内核的完整操作系统,它包括GUI组件和许多其他实用工具。 GNU通用公共许可协议(GNU General Public License,简称GNU GPL或GPL),是一个广泛被使用的自由软件许可协议条款,最初由理查德斯托曼为GNU计划而撰写,GPL给予了计算机程序自由软件的定义,任何基于GPL软件开发衍生的产品在发布时必须采用GPL许可证方式,且必须公开源代码。 Linux是自由软件和开放源代码软件发展中最著名的例子。只要遵循GNU通用公共许可证,任何个人和机构都可以自由地使用Linux的所有底层源代码,也可以自由地修改和再发布。随着Linux操作系统飞速发展,各种集成在Linux上的开源软件和实用工具也得到了应用和普及,因此,Linux也成为了开源软件的代名词。 像之前提到过的一样,不仅仅电脑需要操作系统,手机也需要操作系统,互联网公司也需要选择自己的后端操作系统,对于手机而言,操作系统是需要好用、快速、安全以及稳定的;对于互联网公司来讲,其后端操作系统是需要稳定、安全、快速以及成本低廉。  那么一般公司会选择代码开源的操作系统质量会更好(稳定、安全、快速)呢?还是闭源质量会更好呢?  相信历史以及提供了答案,大部分互联网公司会选择像linus这样代码开源的操作系统,由于Linux操作系统的开源,导致了很多专业工程师和世界顶级黑客对其代码的纠正补充,现在Linux开源代码中的代码量以及达到千万级别。  所以Linux的主要特征是:1.开源——大部分是免费的,稳定、安全、高效;2.更多的被专业的人所使用。  Linux官网以及版本更替 Linux现阶段主要有俩个版本: 1.商业化版本: Debian:Debian运行起来极其稳定,这使得它非常适合用于服务器。 debian这款操作系统无疑并不适合新手用户,而是适合系统管理员和高级用户。 Ubuntu :Ubuntu是Debian的一款衍生版,也是当今最受欢迎的免费操作系统。Ubuntu侧重于它在这个市场的应用,在服务器、云计算、甚至一些运行Ubuntu Linux的移动设备上很常见。Ubuntu是新手用户肯定爱不释手的一款操作系统。 红帽企业级Linux :这是第一款面向商业市场的Linux发行版。它有服务器版本,支持众多处理器架构,包括x86和x86_64。红帽公司通过课程红帽认证系统管理员/红帽认证工程师(RHCSA/RHCE),对系统管理员进行培训和认证。 CentOS :CentOS是一款企业级Linux发行版,它使用红帽企业级Linux中的免费源代码重新构建而成。这款重构版完全去掉了注册商标以及Binary程序包方面一个非常细微的变化。有些人不想支付一大笔钱,又能领略红帽企业级Linux;对他们来说,CentOS值得一试。此外,CentOS的外观和行为似乎与母发行版红帽企业级Linux如出一辙。 CentOS使用YUM来管理软件包。 Fedora :小巧的Fedora适合那些人:想尝试最先进的技术,等不及程序的稳定版出来。其实,Fedora就是红帽公司的一个测试平台;产品在成为企业级发行版之前,在该平台上进行开发和测试。Fedora是一款非常好的发行版,有庞大的用户论坛,软件库中还有为数不少的软件包。 Kali Linux :Kali Linux是Debian的一款衍生版。Kali旨在用于渗透测试。Kali的前身是Backtrack。用于Debian的所有Binary软件包都可以安装到Kali Linux上,而Kali的魅力或威力就来自于此。此外,支持Debian的用户论坛为Kali加分不少。Kali随带许多的渗透测试工具,无论是Wifi、数据库还是其他任何工具,都设计成立马可以使用。Kali使用APT来管理软件包。 另外一种版本是技术版本:主要被称为Linux的内核、源代码。  源代码官网:链接: link     Linux企业应用现状 Linux在服务器领域的发展 随着开源软件在世界范围内影响力日益增强,Linux服务器操作系统在整个服务器操作系统市场格局中占据了越来越多的市场份额,已经形成了大规模市场应用的局面。并且保持着快速的增长率。尤其在政府、金融、农业、交通、电信等国家关键领域。此外,考虑到Linux的快速成长性以及国家相关政策的扶持力度,Linux服务器产品一定能够冲击更大的服务器市场。 据权威部门统计,目前Linux在服务器领域已经占据75%的市场份额,同时,Linux在服务器市场的迅速崛起,已经引起全球IT产业的高度关注,并以强劲的势头成为服务器操作系统领域中的中坚力量。  Linux在桌面领域的发展 近年来,特别在国内市场,Linux桌面操作系统的发展趋势非常迅猛。国内如中标麒麟Linux、红旗Linux、深度Linux等系统软件厂商都推出的Linux桌面操作系统,目前已经在政府、企业、OEM等领域得到了广泛应用。另外SUSE、Ubuntu也相继推出了基于Linux的桌面系统,特别是Ubuntu Linux,已经积累了大量社区用户。但是,从系统的整体功能、性能来看,Linux桌面系统与Windows系列相比还有一定的差距,主要表现在系统易用性、系统管理、软硬件兼容性、软件的丰富程度等方面。  Linux在移动嵌入式领域的发展 Linux的低成本、强大的定制功能以及良好的移植性能,使得Linux在嵌入式系统方面也得到广泛应用,目前Linux以广泛应用于手机、平板电脑、路由器、电视和电子游戏机等领域。在移动设备上广泛使用的Android操作系统就是创建在Linux内核之上的。目前,Android已经成为全球最流行的智能手机操作系统,据2015年权威部门最新统计,Android操作系统的全球市场份额已达84.6%。 此外,思科在网络防火墙和路由器也使用了定制的Linux,阿里云也开发了一套基于Linux的操作系统“YunOS”,可用于智能手机、平板电脑和网络电视;常见的数字视频录像机、舞台灯光控制系统等都在逐渐采用定制版本的Linux来实现,而这一切均归功与Linux与开源的力量。  Linux在云计算/大数据领域的发展 互联网产业的迅猛发展,促使云计算、大数据产业的形成并快速发展,云计算、大数据作为一个基于开源软件的平台,Linux占据了核心优势;据Linux基金会的研究,86%的企业已经使用Linux操作系统进行云计算、大数据平台的构建,目前,Linux已开始取代Unix成为最受青睐的云计算、大数据平台操作系统。  Linux环境的安装 1.裸机安装或者双系统——不推荐 2.虚拟机安装——不推荐 3.云服务器——安装简单,维护成本低,未来学习效果好。  云服务器推荐:阿里云官网,腾讯云官网,华为云官网。 ————————————————                              版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。                          原文链接:https://blog.csdn.net/dab112/article/details/140348766 
总条数:1199 到第
上滑加载中