精华内容
下载资源
问答
  • 嵌入式linux应用程序开发详解

    千次阅读 2017-06-06 22:16:23
    在这里存放前面 Linux 常用操作命令的执行文件,如 mv、ls、mkdir 等。有时,这个目录的内容和/usr/bin 里面的内容一样,它们都是放置一般用户使用的执行文件  /boot 这个目录下存放操作系统启动时所要用到...
    1. /bin            bin 就是二进制(binary)英文缩写。在这里存放前面 Linux 常用操作命令的执行文件,如 mv、ls、mkdir 等。有时,这个目录的内容和/usr/bin 里面的内容一样,它们都是放置一般用户使用的执行文件  
    2. /boot   这个目录下存放操作系统启动时所要用到的程序。如启动 grub 就会用到其下的/boot/grub子目录  
    3. /dev            该目录中包含了所有 Linux 系统中使用的外部设备。要注意的是,这里并不是存放的外部设备的驱动程序,它实际上是一个访问这些外部设备的端口。由于在 Linux 中,所有的设备都当作文件一样进行操作,比如:/dev/cdrom 代表光驱,用户可以非常方便地像访问文件、目录一样对其进行访问  
    4. /etc            该目录下存放了系统管理时要用到的各种配置文件和子目录。如网络配置文件、文件系统、x 系统配置文件、设备配置信息设置用户信息等都在这个目录下。系统在启动过程中需要读取其参数进行相应的配置  
    5. /etc/rc.d       该目录主要存放 Linux 启动和关闭时要用到的脚本文件,在后面的启动详解中还会进一步地讲解  
    6. /etc/rc.d/init  该目录存放所有 Linux 服务默认的启动脚本(在新版本的 Linux 中还用到的是/etc/xinetd.d目录下的内容)  
    7. /home           该目录是 Linux 系统中默认的用户工作根目录。执行 adduser命令后系统会在/home 目录下为对应账号建立一个名为同名的主目录  
    8. /lib            该目录是用来存放系统动态链接共享库的。几乎所有的应用程序都会用到这个目录下的共享库。因此,千万不要轻易对这个目录进行什么操作  
    9. /lost+found     该目录在大多数情况下都是空的。只有当系统产生异常时,会将一些遗失的片段放在此目录下  
    10. /media          该目录下是光驱和软驱的挂载点,Fedora Core 4 已经可以自动挂载光驱和软驱  
    11. /misc           该目录下存放从 DOS 下进行安装的实用工具,一般为空  
    12. /mnt            该目录是软驱、光驱、硬盘的挂载点,也可以临时将别的文件系统挂载到此目录下  
    13. /proc           该目录是用于放置系统核心与执行程序所需的一些信息。而这些信息是在内存中由系统产生的,故不占用硬盘空间  
    14. /root           该目录是超级用户登录时的主目录  
    15. /sbin           该目录是用来存放系统管理员的常用的系统管理程序  
    16. /tmp            该目录用来存放不同程序执行时产生的临时文件。一般 Linux 安装软件的默认安装路径就是这里  
    17. /usr            这是一个非常重要的目录,用户的很多应用程序和文件都存放在这个目录下,类似与Windows 下的 Program Files 的目录  
    18. /usr/bin        系统用户使用的应用程序  
    19. /usr/sbin       超级用户使用的比较高级的管理程序和系统守护程序  
    20. /usr/src        内核源代码默认的放置目录  
    21. /srv            该目录存放一些服务启动之后需要提取的数据  
    22. /sys            这是 Linux 2.6 内核的一个很大的变化。该目录下安装了 2.6 内核中新出现的一个文件系统 sysfs,sysfs 文件系统集成了下面 3 种文件系统的信息:针对进程信息的 proc 文件系统、针对设备的 devfs 文件系统以及针对伪终端的 devpts 文件系统。该文件系统是内核设备树的一个直观反映。当一个内核对象被创建的时候,对应的文件和目录也在内核对象子系统中被创建  
    23. /var            这也是一个非常重要的目录,很多服务的日志信息都存放在这里  

    【linux基础命令】


    root用户切换:
        $:' sudo passwd
        // 输入当前登陆密码,再根据提示输入设置的UNIX密码2遍,即为root用户切换密码
        $:' su
        // 输入UNIX密码,切换为root用户,提示符变为 #

    设置环境变量方法如下:
    1. 通过 etho 显示字符串(指定环境变量)。
    2. 通过 export 设置新的环境变量。
    3. 通过 env 显示所有环境变量。
    4. 通过 set 命令显示所有本地定义的 Shell 变量。
    5. 通过 unset 命令来清除环境变量。

    Linux常见用户管理命令:
    1. useradd         添加用户账号                        useradd [选项] 用户名  
    2. usermod         设置用户账号属性                    usermod [选项] 属性值  
    3. userdel         删除对应用户账号                    userdel [选项] 用户名  
    4. groupadd        添加组账号                          groupadd [选项] 组账号  
    5. groupmod        设置组账号属性                      groupmod [选项] 属性值  
    6. groupdel        删除对应组账号                      groupdel [选项] 组账号  
    7. passwd          设置账号密码                        passwd [对应账号]  
    8. id              显示用户ID、组ID和用户所属组列表    id [用户名]  
    9. groups          显示用户所属的组                    groups [组账号]  
    10. who             显示登录到系统的所有用户            who  
    11. whoami          显示当前用户名                      whoami  

    Linux常见系统管理命令:
    1. ps              显示当前系统中由该用户运行的进程列表        ps [选项]  
    2. top             动态显示系统中运行的程序(一般为每隔 5s)   top  
    3. kill            输出特定的信号给指定 PID(进程号)的进程    kill [选项] 进程号(PID)  
    4. uname           显示系统的信息(可加选项-a)                uname [选项]  
    5. setup           系统图形化界面配置                          setup  
    6. crontab         循环执行例行性命令                          crontab [选项]  
    7. shutdown        关闭或重启 Linux 系统                       shutdown [选项] [时间]  
    8. uptime          显示系统已经运行了多长时间                  uptime  
    9. clear           清除屏幕上的信息(ctrl + l)                  clear  

    Linux常见磁盘管理命令:
    1. free            查看当前系统内存的使用情况                  free [选项]  
    2. df              查看文件系统的磁盘空间占用情况              df [选项]  
    3. du              统计目录(或文件)所占磁盘空间的大小        du [选项]  
    4. fdisk           查看硬盘分区情况及对硬盘进行分区管理        fdisk [-l]  
    5. mount           磁盘挂载命令                                mount -t [选项] [文件系统类型] 设备文件名 挂载点目录  

    mount挂载举例:
        $:' mount -t vfat/dev/hda1 /mnt/c
        $:' umount /mnt/c
    · 在 Linux 下如何使用 U 盘呢?
    一般 U 盘为 SCSI 格式的硬盘,其格式为 vfat 格式,其设备号可通过“fdisk –l”进行查看,假若设备名为“/dev/sda1”,则可用如下命令就可将其挂载:
        $:' mount -t vfat /dev/sda1 /mnt/u
    · 若想设置在开机时自动挂载,可在文件“/etc/fstab”中加入该命令到一个新行即可。

    正则表达式的主要参数有:
    · \:忽略正则表达式中特殊字符的原有含义;
    · ^:匹配正则表达式的开始行;
    · $:匹配正则表达式的结束行;
    · <:从匹配正则表达式的行开始;
    · >:到匹配正则表达式的行结束;
    · [ ]:单个字符,如[A]即 A 符合要求;
    · [-]:范围,如[A-Z],即 A、B、C 一直到 Z 都符合要求;
    · 。:所有的单个字符;
    · *:所有字符,长度可以为 0。

    ln 的链接又软链接和硬链接两种:
    软链接就是上面所说的 ln -s ** **,它只会在用户选定的位置上生成一个文件的镜像,不会重复占用磁盘空间,平时使用较多的都是软链接;
    硬链接是不带参数的 ln ** **,它会在用户选定的位置上生成一个和源文件大小相同的文件,无论是软链接还是硬链接,文件都保持同步变化。

    Linux常见压缩打包相关命令:
    1. bzip2           .bz2 文件的压缩(或解压)程序           bzip2[选项] 压缩(解压缩)的文件名  
    2. bunzip2         .bz2 文件的解压缩程序                   bunzip2[选项] .bz2 压缩文件  
    3. bzip2recover    用来修复损坏的.bz2 文件                 bzip2recover .bz2 压缩文件  
    4. gzip            .gz 文件的压缩程序                      gzip [选项] 压缩(解压缩)的文件名  
    5. gunzip          解压被 gzip 压缩过的文件                gunzip [选项] .gz 文件名  
    6. unzip           解压 winzip 压缩的.zip 文件             unzip [选项] .zip 压缩文件  
    7. compress        早期的压缩或解压程序(压缩后文件名为.Z)  compress [选项] 文件  
    8. tar             对文件目录进行打包或解包                tar [选项] [打包后文件名]文件目录列表  

    Linux比较和合并文件命令:
    1. diff            比较两个不同的文件或不同目录下的两个同名文件功能,并生成补丁文件        diff[选项] 文件1 文件2  
    2.     $:' diff hello1.c hello2.c > hello.patch  
    3. patch           把生成的补丁文件应用到现有代码上            patch [选项] [待 patch 的文件[patch 文件]]  
    4.     $:' patch ./hello1.c < hello1.patch  

    Linux常见网络相关命令:
    1. netstat         显示网络连接、路由表和网络接口信息      netstat [-an]  
    2. nslookup        查询一台机器的 IP 地址和其对应的域名    nslookup [IP 地址/域名]  
    3. finger          查询用户的信息                          finger [选项] [使用者] [用户@主机]  
    4. ping            用于查看网络上的主机是否在工作          ping [选项] 主机名/IP 地址  
    5. ifconfig        查看和配置网络接口的参数                ifconfig [选项] [网络接口]  
    6. ftp             利用 ftp 协议上传和下载文件             ftp [选项] [主机名/IP]  
    7. telnet          利用 telnet 协议浏览信息                telent [选项] [IP 地址/域名]  
    8. ssh             利用 ssh 登录对方主机                   ssh [选项] [IP 地址]  


    定制linux系统服务流程步骤:
    (1)查看系统的默认运行级别。
        $:' cat /etc/inittab(设其结果为 N)
    (2)进入到相应级别的服务脚本目录,查看哪些服务是系统启动的独立运行的服务,并做下记录。
        $:' cd /etc/rc.d/rcN.d
    (3)利用命令查看系统开机自启动服务,并与上次查看结果进行比较,找出其中的区别,并思考其中的原因。
        $:' chkconfig –list
    (4)记录 chkconfig –list 命令中由 xinet 管理的服务,并将其中启动的服务做下记录。
    (5)进入 xinet 配置管理的相应目录,查看是否于 chkconfig –list 所得结果相吻合并查看相应脚本文件。
        $:' cd /etc/xinetd.d
    (6)将 sshd 服务停止。
        $:' service sshd stop
    (7)将 sshd 服务设置为开机不启动。
        $:' chkconfig –level N sshd stop
    (8)查看该设置是否生效。
        $:' chkconfig –list
    (9)查看系统中所有服务及其端口号列表。
        $:' cat /etc/services
    (10)将 sshd 服务端口改为 4022。
        $:' vi /etc/services;转到插入模式并修改其端口号
    (11)重启 sshd 服务,验证所改的端口号是否生效。
        $:' service sshd start
    (12)重启 Linux 系统,验证所改的服务开机启动是否生效。

    【linux下的C编程】


    编辑器:vim
    编译器:gcc
    调试器:gdb
    make工程管理器:Makefile

    Makefile常见预定义变量:
    1. AR          库文件维护程序的名称,默认值为 ar  
    2. AS          汇编程序的名称,默认值为 as  
    3. CC          C 编译器的名称,默认值为 cc  
    4. CPP         C 预编译器的名称,默认值为$(CC) –E  
    5. CXX         C++编译器的名称,默认值为 g++  
    6. FC          FORTRAN 编译器的名称,默认值为 f77  
    7. RM          文件删除程序的名称,默认值为 rm –f  
    8. ARFLAGS     库文件维护程序的选项,无默认值  
    9. ASFLAGS     汇编程序的选项,无默认值  
    10. CFLAGS      C 编译器的选项,无默认值  
    11. CPPFLAGS    C 预编译的选项,无默认值  
    12. CXXFLAGS    C++编译器的选项,无默认值  
    13. FFLAGS      FORTRAN 编译器的选项,无默认值  

    Makefile自动变量:
    $*      不包含扩展名的目标文件名称
    $+      所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件
    $<      第一个依赖文件的名称
    $?      所有时间戳比目标文件晚的依赖文件,并以空格分开
    $@      目标文件的完整名称
    $^      所有不重复的依赖文件,以空格分开
    $%      如果目标是归档成员,则该变量表示目标的归档成员名称

    Makefile 中常见隐式规则:
    C 编译:.c 变为.o $(CC) –c $(CPPFLAGS) $(CFLAGS)
    C++编译:.cc 或.C 变为.o $(CXX) -c $(CPPFLAGS) $(CXXFLAGS)
    Pascal 编译:.p 变为.o $(PC) -c $(PFLAGS)
    Fortran 编译:.r 变为-o $(FC) -c $(FFLAGS)

    autotools自动生成Makefile:
    首先要确认系统是否装了以下工具(可以用 which 命令进行查看)。
    · aclocal
    · autoscan
    · autoconf
    · autoheader
    · automake
    没有安装就进行安装。$:' sudo apt-get install aclocal autoscan autoconf autoheader automake
    1. 使用 aclocal 生成一个“aclocal.m4”文件,该文件主要处理本地的宏定义;
    2. 改写“configure.scan”文件,并将其重命名为“configure.in”,并使用 autoconf 文件生成 configure 文件。

    【嵌入式系统基础】


    RAM(随机存取存储器),内存,掉电丢失。
    ROM(只读存储器),硬盘,掉电不丢失。
    RAM 又可分为 SRAM(静态存储器)和 DRAM(动态存储器)。
    SDRAM 是 DRAM 的一种,它是同步动态存储器。
    Flash 也是一种非易失性存储器(掉电不会丢失),它擦写方便,访问速度快。
    NOR Flash 的特点是芯片内执行(Execute In Place),这样应用程序可以直接在 flash 闪存内运行,而不必再把代码读到系统 RAM 中。
    NAND Flash 结构能提供极高的单元密度,可以达到高存储密度,NAND 读和写操作采用 512 字节的块,单元尺寸几乎是 NOR 器件的一半,同时由于生产过程更为简单,大大降低了生产的成本。

    常见的 CPU 指令集分为 CISC 和 RISC 两种:
    CISC(Complex Instruction Set Computer)是“复杂指令集”。
    RISC(Reduced Instruction Set Computing)是“精简指令集”。

    MMU 是内存管理单元,它把内存以“页(page)”为单位来进行处理。一页内存是指一个具有一定大小的连续的内存块,通常为 4096B 或 8192B。

    【嵌入式Linux开发环境搭建】


    交叉编译器下载:ftp://gcc.gnu.org/pub/
    多个编译包:cross-3.3.2.bar.bz2

    超级终端:115200,8,N,1
    Minicom:
    CTRL+A Z,来查看 minicom 帮助;
    CTRL-A O,来进行配置串口参数,同样是 115200,8,N,1

    下载映像到开发板:
    >> tftp
        $:' vi /etc/xinetd.d/tftp
        // 主要要将“disable=yes”改为“no”,另外,从“server_args”可以看出,tftp服务器端的默认根目录为“/tftpboot”。
        $:' service xinetd restart
        $:' netstat -au
        // 确认tftp服务是否已经开启
        接下来,用直连线(注意:不可以使用网线)把目标板和宿主机连起来,并且将其配置成一个网段的地址。
        #:' tftpboot 0x30200000 zImage
        // 进行下载。

    编译linux内核、制作文件系统镜像、u-boot移植,这些基本操作:略。

    【文件I/O编程】


    系统调用:操作系统提供给用户程序调用的一组“特殊”接口,用户程序可以通过这组“特殊”接口来获得操作系统内核提供的服务。
    Linux 中的文件主要分为 4 种:普通文件、目录文件、链接文件和设备文件。
    一个进程启动时,都会打开 3 个文件:标准输入、标准输出和标准出错处理。这 3 个文件分别对应文件描述符为 0、1 和 2(也就是宏替换 STDIN_FILENO、STDOUT_FILENO 和 STDERR_FILENO,鼓励使用这些宏替换)。

    不带缓存的文件 I/O 操作,主要用到 5 个函数:openreadwritelseekclose
    函数较简单,用法:略。
    不带缓存是指每一个函数都只调用系统中的一个函数。

    在文件已经共享的情况下如何操作,也就是当多个用户共同使用、操作一个文件的情况,这时,Linux 通常采用的方法是给文件上锁,来避免共享的资源产生竞争的状态。
    fcntl 函数:
    1. /* fcntl 使用实例 lock_set 函数 */  
    2. void lock_set(int fd, int type)  
    3. {  
    4.     struct flock lock;  
    5.     lock.l_whence = SEEK_SET;//赋值 lock 结构体  
    6.     lock.l_start = 0;  
    7.     lock.l_len =0;  
    8.     while(1)  
    9.     {  
    10.         lock.l_type = type;  
    11.         /*根据不同的 type 值给文件上锁或解锁*/  
    12.         if((fcntl(fd, F_SETLK, &lock)) == 0){  
    13.             if( lock.l_type == F_RDLCK )  
    14.             printf("read lock set by %d\n",getpid());  
    15.         else if( lock.l_type == F_WRLCK )  
    16.             printf("write lock set by %d\n",getpid());  
    17.         else if( lock.l_type == F_UNLCK )  
    18.             printf("release lock by %d\n",getpid());  
    19.         return;  
    20.     }  
    21.     /*判断文件是否可以上锁*/  
    22.     fcntl(fd, F_GETLK,&lock);  
    23.     /*判断文件不能上锁的原因*/  
    24.     if(lock.l_type != F_UNLCK){  
    25.     /*/该文件已有写入锁*/  
    26.         if( lock.l_type == F_RDLCK )  
    27.             printf("read lock already set by %d\n",lock.l_pid);  
    28.         /*该文件已有读取锁*/  
    29.         else if( lock.l_type == F_WRLCK )  
    30.             printf("write lock already set by %d\n",lock.l_pid);  
    31.         getchar();  
    32.         }  
    33.     }  
    34. }  
    1. /*fcntl_write.c 测试文件写入锁主函数部分*/  
    2. #include <unistd.h>  
    3. #include <sys/file.h>  
    4. #include <sys/types.h>  
    5. #include <sys/stat.h>  
    6. #include <stdio.h>  
    7. #include <stdlib.h>  
    8. int main(void)  
    9. {  
    10.     int fd;  
    11.     /*首先打开文件*/  
    12.     fd=open("hello",O_RDWR | O_CREAT, 0666);  
    13.     if(fd < 0){  
    14.         perror("open");  
    15.         exit(1);  
    16.     }  
    17.     /*给文件上写入锁*/  
    18.     lock_set(fd, F_WRLCK);  
    19.     getchar();  
    20.     /*给文件接锁*/  
    21.     lock_set(fd, F_UNLCK);  
    22.     getchar();  
    23.     close(fd);  
    24.     return 0;  
    25. }  
    终端一:
    [root@localhost file]# ./fcntl_write
    write lock set by 4994
    release lock by 4994
    终端二:
    [root@localhost file]# ./fcntl_write
    write lock already set by 4994
    write lock set by 4997
    release lock by 4997

    1. /*fcntl_read.c 测试文件读取锁主函数部分*/  
    2. #include <unistd.h>  
    3. #include <sys/file.h>  
    4. #include <sys/types.h>  
    5. #include <sys/stat.h>  
    6. #include <stdio.h>  
    7. #include <stdlib.h>  
    8. int main(void)  
    9. {  
    10.     int fd;  
    11.     fd=open("hello",O_RDWR | O_CREAT, 0666);  
    12.     if(fd < 0){  
    13.         perror("open");  
    14.         exit(1);  
    15.     }  
    16.     /*给文件上读取锁*/  
    17.     lock_set(fd, F_RDLCK);  
    18.     getchar();  
    19.     /*给文件接锁*/  
    20.     lock_set(fd, F_UNLCK);  
    21.     getchar();  
    22.     close(fd);  
    23.     return 0;;  
    24. }  

    终端一:
    [root@localhost file]# ./fcntl2
    read lock set by 5009
    release lock by 5009
    终端二:
    [root@localhost file]# ./fcntl2
    read lock set by 5010
    release lock by 5010

    I/O 处理的模型有 5 种:
    · 阻塞 I/O 模型:在这种模型下,若所调用的 I/O 函数没有完成相关的功能就会使进程挂起,直到相关数据到才会出错返回。如常见对管道设备、终端设备和网络设备进行读写时经常会出现这种情况。
    · 非阻塞模型:在这种模型下,当请求的 I/O 操作不能完成时,则不让进程睡眠,而且返回一个错误。非阻塞 I/O 使用户可以调用不会永远阻塞的 I/O 操作,如 open、write和 read。如果该操作不能完成,则会立即出错返回,且表示该 I/O 如果该操作继续执行就会阻塞。
    · I/O 多路转接模型:在这种模型下,如果请求的 I/O 操作阻塞,且它不是真正阻塞 I/O,而是让其中的一个函数等待,在这期间,I/O 还能进行其他操作。如select函数和poll 函数,就是属于这种模型。
    · 信号驱动 I/O 模型:在这种模型下,通过安装一个信号处理程序,系统可以自动捕获特定信号的到来,从而启动 I/O。这是由内核通知用户何时可以启动一个 I/O 操作决定的。
    · 异步 I/O 模型:在这种模型下,当一个描述符已准备好,可以启动 I/O 时,进程会通知内核。现在,并不是所有的系统都支持这种模型。

    select函数:
    select 的 I/O 多路转接模型是处理 I/O 复用的一个高效的方法。
    int select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exeptfds, struct timeval *timeout);
    功能:I/O 多路转接,具体设置每一个所关心的文件描述符的条件、希望等待的时间等。
    参数:
        @numfds:需要检查的号码最高的文件描述符加 1
        @readfds:由 select()监视的读文件描述符集合
        @writefds:由 select()监视的写文件描述符集合
        @exeptfds:由 select()监视的异常处理文件描述符集合
        @timeout:
            NULL:永远等待,直到捕捉到信号或文件描述符已准备好为止
            具体值:struct timeval 类型的指针,若等待为 timeout 时间还没有文件描符准备好,就立即返回
            0:从不等待,测试所有指定的描述符并立即返回
    函数返回值:成功:准备好的文件描述符,-1:出错

    select 函数根据希望进行的文件操作对文件描述符进行了分类处理,这里,对文件描述符的处理主要涉及到 4 个宏函数:
    1. FD_ZERO(fd_set *set)            清除一个文件描述符集  
    2. FD_SET(int fd,fd_set *set)      将一个文件描述符加入文件描述符集中  
    3. FD_CLR(int fd,fd_set *set)      将一个文件描述符从文件描述符集中清除  
    4. FD_ISSET(int fd,fd_set *set)    测试该集中的一个给定位是否有变化  
    5.   
    6. // 一般来说,在使用 select 函数之前,首先使用 FD_ZERO 和 FD_SET 来初始化文件描述符集,在使用了 select 函数时,可循环使用 FD_ISSET 测试描述符集,在执行完对相关后文件描述符后,使用 FD_CLR 来清楚描述符集。  

    本实例中主要实现将文件 hello1 里的内容读出,并将此内容每隔 10s 写入 hello2 中去。在这里建立了两个描述符集,其中一个描述符集 inset1 是用于读取文件内容,另一个描述符集 inset2 是用于写入文件的。两个文件描述符 fds[0]和 fds[1]分别指向这一文件描述符。在首先初始化完各文件描述符集之后,就开始了循环测试这两个文件描述符是否可读写,由于在这里没有阻塞,所以文件描述符处于准备就绪的状态。这时,就分别对文件描述符 fds[0]和fsd[1]进行读写操作。
    1. /*select.c*/  
    2. #include <fcntl.h>  
    3. #include <stdio.h>  
    4. #include <unistd.h>  
    5. #include <stdlib.h>  
    6. #include <time.h>  
    7. int main(void)  
    8. {  
    9.     int fds[2];  
    10.     char buf[7];  
    11.     int i,rc,maxfd;  
    12.     fd_set inset1,inset2;  
    13.     struct timeval tv;  
    14.     /*首先按一定的权限打开 hello1 文件*/  
    15.     if((fds[0] = open ("hello1", O_RDWR|O_CREAT,0666))<0)  
    16.         perror("open hello1");  
    17.     /*再按一定的权限打开 hello2 文件*/  
    18.     if((fds[1] = open ("hello2", O_RDWR|O_CREAT,0666))<0)  
    19.         perror("open hello2");  
    20.     if((rc = write(fds[0],"Hello!\n",7)))  
    21.         printf("rc=%d\n",rc);  
    22.     lseek(fds[0],0,SEEK_SET);  
    23.     /*取出两个文件描述符中的较大者*/  
    24.     maxfd = fds[0]>fds[1] ? fds[0] : fds[1];  
    25.     /*初始化读集合 inset1,并在读集合中加入相应的描述集*/  
    26.     FD_ZERO(&inset1);  
    27.     FD_SET(fds[0],&inset1);  
    28.     /*初始化写集合 inset2,并在写集合中加入相应的描述集*/  
    29.     FD_ZERO(&inset2);  
    30.     FD_SET(fds[1],&inset2);  
    31.     tv.tv_sec=2;  
    32.     tv.tv_usec=0;  
    33.     /*循环测试该文件描述符是否准备就绪,并调用 select 函数对相关文件描述符做对应操作*/  
    34.     while(FD_ISSET(fds[0],&inset1)||FD_ISSET(fds[1],&inset2))  
    35.     {  
    36.         if(select(maxfd+1,&inset1,&inset2,NULL,&tv)<0)  
    37.             perror("select");  
    38.         else  
    39.         {  
    40.             if(FD_ISSET(fds[0],&inset1))  
    41.             {  
    42.                 rc = read(fds[0],buf,7);  
    43.                 if(rc>0)  
    44.                 {  
    45.                     buf[rc]='\0';  
    46.                     printf("read: %s\n",buf);  
    47.                 }  
    48.                 else  
    49.                 perror("read");  
    50.             }  
    51.             if(FD_ISSET(fds[1],&inset2))  
    52.             {  
    53.                 rc = write(fds[1],buf,7);  
    54.                 if(rc>0)  
    55.                 {  
    56.                     buf[rc]='\0';  
    57.                     printf("rc=%d,write: %s\n",rc,buf);  
    58.                 }  
    59.                 else  
    60.                     perror("write");  
    61.                 sleep(10);  
    62.             }  
    63.         }  
    64.     }  
    65.     return 0;  
    66. }  
    运行结果:
    [root@(none) 1]#:' ./select
        rc=7
        read: Hello!
        rc=7,write: Hello!
        rc=7,write:Hello!
        rc=7,write:Hello!
        …
    [root@(none) 1]#:'  cat hello1
    Hello!
    [root@(none) 1]#:'  cat hello2
    Hello!
    Hello!

    使用 select 可以很好地实现 I/O 多路复用,在有阻塞的情况下更能够显示出它的作用。

    Linux 串口应用开发 page203
    在 Linux 中,所有的设备文件一般都位于“/dev”下,其中串口一、串口二对应的设备名依次为“/dev/ttyS0”、“/dev/ttyS1”,可以查看在“/dev”下的文件以确认。

    标准 I/O 开发 - 基于流缓冲
    标准 I/O 提供流缓冲的目的:尽可能减少使用 read 和 write 系统调用的次数
    打开文件函数:fopenfdopenfreopen
    fopen 可以指定打开文件的路径和模式,fdopen可以指定打开的文件描述符和模式,而 freopen 除可指定打开的文件、模式外,还可指定特定的 IO 流。
    关闭文件函数:fclose
    文件读写函数:fread 和 fwrite
    输入输出函数:
        字符输入,getc/fgetc/getchar
        字符输出,putc/fputc/putchar
        // 这几个函数功能类似,其区别仅在于 getc 和 putc 通常被实现为宏,而 fgetc 和 fputc 不能实现为宏,因此,函数的实现时间会有所差别。
        行输入,gets/fgets
        行输出,puts/fputs
        // 行输入输出函数一次操作一行。
        格式化输入,scanf/fscanf/sscanf
        格式化输出,printf/fprintf/sprintf、vprintf/vfprintf/vsprintf
        // 格式化输入输出函数使用的是可变参数。
    1. /* 打开一个文件,然后将该文件上写入锁,并写入 hello 字符串。接着在解锁后再将该文件上读取锁,并读取刚才写入的内容。最后模拟多进程,同时读写一个文件时的情况。 expr1.c 实验源码*/  
    2. #include <unistd.h>  
    3. #include <sys/file.h>  
    4. #include <sys/types.h>  
    5. #include <sys/stat.h>  
    6. #include <stdio.h>  
    7. #include <stdlib.h>  
    8. #include <string.h>  
    9. void lock_set(int fd, int type)  
    10. {  
    11.     struct flock lock;  
    12.     lock.l_whence = SEEK_SET;//赋值 lock 结构体  
    13.     lock.l_start = 0;  
    14.     lock.l_len =0;  
    15.     while(1)  
    16.     {  
    17.         lock.l_type = type;  
    18.         /*根据不同的 type 值给文件上锁或解锁*/  
    19.         if((fcntl(fd, F_SETLK, &lock)) == 0){  
    20.             if( lock.l_type == F_RDLCK )  
    21.             printf("read lock set by %d\n",getpid());  
    22.         else if( lock.l_type == F_WRLCK )  
    23.             printf("write lock set by %d\n",getpid());  
    24.         else if( lock.l_type == F_UNLCK )  
    25.             printf("release lock by %d\n",getpid());  
    26.         return;  
    27.     }  
    28.     /*判断文件是否可以上锁*/  
    29.     fcntl(fd, F_GETLK,&lock);  
    30.     /*判断文件不能上锁的原因*/  
    31.     if(lock.l_type != F_UNLCK){  
    32.     /*/该文件已有写入锁*/  
    33.         if( lock.l_type == F_RDLCK )  
    34.             printf("read lock already set by %d\n",lock.l_pid);  
    35.         /*该文件已有读取锁*/  
    36.         else if( lock.l_type == F_WRLCK )  
    37.             printf("write lock already set by %d\n",lock.l_pid);  
    38.         getchar();  
    39.         }  
    40.     }  
    41. }  
    42. int main(void)  
    43. {  
    44.     int fd,nwrite,nread,len;  
    45.     char *buff="Hello\n";  
    46.     char buf_r[100];  
    47.     len=strlen(buff);  
    48.     fd=open("hello",O_RDWR | O_CREAT, 0666);  
    49.     if(fd < 0){  
    50.         perror("open");  
    51.         exit(1);  
    52.     }  
    53.     /*加上写入锁*/  
    54.     lock_set(fd, F_WRLCK);  
    55.     if((nwrite=write(fd,buff,len))==len){  
    56.         printf("write success\n");  
    57.     }  
    58.     getchar();  
    59.     /*解锁*/  
    60.     lock_set(fd, F_UNLCK);  
    61.     getchar();  
    62.     /*加上读取锁*/  
    63.     lock_set(fd, F_RDLCK);  
    64.     lseek(fd,0,SEEK_SET);  
    65.     if((nread=read(fd,buf_r,len))==len){  
    66.         printf("read:%s\n",buf_r);  
    67.     }  
    68.     getchar();  
    69.     /*解锁*/  
    70.     lock_set(fd, F_UNLCK);  
    71.     getchar();  
    72.     close(fd);  
    73.     return 0;  
    74. }  
    75. // 同一个终端内运行测试,开两个终端运行测试多进程情况,测试结果均不会收到影响。  

    【进程控制开发】


    进程创建:fork
    进程中启动进程:exec函数族(execve为系统调用,其他都为库函数)
    进程退出:exit/_exit
    进程阻塞等待:wait/waitpid

    守护进程Daemon编写 5 步骤:
    1. 创建子进程,父进程退出;fork/exit
    1. /*父进程退出*/  
    2. pid=fork();  
    3. if(pid>0){  
    4.     exit(0);  
    5. }  
    2. 在子进程中创建新会话;setsid
    3. 改变当前目录为根目录;chdir
    4. 重设文件权限掩码;umask
    5. 关闭文件描述符;close
    1. /* 守护进程需要关闭标准I/O MAXFILE==3 */  
    2. for(i=0;i<MAXFILE;i++)  
    3.     close(i);  
    汇总:开始 >> fork()/exit() >> setsid() >> chdir("/") >> umask(0) >> close >> 结束(守护进程创建)
    1. /* 实现守护进程的一个完整实例 */  
    2. /*dameon.c 创建守护进程实例*/  
    3. #include<stdio.h>  
    4. #include<stdlib.h>  
    5. #include<string.h>  
    6. #include<fcntl.h>  
    7. #include<sys/types.h>  
    8. #include<unistd.h>  
    9. #include<sys/wait.h>  
    10. #define MAXFILE 65535  
    11. int main()  
    12. {  
    13.     pid_t pc;  
    14.     int i,fd,len;  
    15.     char *buf="This is a Dameon\n";  
    16.     len =strlen(buf);  
    17.     pc=fork(); // 第一步  
    18.     if(pc<0)  
    19.     {  
    20.         printf("error fork\n");  
    21.         exit(1);  
    22.     }else if(pc>0)  
    23.         exit(0);  
    24.     /*第二步*/  
    25.     setsid();  
    26.     /*第三步*/  
    27.     chdir("/");  
    28.     /*第四步*/  
    29.     umask(0);  
    30.     /*第五步*/  
    31.     for(i=0;i<MAXFILE;i++)  
    32.         close(i);  
    33.     /*这时创建完守护进程,以下开始正式进入守护进程工作*/  
    34.     while(1)  
    35.     {  
    36.         if((fd=open("/tmp/dameon.log",O_CREAT|O_WRONLY|O_APPEND,0600))<0)  
    37.         {  
    38.             perror("open");  
    39.             exit(1);  
    40.         }  
    41.         write(fd, buf, len+1);  
    42.         close(fd);  
    43.         sleep(10);  
    44.     }  
    45. }  
    46. // 该程序每隔 10s 就会在对应的文件中输入相关内容。  
    守护进程的进程要如何调试呢?
    一种通用的办法是使用 syslog服务,将程序中的出错信息输入到" /var/log/messages "系统日志文件中,需要root权限,从而可以直观地看到程序的问题所在。

    系统日志函数:openlogsyslogcloselog
    openlog 函数用于打开系统日志服务的一个连接;syslog 函数是用于向日志文件中写入消息,在这里可以规定消息的优先级、消息输出格式等;closelog 函数是用于关闭系统日志服务的连接。

    【进程间通信】


    1. UNIX 进程间通信(IPC)方式包括管道、FIFO、信号。
    2. System V 进程间通信(IPC)包括 System V 消息队列、System V信号灯(信号量集)、System V共享内存区。
    3. Posix 进程间通信(IPC)包括 Posix 消息队列、Posix 信号灯(信号量集)、Posix 共享内存区。
    4. 基于socket的进程间通信。

    管道的创建和关闭:pipe/close
    管道的读写:read/write
    标准流管道:popen/pclose

    信号的发送:kill raise alarm pause
    信号的处理:signal / 信号量集函数组
    信号量集功能模块:
        创建信号集合,sigemptyset sigfillset sigaddset sigdelset sigismember
        登记信号处理器,sigprocmask sigaction
        检测信号,sigpending
    共享内存:shmget shmat/shmdt
    消息队列:msgget msgsnd/msgrcvmsgctl

    【多线程通信】


    线程创建和退出:pthread_create pthread_exit pthread_join
    修改线程属性:pthread_attr_init pthread_attr_setscope pthread_attr_setdetachstate/pthread_attr_getschedparampthread_attr_setschedparam
    这些属性主要包括绑定属性、分离属性、堆栈地址、堆栈大小、优先级。
    线程同步:
        · 互斥锁初始化:pthread_mutex_init
        · 互斥锁上锁:pthread_mutex_lock
        · 互斥锁判断上锁:pthread_mutex_trylock
        · 互斥锁接锁:pthread_mutex_unlock
        · 销毁互斥锁:pthread_mutex_destroy
    信号量线程控制:PV操作
        · sem_init 用于创建一个信号量,并能初始化它的值。
        · sem_wait 和 sem_trywait相当于 P 操作,它们都能将信号量的值减一,两者的区别在于若信号量小于零时,sem_wait 将会阻塞进程,而 sem_trywait 则会立即返回。
        · sem_post 相当于 V 操作,它将信号量的值加一同时发出信号唤醒等待的进程。
        · sem_getvalue 用于得到信号量的值。
        · sem_destroy 用于删除信号量。

    经典例程:生产者与消费者模型。

    【网络编程】


    TCP 对话通过三次握手来初始化的。
    三次握手的目的:使数据段的发送和接收同步,告诉其他主机其一次可接收的数据量,并建立虚连接。

    socket三种类型:
    (1)流式 socket(SOCK_STREAM
    流式套接字提供可靠的、面向连接的通信流;它使用 TCP 协议,从而保证了数据传输的正确性和顺序性。
    (2)数据报 socket(SOCK_DGRAM
    数据报套接字定义了一种无连接的服务,数据通过相互独立的报文进行传输,是无序的,并且不保证是可靠、无差错的。它使用数据报协议 UDP。
    (3)原始 socket
    原始套接字允许对底层协议如 IP 或 ICMP 进行直接访问,它功能强大但使用较为不便,主要用于一些协议的开发。

    网络字节序与主机字节序的转化:htonsntohshtonlntohl
    //  h 代表 host,n 代表 network,s 代表 short,l 代表 long。通常 16 位的 IP 端口号用 s 代表,而 IP 地址用 l 来代表。
    地址格式转化:IPv4,inet_atoninet_addrinet_ntoa;IPv4和IPv6兼容函数,inet_ptoninet_ntop
    主机名和地址的转化:gethostbynamegethostbyaddrgetaddrinfo
    1. Struct hostent{  
    2.     char *h_name;/*正式主机名*/  
    3.     char **h_aliases;/*主机别名*/  
    4.     int h_addrtype;/*地址类型*/  
    5.     int h_length;/*地址长度*/  
    6.     char **h_addr_list;/*指向 IPv4 或 IPv6 的地址指针数组*/  
    7. }  
    8.   
    9. struct addrinfo{  
    10.     int ai_flags;/*AI_PASSIVE,AI_CANONNAME;*/  
    11.     int ai_family;/*地址族*/  
    12.     int ai_socktype;/*socket 类型*/  
    13.     int ai_protocol;/*协议类型*/  
    14.     size_t ai_addrlen;/*地址长度*/  
    15.     char *ai_canoname;/*主机名*/  
    16.     struct sockaddr *ai_addr;/*socket 结构体*/  
    17.     struct addrinfo *ai_next;/*下一个指针链表*/  
    18. }  
    展开全文
  • linux快速入门】 自由软件(free software)中的 free 并不是指免费,而是指自由。它赋予使用者四种自由。 · 自由之一:有使用软件的自由。 · 自由之二:有研究该软件如何运作的自由,并且得以改写该软件来符合...

    【linux快速入门】


    自由软件(free software)中的 free 并不是指免费,而是指自由。它赋予使用者四种自由。
    · 自由之一:有使用软件的自由。
    · 自由之二:有研究该软件如何运作的自由,并且得以改写该软件来符合使用者自身的需求。取得该软件的源码是达成此目的前提。
    · 自由之三:有重新散布该软件的自由,所以每个人都可以藉由散布自由软件来敦亲睦另。
    · 自由之四:有改善再利用该软件的自由,并且可以发表改写版供公众使用,如此一来,整个社群都可以受惠。如前项,取得该软件的源码是达成此目的前提。

    GPL:GPL 协议是 GNU 组织、维护的一种版权协议,遵守这个协议的软件可以自由地获取、查看、使用其源代码。GPL 协议是整个开源世界的精神基础。

    Linux 的内核版本号:
    Linux 内核版本号格式是 x.y.zz-www,数字 x 代表版本类型,数字 y 为偶数时是稳定版本,为奇数时是开发版本,如 2.0.40 为稳定版本,2.3.42 为开发版本,测试版本为 3 个数字加上测试号,如 2.4.12-rc1。最新的 Linux 内核版本可从 http://www.kernel.org 上获得。

    国内的一些 Linux 论坛:
    http://www.linuxfans.org
    http://www.linuxforum.net
    http://www.linuxeden.com
    http://www.newsmth.net


    在 Windows 下,目录结构属于分区;Linux 下,分区属于目录结构。
    在 Windows 下,路径用 \ 反斜杠分割;Linux 下,路径用 / 斜杠分割。(实际是linux最早,你懂的)

    通常在 Windows 下的盘符和 Linux 设备文件的对应关系如下:
    C 盘—/dev/hda1主分区
    D 盘—/dev/hda5(逻辑分区)
    E 盘—/dev/hda6(逻辑分区)

    如果想修复已经安装好的系统,请在提示符 boot:后输入“Linux rescue”命令。

    ext3 是现在 Linux(包括 Red Hat,Mandrake 下)常见的默认的文件系统,它是 ext2 的升级版本。
    /bin            bin 就是二进制(binary)英文缩写。在这里存放前面 Linux 常用操作命令的执行文件,如 mv、ls、mkdir 等。有时,这个目录的内容和/usr/bin 里面的内容一样,它们都是放置一般用户使用的执行文件
    /boot   这个目录下存放操作系统启动时所要用到的程序。如启动 grub 就会用到其下的/boot/grub子目录
    /dev            该目录中包含了所有 Linux 系统中使用的外部设备。要注意的是,这里并不是存放的外部设备的驱动程序,它实际上是一个访问这些外部设备的端口。由于在 Linux 中,所有的设备都当作文件一样进行操作,比如:/dev/cdrom 代表光驱,用户可以非常方便地像访问文件、目录一样对其进行访问
    /etc            该目录下存放了系统管理时要用到的各种配置文件和子目录。如网络配置文件、文件系统、x 系统配置文件、设备配置信息设置用户信息等都在这个目录下。系统在启动过程中需要读取其参数进行相应的配置
    /etc/rc.d       该目录主要存放 Linux 启动和关闭时要用到的脚本文件,在后面的启动详解中还会进一步地讲解
    /etc/rc.d/init  该目录存放所有 Linux 服务默认的启动脚本(在新版本的 Linux 中还用到的是/etc/xinetd.d目录下的内容)
    /home           该目录是 Linux 系统中默认的用户工作根目录。执行 adduser命令后系统会在/home 目录下为对应账号建立一个名为同名的主目录
    /lib            该目录是用来存放系统动态链接共享库的。几乎所有的应用程序都会用到这个目录下的共享库。因此,千万不要轻易对这个目录进行什么操作
    /lost+found     该目录在大多数情况下都是空的。只有当系统产生异常时,会将一些遗失的片段放在此目录下
    /media          该目录下是光驱和软驱的挂载点,Fedora Core 4 已经可以自动挂载光驱和软驱
    /misc           该目录下存放从 DOS 下进行安装的实用工具,一般为空
    /mnt            该目录是软驱、光驱、硬盘的挂载点,也可以临时将别的文件系统挂载到此目录下
    /proc           该目录是用于放置系统核心与执行程序所需的一些信息。而这些信息是在内存中由系统产生的,故不占用硬盘空间
    /root           该目录是超级用户登录时的主目录
    /sbin           该目录是用来存放系统管理员的常用的系统管理程序
    /tmp            该目录用来存放不同程序执行时产生的临时文件。一般 Linux 安装软件的默认安装路径就是这里
    /usr            这是一个非常重要的目录,用户的很多应用程序和文件都存放在这个目录下,类似与Windows 下的 Program Files 的目录
    /usr/bin        系统用户使用的应用程序
    /usr/sbin       超级用户使用的比较高级的管理程序和系统守护程序
    /usr/src        内核源代码默认的放置目录
    /srv            该目录存放一些服务启动之后需要提取的数据
    /sys            这是 Linux 2.6 内核的一个很大的变化。该目录下安装了 2.6 内核中新出现的一个文件系统 sysfs,sysfs 文件系统集成了下面 3 种文件系统的信息:针对进程信息的 proc 文件系统、针对设备的 devfs 文件系统以及针对伪终端的 devpts 文件系统。该文件系统是内核设备树的一个直观反映。当一个内核对象被创建的时候,对应的文件和目录也在内核对象子系统中被创建
    /var            这也是一个非常重要的目录,很多服务的日志信息都存放在这里

    【linux基础命令】


    root用户切换:
        $:' sudo passwd
        // 输入当前登陆密码,再根据提示输入设置的UNIX密码2遍,即为root用户切换密码
        $:' su
        // 输入UNIX密码,切换为root用户,提示符变为 #

    设置环境变量方法如下:
    1. 通过 echo 显示字符串(指定环境变量)。
    2. 通过 export 设置新的环境变量。
    3. 通过 env 显示所有环境变量。
    4. 通过 set 命令显示所有本地定义的 Shell 变量。
    5. 通过 unset 命令来清除环境变量。

    Linux常见用户管理命令:
    useradd         添加用户账号                        useradd [选项] 用户名
    usermod         设置用户账号属性                    usermod [选项] 属性值
    userdel         删除对应用户账号                    userdel [选项] 用户名
    groupadd        添加组账号                          groupadd [选项] 组账号
    groupmod        设置组账号属性                      groupmod [选项] 属性值
    groupdel        删除对应组账号                      groupdel [选项] 组账号
    passwd          设置账号密码                        passwd [对应账号]
    id              显示用户ID、组ID和用户所属组列表    id [用户名]
    groups          显示用户所属的组                    groups [组账号]
    who             显示登录到系统的所有用户            who
    whoami          显示当前用户名                      whoami

    Linux常见系统管理命令:
    ps              显示当前系统中由该用户运行的进程列表        ps [选项]
    top             动态显示系统中运行的程序(一般为每隔 5s)   top
    kill            输出特定的信号给指定 PID(进程号)的进程    kill [选项] 进程号(PID)
    uname           显示系统的信息(可加选项-a)                uname [选项]
    setup           系统图形化界面配置                          setup
    crontab         循环执行例行性命令                          crontab [选项]
    shutdown        关闭或重启 Linux 系统                       shutdown [选项] [时间]
    uptime          显示系统已经运行了多长时间                  uptime
    clear           清除屏幕上的信息(ctrl + l)                  clear

    Linux常见磁盘管理命令:
    free            查看当前系统内存的使用情况                  free [选项]
    df              查看文件系统的磁盘空间占用情况              df [选项]
    du              统计目录(或文件)所占磁盘空间的大小        du [选项]
    fdisk           查看硬盘分区情况及对硬盘进行分区管理        fdisk [-l]
    mount           磁盘挂载命令                                mount -t [选项] [文件系统类型] 设备文件名 挂载点目录

    mount挂载举例:
        $:' mount -t vfat/dev/hda1 /mnt/c
        $:' umount /mnt/c
    · 在 Linux 下如何使用 U 盘呢?
    一般 U 盘为 SCSI 格式的硬盘,其格式为 vfat 格式,其设备号可通过“fdisk –l”进行查看,假若设备名为“/dev/sda1”,则可用如下命令就可将其挂载:
        $:' mount -t vfat /dev/sda1 /mnt/u
    · 若想设置在开机时自动挂载,可在文件“/etc/fstab”中加入该命令到一个新行即可。

    正则表达式的主要参数有:
    · \:忽略正则表达式中特殊字符的原有含义;
    · ^:匹配正则表达式的开始行;
    · $:匹配正则表达式的结束行;
    · <:从匹配正则表达式的行开始;
    · >:到匹配正则表达式的行结束;
    · [ ]:单个字符,如[A]即 A 符合要求;
    · [-]:范围,如[A-Z],即 A、B、C 一直到 Z 都符合要求;
    · 。:所有的单个字符;
    · *:所有字符,长度可以为 0。

    ln 的链接又软链接和硬链接两种:
    软链接就是上面所说的 ln -s ** **,它只会在用户选定的位置上生成一个文件的镜像,不会重复占用磁盘空间,平时使用较多的都是软链接;
    硬链接是不带参数的 ln ** **,它会在用户选定的位置上生成一个和源文件大小相同的文件,无论是软链接还是硬链接,文件都保持同步变化。

    Linux常见压缩打包相关命令:
    bzip2           .bz2 文件的压缩(或解压)程序           bzip2[选项] 压缩(解压缩)的文件名
    bunzip2         .bz2 文件的解压缩程序                   bunzip2[选项] .bz2 压缩文件
    bzip2recover    用来修复损坏的.bz2 文件                 bzip2recover .bz2 压缩文件
    gzip            .gz 文件的压缩程序                      gzip [选项] 压缩(解压缩)的文件名
    gunzip          解压被 gzip 压缩过的文件                gunzip [选项] .gz 文件名
    unzip           解压 winzip 压缩的.zip 文件             unzip [选项] .zip 压缩文件
    compress        早期的压缩或解压程序(压缩后文件名为.Z)  compress [选项] 文件
    tar             对文件目录进行打包或解包                tar [选项] [打包后文件名]文件目录列表

    Linux比较和合并文件命令:
    diff            比较两个不同的文件或不同目录下的两个同名文件功能,并生成补丁文件        diff[选项] 文件1 文件2
        $:' diff hello1.c hello2.c > hello.patch
    patch           把生成的补丁文件应用到现有代码上            patch [选项] [待 patch 的文件[patch 文件]]
        $:' patch ./hello1.c < hello1.patch

    Linux常见网络相关命令:
    netstat         显示网络连接、路由表和网络接口信息      netstat [-an]
    nslookup        查询一台机器的 IP 地址和其对应的域名    nslookup [IP 地址/域名]
    finger          查询用户的信息                          finger [选项] [使用者] [用户@主机]
    ping            用于查看网络上的主机是否在工作          ping [选项] 主机名/IP 地址
    ifconfig        查看和配置网络接口的参数                ifconfig [选项] [网络接口]
    ftp             利用 ftp 协议上传和下载文件             ftp [选项] [主机名/IP]
    telnet          利用 telnet 协议浏览信息                telent [选项] [IP 地址/域名]
    ssh             利用 ssh 登录对方主机                   ssh [选项] [IP 地址]


    定制linux系统服务流程步骤:
    (1)查看系统的默认运行级别。
        $:' cat /etc/inittab(设其结果为 N)
    (2)进入到相应级别的服务脚本目录,查看哪些服务是系统启动的独立运行的服务,并做下记录。
        $:' cd /etc/rc.d/rcN.d
    (3)利用命令查看系统开机自启动服务,并与上次查看结果进行比较,找出其中的区别,并思考其中的原因。
        $:' chkconfig –list
    (4)记录 chkconfig –list 命令中由 xinet 管理的服务,并将其中启动的服务做下记录。
    (5)进入 xinet 配置管理的相应目录,查看是否于 chkconfig –list 所得结果相吻合并查看相应脚本文件。
        $:' cd /etc/xinetd.d
    (6)将 sshd 服务停止。
        $:' service sshd stop
    (7)将 sshd 服务设置为开机不启动。
        $:' chkconfig –level N sshd stop
    (8)查看该设置是否生效。
        $:' chkconfig –list
    (9)查看系统中所有服务及其端口号列表。
        $:' cat /etc/services
    (10)将 sshd 服务端口改为 4022。
        $:' vi /etc/services;转到插入模式并修改其端口号
    (11)重启 sshd 服务,验证所改的端口号是否生效。
        $:' service sshd start
    (12)重启 Linux 系统,验证所改的服务开机启动是否生效。

    【linux下的C编程】


    编辑器:vim
    编译器:gcc
    调试器:gdb
    make工程管理器:Makefile

    Makefile常见预定义变量:
    AR          库文件维护程序的名称,默认值为 ar
    AS          汇编程序的名称,默认值为 as
    CC          C 编译器的名称,默认值为 cc
    CPP         C 预编译器的名称,默认值为$(CC) –E
    CXX         C++编译器的名称,默认值为 g++
    FC          FORTRAN 编译器的名称,默认值为 f77
    RM          文件删除程序的名称,默认值为 rm –f
    ARFLAGS     库文件维护程序的选项,无默认值
    ASFLAGS     汇编程序的选项,无默认值
    CFLAGS      C 编译器的选项,无默认值
    CPPFLAGS    C 预编译的选项,无默认值
    CXXFLAGS    C++编译器的选项,无默认值
    FFLAGS      FORTRAN 编译器的选项,无默认值

    Makefile自动变量:
    $*      不包含扩展名的目标文件名称
    $+      所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件
    $<      第一个依赖文件的名称
    $?      所有时间戳比目标文件晚的依赖文件,并以空格分开
    $@      目标文件的完整名称
    $^      所有不重复的依赖文件,以空格分开
    $%      如果目标是归档成员,则该变量表示目标的归档成员名称

    Makefile 中常见隐式规则:
    C 编译:.c 变为.o $(CC) –c $(CPPFLAGS) $(CFLAGS)
    C++编译:.cc 或.C 变为.o $(CXX) -c $(CPPFLAGS) $(CXXFLAGS)
    Pascal 编译:.p 变为.o $(PC) -c $(PFLAGS)
    Fortran 编译:.r 变为-o $(FC) -c $(FFLAGS)

    autotools自动生成Makefile:
    首先要确认系统是否装了以下工具(可以用 which 命令进行查看)。
    · aclocal
    · autoscan
    · autoconf
    · autoheader
    · automake
    没有安装就进行安装。$:' sudo apt-get install aclocal autoscan autoconf autoheader automake
    1. 使用 aclocal 生成一个“aclocal.m4”文件,该文件主要处理本地的宏定义;
    2. 改写“configure.scan”文件,并将其重命名为“configure.in”,并使用 autoconf 文件生成 configure 文件。

    【嵌入式系统基础】


    RAM(随机存取存储器),内存,掉电丢失。
    ROM(只读存储器),硬盘,掉电不丢失。
    RAM 又可分为 SRAM(静态存储器)和 DRAM(动态存储器)。
    SDRAM 是 DRAM 的一种,它是同步动态存储器。
    Flash 也是一种非易失性存储器(掉电不会丢失),它擦写方便,访问速度快。
    NOR Flash 的特点是芯片内执行(Execute In Place),这样应用程序可以直接在 flash 闪存内运行,而不必再把代码读到系统 RAM 中。
    NAND Flash 结构能提供极高的单元密度,可以达到高存储密度,NAND 读和写操作采用 512 字节的块,单元尺寸几乎是 NOR 器件的一半,同时由于生产过程更为简单,大大降低了生产的成本。

    常见的 CPU 指令集分为 CISC 和 RISC 两种:
    CISC(Complex Instruction Set Computer)是“复杂指令集”。
    RISC(Reduced Instruction Set Computing)是“精简指令集”。

    MMU 是内存管理单元,它把内存以“页(page)”为单位来进行处理。一页内存是指一个具有一定大小的连续的内存块,通常为 4096B 或 8192B。

    【嵌入式Linux开发环境搭建】


    交叉编译器下载:ftp://gcc.gnu.org/pub/
    多个编译包:cross-3.3.2.bar.bz2

    超级终端:115200,8,N,1
    Minicom:
    CTRL+A Z,来查看 minicom 帮助;
    CTRL-A O,来进行配置串口参数,同样是 115200,8,N,1

    下载映像到开发板:
    >> tftp
        $:' vi /etc/xinetd.d/tftp
        // 主要要将“disable=yes”改为“no”,另外,从“server_args”可以看出,tftp服务器端的默认根目录为“/tftpboot”。
        $:' service xinetd restart
        $:' netstat -au
        // 确认tftp服务是否已经开启
        接下来,用直连线(注意:不可以使用网线)把目标板和宿主机连起来,并且将其配置成一个网段的地址。
        #:' tftpboot 0x30200000 zImage
        // 进行下载。

    编译linux内核、制作文件系统镜像、u-boot移植,这些基本操作:略。

    【文件I/O编程】


    系统调用:操作系统提供给用户程序调用的一组“特殊”接口,用户程序可以通过这组“特殊”接口来获得操作系统内核提供的服务。
    Linux 中的文件主要分为 4 种:普通文件、目录文件、链接文件和设备文件。
    一个进程启动时,都会打开 3 个文件:标准输入、标准输出和标准出错处理。这 3 个文件分别对应文件描述符为 0、1 和 2(也就是宏替换 STDIN_FILENO、STDOUT_FILENO 和 STDERR_FILENO,鼓励使用这些宏替换)。

    不带缓存的文件 I/O 操作,主要用到 5 个函数:openreadwritelseekclose
    函数较简单,用法:略。
    不带缓存是指每一个函数都只调用系统中的一个函数。

    在文件已经共享的情况下如何操作,也就是当多个用户共同使用、操作一个文件的情况,这时,Linux 通常采用的方法是给文件上锁,来避免共享的资源产生竞争的状态。
    fcntl 函数:
    /* fcntl 使用实例 lock_set 函数 */
    void lock_set(int fd, int type)
    {
        struct flock lock;
        lock.l_whence = SEEK_SET;//赋值 lock 结构体
        lock.l_start = 0;
        lock.l_len =0;
        while(1)
        {
            lock.l_type = type;
            /*根据不同的 type 值给文件上锁或解锁*/
            if((fcntl(fd, F_SETLK, &lock)) == 0){
                if( lock.l_type == F_RDLCK )
                printf("read lock set by %d\n",getpid());
            else if( lock.l_type == F_WRLCK )
                printf("write lock set by %d\n",getpid());
            else if( lock.l_type == F_UNLCK )
                printf("release lock by %d\n",getpid());
            return;
        }
        /*判断文件是否可以上锁*/
        fcntl(fd, F_GETLK,&lock);
        /*判断文件不能上锁的原因*/
        if(lock.l_type != F_UNLCK){
        /*/该文件已有写入锁*/
            if( lock.l_type == F_RDLCK )
                printf("read lock already set by %d\n",lock.l_pid);
            /*该文件已有读取锁*/
            else if( lock.l_type == F_WRLCK )
                printf("write lock already set by %d\n",lock.l_pid);
            getchar();
            }
        }
    }
    /*fcntl_write.c 测试文件写入锁主函数部分*/
    #include <unistd.h>
    #include <sys/file.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <stdio.h>
    #include <stdlib.h>
    int main(void)
    {
        int fd;
        /*首先打开文件*/
        fd=open("hello",O_RDWR | O_CREAT, 0666);
        if(fd < 0){
            perror("open");
            exit(1);
        }
        /*给文件上写入锁*/
        lock_set(fd, F_WRLCK);
        getchar();
        /*给文件接锁*/
        lock_set(fd, F_UNLCK);
        getchar();
        close(fd);
        return 0;
    }
    终端一:
    [root@localhost file]# ./fcntl_write
    write lock set by 4994
    release lock by 4994
    终端二:
    [root@localhost file]# ./fcntl_write
    write lock already set by 4994
    write lock set by 4997
    release lock by 4997

    /*fcntl_read.c 测试文件读取锁主函数部分*/
    #include <unistd.h>
    #include <sys/file.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <stdio.h>
    #include <stdlib.h>
    int main(void)
    {
        int fd;
        fd=open("hello",O_RDWR | O_CREAT, 0666);
        if(fd < 0){
            perror("open");
            exit(1);
        }
        /*给文件上读取锁*/
        lock_set(fd, F_RDLCK);
        getchar();
        /*给文件接锁*/
        lock_set(fd, F_UNLCK);
        getchar();
        close(fd);
        return 0;;
    }

    终端一:
    [root@localhost file]# ./fcntl2
    read lock set by 5009
    release lock by 5009
    终端二:
    [root@localhost file]# ./fcntl2
    read lock set by 5010
    release lock by 5010

    I/O 处理的模型有 5 种:
    · 阻塞 I/O 模型:在这种模型下,若所调用的 I/O 函数没有完成相关的功能就会使进程挂起,直到相关数据到才会出错返回。如常见对管道设备、终端设备和网络设备进行读写时经常会出现这种情况。
    · 非阻塞模型:在这种模型下,当请求的 I/O 操作不能完成时,则不让进程睡眠,而且返回一个错误。非阻塞 I/O 使用户可以调用不会永远阻塞的 I/O 操作,如 open、write和 read。如果该操作不能完成,则会立即出错返回,且表示该 I/O 如果该操作继续执行就会阻塞。
    · I/O 多路转接模型:在这种模型下,如果请求的 I/O 操作阻塞,且它不是真正阻塞 I/O,而是让其中的一个函数等待,在这期间,I/O 还能进行其他操作。如select函数和poll 函数,就是属于这种模型。
    · 信号驱动 I/O 模型:在这种模型下,通过安装一个信号处理程序,系统可以自动捕获特定信号的到来,从而启动 I/O。这是由内核通知用户何时可以启动一个 I/O 操作决定的。
    · 异步 I/O 模型:在这种模型下,当一个描述符已准备好,可以启动 I/O 时,进程会通知内核。现在,并不是所有的系统都支持这种模型。

    select函数:
    select 的 I/O 多路转接模型是处理 I/O 复用的一个高效的方法。
    int select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exeptfds, struct timeval *timeout);
    功能:I/O 多路转接,具体设置每一个所关心的文件描述符的条件、希望等待的时间等。
    参数:
        @numfds:需要检查的号码最高的文件描述符加 1
        @readfds:由 select()监视的读文件描述符集合
        @writefds:由 select()监视的写文件描述符集合
        @exeptfds:由 select()监视的异常处理文件描述符集合
        @timeout:
            NULL:永远等待,直到捕捉到信号或文件描述符已准备好为止
            具体值:struct timeval 类型的指针,若等待为 timeout 时间还没有文件描符准备好,就立即返回
            0:从不等待,测试所有指定的描述符并立即返回
    函数返回值:成功:准备好的文件描述符,-1:出错

    select 函数根据希望进行的文件操作对文件描述符进行了分类处理,这里,对文件描述符的处理主要涉及到 4 个宏函数:
    FD_ZERO(fd_set *set)            清除一个文件描述符集
    FD_SET(int fd,fd_set *set)      将一个文件描述符加入文件描述符集中
    FD_CLR(int fd,fd_set *set)      将一个文件描述符从文件描述符集中清除
    FD_ISSET(int fd,fd_set *set)    测试该集中的一个给定位是否有变化
    
    // 一般来说,在使用 select 函数之前,首先使用 FD_ZERO 和 FD_SET 来初始化文件描述符集,在使用了 select 函数时,可循环使用 FD_ISSET 测试描述符集,在执行完对相关后文件描述符后,使用 FD_CLR 来清楚描述符集。

    本实例中主要实现将文件 hello1 里的内容读出,并将此内容每隔 10s 写入 hello2 中去。在这里建立了两个描述符集,其中一个描述符集 inset1 是用于读取文件内容,另一个描述符集 inset2 是用于写入文件的。两个文件描述符 fds[0]和 fds[1]分别指向这一文件描述符。在首先初始化完各文件描述符集之后,就开始了循环测试这两个文件描述符是否可读写,由于在这里没有阻塞,所以文件描述符处于准备就绪的状态。这时,就分别对文件描述符 fds[0]和fsd[1]进行读写操作。
    /*select.c*/
    #include <fcntl.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <time.h>
    int main(void)
    {
        int fds[2];
        char buf[7];
        int i,rc,maxfd;
        fd_set inset1,inset2;
        struct timeval tv;
        /*首先按一定的权限打开 hello1 文件*/
        if((fds[0] = open ("hello1", O_RDWR|O_CREAT,0666))<0)
            perror("open hello1");
        /*再按一定的权限打开 hello2 文件*/
        if((fds[1] = open ("hello2", O_RDWR|O_CREAT,0666))<0)
            perror("open hello2");
        if((rc = write(fds[0],"Hello!\n",7)))
            printf("rc=%d\n",rc);
        lseek(fds[0],0,SEEK_SET);
        /*取出两个文件描述符中的较大者*/
        maxfd = fds[0]>fds[1] ? fds[0] : fds[1];
        /*初始化读集合 inset1,并在读集合中加入相应的描述集*/
        FD_ZERO(&inset1);
        FD_SET(fds[0],&inset1);
        /*初始化写集合 inset2,并在写集合中加入相应的描述集*/
        FD_ZERO(&inset2);
        FD_SET(fds[1],&inset2);
        tv.tv_sec=2;
        tv.tv_usec=0;
        /*循环测试该文件描述符是否准备就绪,并调用 select 函数对相关文件描述符做对应操作*/
        while(FD_ISSET(fds[0],&inset1)||FD_ISSET(fds[1],&inset2))
        {
            if(select(maxfd+1,&inset1,&inset2,NULL,&tv)<0)
                perror("select");
            else
            {
                if(FD_ISSET(fds[0],&inset1))
                {
                    rc = read(fds[0],buf,7);
                    if(rc>0)
                    {
                        buf[rc]='\0';
                        printf("read: %s\n",buf);
                    }
                    else
                    perror("read");
                }
                if(FD_ISSET(fds[1],&inset2))
                {
                    rc = write(fds[1],buf,7);
                    if(rc>0)
                    {
                        buf[rc]='\0';
                        printf("rc=%d,write: %s\n",rc,buf);
                    }
                    else
                        perror("write");
                    sleep(10);
                }
            }
        }
        return 0;
    }
    运行结果:
    [root@(none) 1]#:' ./select
        rc=7
        read: Hello!
        rc=7,write: Hello!
        rc=7,write:Hello!
        rc=7,write:Hello!
        …
    [root@(none) 1]#:'  cat hello1
    Hello!
    [root@(none) 1]#:'  cat hello2
    Hello!
    Hello!

    使用 select 可以很好地实现 I/O 多路复用,在有阻塞的情况下更能够显示出它的作用。

    Linux 串口应用开发 page203
    在 Linux 中,所有的设备文件一般都位于“/dev”下,其中串口一、串口二对应的设备名依次为“/dev/ttyS0”、“/dev/ttyS1”,可以查看在“/dev”下的文件以确认。

    标准 I/O 开发 - 基于流缓冲
    标准 I/O 提供流缓冲的目的:尽可能减少使用 read 和 write 系统调用的次数
    打开文件函数:fopenfdopenfreopen
    fopen 可以指定打开文件的路径和模式,fdopen可以指定打开的文件描述符和模式,而 freopen 除可指定打开的文件、模式外,还可指定特定的 IO 流。
    关闭文件函数:fclose
    文件读写函数:fread fwrite
    输入输出函数:
        字符输入,getc/fgetc/getchar
        字符输出,putc/fputc/putchar
        // 这几个函数功能类似,其区别仅在于 getc 和 putc 通常被实现为宏,而 fgetc 和 fputc 不能实现为宏,因此,函数的实现时间会有所差别。
        行输入,gets/fgets
        行输出,puts/fputs
        // 行输入输出函数一次操作一行。
        格式化输入,scanf/fscanf/sscanf
        格式化输出,printf/fprintf/sprintf、vprintf/vfprintf/vsprintf
        // 格式化输入输出函数使用的是可变参数。
    /* 打开一个文件,然后将该文件上写入锁,并写入 hello 字符串。接着在解锁后再将该文件上读取锁,并读取刚才写入的内容。最后模拟多进程,同时读写一个文件时的情况。 expr1.c 实验源码*/
    #include <unistd.h>
    #include <sys/file.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    void lock_set(int fd, int type)
    {
        struct flock lock;
        lock.l_whence = SEEK_SET;//赋值 lock 结构体
        lock.l_start = 0;
        lock.l_len =0;
        while(1)
        {
            lock.l_type = type;
            /*根据不同的 type 值给文件上锁或解锁*/
            if((fcntl(fd, F_SETLK, &lock)) == 0){
                if( lock.l_type == F_RDLCK )
                printf("read lock set by %d\n",getpid());
            else if( lock.l_type == F_WRLCK )
                printf("write lock set by %d\n",getpid());
            else if( lock.l_type == F_UNLCK )
                printf("release lock by %d\n",getpid());
            return;
        }
        /*判断文件是否可以上锁*/
        fcntl(fd, F_GETLK,&lock);
        /*判断文件不能上锁的原因*/
        if(lock.l_type != F_UNLCK){
        /*/该文件已有写入锁*/
            if( lock.l_type == F_RDLCK )
                printf("read lock already set by %d\n",lock.l_pid);
            /*该文件已有读取锁*/
            else if( lock.l_type == F_WRLCK )
                printf("write lock already set by %d\n",lock.l_pid);
            getchar();
            }
        }
    }
    int main(void)
    {
        int fd,nwrite,nread,len;
        char *buff="Hello\n";
        char buf_r[100];
        len=strlen(buff);
        fd=open("hello",O_RDWR | O_CREAT, 0666);
        if(fd < 0){
            perror("open");
            exit(1);
        }
        /*加上写入锁*/
        lock_set(fd, F_WRLCK);
        if((nwrite=write(fd,buff,len))==len){
            printf("write success\n");
        }
        getchar();
        /*解锁*/
        lock_set(fd, F_UNLCK);
        getchar();
        /*加上读取锁*/
        lock_set(fd, F_RDLCK);
        lseek(fd,0,SEEK_SET);
        if((nread=read(fd,buf_r,len))==len){
            printf("read:%s\n",buf_r);
        }
        getchar();
        /*解锁*/
        lock_set(fd, F_UNLCK);
        getchar();
        close(fd);
        return 0;
    }
    // 同一个终端内运行测试,开两个终端运行测试多进程情况,测试结果均不会收到影响。

    【进程控制开发】


    进程创建:fork
    进程中启动进程:exec函数族(execve为系统调用,其他都为库函数)
    进程退出:exit/_exit
    进程阻塞等待:wait/waitpid

    守护进程Daemon编写 5 步骤:
    1. 创建子进程,父进程退出;fork/exit
        /*父进程退出*/
        pid=fork();
        if(pid>0){
            exit(0);
        }
    2. 在子进程中创建新会话;setsid
    3. 改变当前目录为根目录;chdir
    4. 重设文件权限掩码;umask
    5. 关闭文件描述符;close
    /* 守护进程需要关闭标准I/O MAXFILE==3 */
    for(i=0;i<MAXFILE;i++)
        close(i);
    汇总:开始 >> fork()/exit() >> setsid() >> chdir("/") >> umask(0) >> close >> 结束(守护进程创建)
    /* 实现守护进程的一个完整实例 */
    /*dameon.c 创建守护进程实例*/
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<fcntl.h>
    #include<sys/types.h>
    #include<unistd.h>
    #include<sys/wait.h>
    #define MAXFILE 65535
    int main()
    {
        pid_t pc;
        int i,fd,len;
        char *buf="This is a Dameon\n";
        len =strlen(buf);
        pc=fork(); // 第一步
        if(pc<0)
        {
            printf("error fork\n");
            exit(1);
        }else if(pc>0)
            exit(0);
        /*第二步*/
        setsid();
        /*第三步*/
        chdir("/");
        /*第四步*/
        umask(0);
        /*第五步*/
        for(i=0;i<MAXFILE;i++)
            close(i);
        /*这时创建完守护进程,以下开始正式进入守护进程工作*/
        while(1)
        {
            if((fd=open("/tmp/dameon.log",O_CREAT|O_WRONLY|O_APPEND,0600))<0)
            {
                perror("open");
                exit(1);
            }
            write(fd, buf, len+1);
            close(fd);
            sleep(10);
        }
    }
    // 该程序每隔 10s 就会在对应的文件中输入相关内容。
    守护进程的进程要如何调试呢?
    一种通用的办法是使用 syslog服务,将程序中的出错信息输入到" /var/log/messages "系统日志文件中,需要root权限,从而可以直观地看到程序的问题所在。

    系统日志函数:openlogsyslogcloselog
    openlog 函数用于打开系统日志服务的一个连接;syslog 函数是用于向日志文件中写入消息,在这里可以规定消息的优先级、消息输出格式等;closelog 函数是用于关闭系统日志服务的连接。

    【进程间通信】


    1. UNIX 进程间通信(IPC)方式包括管道、FIFO、信号。
    2. System V 进程间通信(IPC)包括 System V 消息队列、System V信号灯(信号量集)、System V共享内存区。
    3. Posix 进程间通信(IPC)包括 Posix 消息队列、Posix 信号灯(信号量集)、Posix 共享内存区。
    4. 基于socket的进程间通信。

    管道的创建和关闭:pipe/close
    管道的读写:read/write
    标准流管道:popen/pclose

    信号的发送:kill raise alarm pause
    信号的处理:signal / 信号量集函数组
    信号量集功能模块:
        创建信号集合,sigemptyset / sigfillset / sigaddset / sigdelset / sigismember
        登记信号处理器,sigprocmask / sigaction
        检测信号,sigpending
    共享内存:shmget / shmat/shmdt
    消息队列:msgget / msgsnd/msgrcv/msgctl

    【多线程通信】


    线程创建和退出:pthread_create / pthread_exit / pthread_join
    修改线程属性:pthread_attr_init / pthread_attr_setscope / pthread_attr_setdetachstate/pthread_attr_getschedparam/pthread_attr_setschedparam
    这些属性主要包括绑定属性、分离属性、堆栈地址、堆栈大小、优先级。
    线程同步:
        · 互斥锁初始化:pthread_mutex_init
        · 互斥锁上锁:pthread_mutex_lock
        · 互斥锁判断上锁:pthread_mutex_trylock
        · 互斥锁接锁:pthread_mutex_unlock
        · 销毁互斥锁:pthread_mutex_destroy
    信号量线程控制:PV操作
        · sem_init 用于创建一个信号量,并能初始化它的值。
        · sem_wait sem_trywait相当于 P 操作,它们都能将信号量的值减一,两者的区别在于若信号量小于零时,sem_wait 将会阻塞进程,而 sem_trywait 则会立即返回。
        · sem_post 相当于 V 操作,它将信号量的值加一同时发出信号唤醒等待的进程。
        · sem_getvalue 用于得到信号量的值。
        · sem_destroy 用于删除信号量。

    经典例程:生产者与消费者模型。

    【网络编程】


    TCP 对话通过三次握手来初始化的。
    三次握手的目的:使数据段的发送和接收同步,告诉其他主机其一次可接收的数据量,并建立虚连接。

    socket三种类型:
    (1)流式 socket(SOCK_STREAM
    流式套接字提供可靠的、面向连接的通信流;它使用 TCP 协议,从而保证了数据传输的正确性和顺序性。
    (2)数据报 socket(SOCK_DGRAM
    数据报套接字定义了一种无连接的服务,数据通过相互独立的报文进行传输,是无序的,并且不保证是可靠、无差错的。它使用数据报协议 UDP。
    (3)原始 socket
    原始套接字允许对底层协议如 IP 或 ICMP 进行直接访问,它功能强大但使用较为不便,主要用于一些协议的开发。

    网络字节序与主机字节序的转化:htonsntohshtonlntohl
    //  h 代表 host,n 代表 network,s 代表 short,l 代表 long。通常 16 位的 IP 端口号用 s 代表,而 IP 地址用 l 来代表。
    地址格式转化:IPv4,inet_atoninet_addrinet_ntoa;IPv4和IPv6兼容函数,inet_ptoninet_ntop
    主机名和地址的转化:gethostbynamegethostbyaddrgetaddrinfo
    Struct hostent{
        char *h_name;/*正式主机名*/
        char **h_aliases;/*主机别名*/
        int h_addrtype;/*地址类型*/
        int h_length;/*地址长度*/
        char **h_addr_list;/*指向 IPv4 或 IPv6 的地址指针数组*/
    }
    
    struct addrinfo{
        int ai_flags;/*AI_PASSIVE,AI_CANONNAME;*/
        int ai_family;/*地址族*/
        int ai_socktype;/*socket 类型*/
        int ai_protocol;/*协议类型*/
        size_t ai_addrlen;/*地址长度*/
        char *ai_canoname;/*主机名*/
        struct sockaddr *ai_addr;/*socket 结构体*/
        struct addrinfo *ai_next;/*下一个指针链表*/
    }

    socket编程基本函数:socketbindlistenacceptsendsendtorecvrecvfrom

    网络高级编程:fcntl
        · 非阻塞 I/O:可将 cmd 设置为 F_SETFL,将 lock 设置为 O_NONBLOCK。
        · 信号驱动 I/O:可将 cmd 设置为 F_SETFL,将 lock 设置为 O_ASYNC。

    网络高级编程:select
        使用 select 函数还可以设置等待的时间,减少CPU资源浪费。详解可单独查阅专题。


    展开全文
  • linux 下 syslog 系统日志应用

    千次阅读 2012-10-10 08:02:12
    syslog 系统日志应用  1) 概述  syslog是Linux系统默认的日志守护进程。默认的syslog配置文件是/etc/syslog.conf文件。程序,守护进程和内核提供了访问系统的日志信息。因此,任何希望生成日志信息的程序都可以...

    syslog 系统日志应用
     1) 概述
          syslog是Linux系统默认的日志守护进程。默认的syslog配置文件是/etc/syslog.conf文件。程序,守护进程和内核提供了访问系统的日志信息。因此,任何希望生成日志信息的程序都可以向 syslog 接口呼叫生成该信息。
          几乎所有的网络设备都可以通过syslog协议,将日志信息以用户数据报协议(UDP)方式传送到远端服务器,远端接收日志服务器必须通过syslogd监听UDP 端口514,并根据 syslog.conf配置文件中的配置处理本机,接收访问系统的日志信息,把指定的事件写入特定文件中,供后台数据库管理和响应之用。意味着可以让任何事件都登录到一台或多台服务器上,以备后台数据库用off-line(离线) 方法分析远端设备的事件。
          通常,syslog 接受来自系统的各种功能的信息,每个信息都包括重要级。/etc/syslog.conf 文件通知 syslogd 如何根据设备和信息重要级别来报告信息。

     2) etc/syslog.conf
          /etc/syslog.conf 文件使用下面的格式:
          facility.level    action
          facility.level为选择条件本身分为两个字段,之间用一个小数点(.)分隔。前一字段是一项服务,后一字段是一个优先级。选择条件其实是对消息类型的一种分类,这种分类便于人们把不同类型的消息发送到不同的地方。在同一个syslog配置行上允许出现一个以上的选择条件,但必须用分号(;)把它们分隔开。action字段所表示的活动具有许多灵活性,特别是,可以使用名称管道的作用是可以使 syslogd 生成后处理信息。
          要素分析:
    facility 指定 syslog 功能,主要包括以下这些:
    kern     内核信息,首先通过 klogd 传递;
    user     用户进程;
    mail     邮件;
    daemon   后台进程;
    authpriv 授权信息;
    syslog   系统日志;
    lpr      打印信息;
    news     新闻组信息;
    uucp     由uucp生成的信息
    cron     计划和任务信息。
    mark     syslog 内部功能用于生成时间戳
    local0----local7   与自定义程序使用,例如使用 local5 做为 ssh 功能
    *        通配符代表除了 mark 以外的所有功能

          level 指定syslog优先级:
          syslog 级别如下:(按严重程度由高到低的顺序列出了所有可能的优先级。)
    emerg 或 panic   该系统不可用(最紧急消息)
    alert            需要立即被修改的条件(紧急消息)
    crit             阻止某些工具或子系统功能实现的错误条件(重要消息)
    err              阻止工具或某些子系统部分功能实现的错误条件(出错消息)
    warning          预警信息(警告消息)
    notice           具有重要性的普通条件(普通但重要的消息)
    info             提供信息的消息(通知性消息)
    debug            不包含函数条件或问题的其他信息(调试级-信息量最多)
    none             没有重要级,通常用于排错(不记录任何日志消息)
    *                所有级别,除了none
    Application 中定义level:
       0: LOG_EMERG
       1: LOG_ALERT
       2: LOG_CRIT
       3: LOG_ERR
       4: LOG_WARNING
       5: LOG_NOTICE
       6: LOG_INFO
       7: LOG_DEBUG
    kernel中定义level(使用printk函数设定level):
       0: KERN_EMERG, 系統無法使用
       1: KERN_ALERT, 必須立即執行
       2: KERN_CRIT, 緊急狀態
       3: KERN_ERR, 錯誤狀態
       4: KERN_WARNING, 警告狀態
       5: KERN_NOTICE, 正常狀態且十分重要
       6: KERN_INFO, 報告
       7: KERN_DEBUG, debug-level訊息

    例子:
    “mail.*”将发送所有的消息,“mail.!info”把info优先级的消息排除在外。
    mail.*;mail.!info /var/log/mail  
    下面的规则指定Facility为mail,Severity为err以上级别的日志写入/var/log/mail.err文件,而err以下级别的日志则被忽略:
    mail.err                        /var/log/mail.err
    facility和level可以使用通配符,也可以指定多个,用逗号隔开:
    auth,authpriv.*                 /var/log/auth.log
    Facility和level的组合可以有多个,用分号隔开,文件前面加一个减号表示日志不立即写入文件,而是在缓冲中积攒到一定的条件再写,这样 可以提高性能,但是当机可能会丢失数据:
    *.*;auth,authpriv.none          -/var/log/syslog 
    可以把syslog消息通过UDP发送到syslog服务器的514端口:
    *.err    @192.168.0.1
    发生错误时,在控制台打屏:
    *.err    /dev/console

     

          linux日志管理:
          内核信息 -> klogd -> syslogd -> /var/log/messages等文件
          其他信息 -> syslogd -> /var/log/messages等文件
          syslog配置文件 -> /etc/syslog.conf

     3) 调用 syslogd 守护程序
          syslog 守护程序是由 /etc/rc.d/init.d/syslog 脚本在运行级2下被调用的,缺省不使用选项。但有两个选项 -r 和 -h 很有用。
          如果将要使用一个日志服务器,必须调用 syslogd -r。缺省情况下 syslog 不接受来自远程系统的信息。当指定 -r 选项,syslogd 将会监听从 514 端口上进来的 UDP 包。
          如果还希望日志服务器能传送日志信息,可以使用 -h 标志。缺省时,syslogd 将忽略使其从一个远程系统传送日志信息到另一个系统的/etc/syslog.conf 输入项。

     4) klogd 守护进程
          klogd 守护进程获得并记录 Linux 内核信息。通常,syslogd 会记录 klogd 传来的所有信息,然而,如果调用带有 -f filename 变量的 klogd 时,klogd 就在 filename 中记录所有信息,而不是传给syslogd。当指定另外一个文件进行日志记录时,klogd 就向该文件中写入所有级别或优先权。Klogd 中没有和 /etc/syslog.conf 类似的配置文件。使用 klogd 而避免使用 syslogd 的好处在于可以查找大量错误。如果有人入侵了内核,使用 klogd 可以修改错误。

     5) 配置一个中央日志服务器 
    1.  编辑/etc/sysconfig/syslog文件。
          在“SYSLOGD_OPTIONS”行上加“-r”选项以允许接受外来日志消息。如果因为关于其他机器的DNS记录项不够齐全或其他原因不想让中央日志服务器解析其他机器的FQDN,还可以加上“-x”选项。此外,你或许还想把默认的时间戳标记消息(--MARK--)出现频率改成比较有实际意义的数值,比如240,表示每隔240分钟(每天6次)在日志文件里增加一行时间戳消息。日志文件里的“--MARK--”消息可以让你知道中央日志服务器上的 syslog守护进程没有停工偷懒。按照上面这些解释写出来的配置行应该是如下所示的样子:
        SYSLOGD_OPTIONS="-r-x-m240"
    2.  重新启动syslog守护进程。

          修改只有在syslog守护进程重新启动后才会生效。如果你只想重新启动syslog守护进程而不是整个系统,执行以下两条命令之一:
    /etc/rc.d/init.d/syslog stop;   /etc/rc.d/init.d/syslog start
    /etc/rc.d/init.d/syslog restart 
    3.  如果这台机器上运行着iptables防火墙或TCPWrappers,请确保它们允许514号端口上的连接通过。syslog守护进程要用到514号端口。 
    4.  为中央日志服务器配置各客户机器
          让客户机把日志消息发往一个中央日志服务器并不困难。编辑客户机上的/etc/syslog.conf文件,在有关配置行的操作动作部分用一个“@”字符指向中央日志服务器,如下所示:
    authpriv.*@192.168.1.40
          另一种办法是在DNS里定义一个名为“loghost”的机器,然后对客户机的syslog配置文件做如下修改(这个办法的好处是:当你把中央日志服务器换成另一台机器时,不用再修改每一个客户机上的syslog配置文件)

    authpriv.*@loghost
          接下来,重新启动客户机上的syslog守护进程让修改生效。让客户机在往中央日志服务器发送日志消息的同时继续在本地进行日志工作仍有必要,起码在调试客户机的时候不必到中央日志服务器查日志,在中央日志服务器出问题的时候还可以帮助调试。

     6)与系统日志相关的函数:
    openlog, syslog, closelog是一套系统日志写入接口。
    程序的用法示例代码如下:syslog.c

    [c-sharp] view plaincopy
    1. //syslog.c  
    2. #include <syslog.h>  
    3. int main(int argc, char **argv)  
    4. {  
    5.     openlog("MyMsgMARK", LOG_CONS | LOG_PID, 0);  
    6.     syslog(LOG_EMERG,  
    7.            "This is a syslog test message generated by program '%s'/n",  
    8.            argv[0]);  
    9.     closelog();  
    10.     return 0;  
    11. }  


    编译运行:

    [root@localhost liuxltest]# gcc -o syslog syslog.c

    [root@localhost liuxltest]# ./syslog

    [root@localhost liuxltest]# 
    Message from syslogd@ at Tue Feb 24 13:24:34 2009 ...
    localhost MyMsgMARK[16467]: This is a syslog test message generated by program './syslog'

    同时,你也可以在/var/log/messages中看到信息如下:

    Feb 24 13:24:34 localhost MyMsgMARK[16467]: This is a syslog test message generated by program './syslog'


    函数说明:
    openlog函数原型如下:
    void openlog(const char *ident, int option, int facility);
        此函数用来打开一个到系统日志记录程序的连接,打开之后就可以用syslog或vsyslog函数向系统日志里添加信息了。
        参数说明:
        ident:是一个标记,ident所表示的字符串将固定地加在每行日志的前面以标识这个日志,通常就写成当前程序的名称以作标记。
        option:是下列值取与运算的结果:LOG_CONS, LOG_NDELAY, LOG_NOWAIT, LOG_ODELAY,

    LOG_PERROR, LOG_PID,各值意义请参考man openlog手册:
           LOG_CONS
                  Write directly to system console if there is an error while sending to system

    logger.
           LOG_NDELAY
                  Open the connection immediately (normally, the connection is opened when the

    first message is logged).
           LOG_PERROR
                  (Not in SUSv3.) Print to stderr as well.
           LOG_PID
                  Include PID with each message.
        facility:指明记录日志的程序的类型。
    closelog函数原型如下:
    void  closelog(void )
        此函数就是用来关闭openlog打开的连接的。
    syslog函数原型如下:    
    void  syslog(int priority, const char *format, ...);      
        此函数用于把日志消息发给系统程序syslogd去记录。
        参数说明:
        priority:是消息的紧急级别;
        format:是消息的格式,之后是格式对应的参数。就是printf函数一样使用。
    应用:
        如果我们的程序要使用系统日志功能,只需要在程序启动时使用openlog函数来连接syslogd程序,后面随时用syslog函数写日志就行了。
        另外,作为syslog的替代程序的新一代工具是syslog-ng,syslog-ng具有很强的网络功能,可以方便地把多台机器上的日志保存到一台中心日志服务器上。


    展开全文
  • 守护进程是一种很有用的进程,Linux的大多数服务器就是用守护进程实现的。比如,Internet服务器inetd,Web服务器httpd等。同时,守护进程完成许多系统任务。比如,作业规划进程crond、打印进程lpd等。 1 守护进程...

     (2009-10-22)


           守护进程(daemon)是运行在后台,并且一直在运行的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。守护进程是一种很有用的进程,Linux的大多数服务器就是用守护进程实现的。比如,Internet服务器inetd,Web服务器httpd等。同时,守护进程完成许多系统任务。比如,作业规划进程crond、打印进程lpd等。

    1 守护进程及其特性

            守护进程最重要的特性是后台运行。其次,守护进程必须与其运行前的环境隔离开来。这些环境包括未关闭的文件描述符,控制终端,会话和进程组,工作目录以及文件创建掩码等。这些环境通常是守护进程从执行它的父进程(特别是shell)中继承下来的。最后,守护进程的启动方式有其特殊之处。它可以在Linux系统启动时从启动脚本/etc/rc.d中启动,也可以由作业规划进程crond启动,还可以由用户终端(通常是shell)执行。
            总之,除了这些特殊性以外,守护进程与普通进程基本上没有什么区别。因此,编写守护进程实际上是把一个普通进程按照上述的守护进程的特性改造成为守护进程。如果读者对前面进程控制编程有比较深入的认识,就更容易理解和编写守护进程了。
           请读者了解一下,在Linux环境下有哪些内核守护进程。通过ps-aux命令就可查看Linux环境下的守护进程了。
    1)Init系统守护进程:它是进程1,负责启动各运行层次特定的系统服务。这些服务通常是在它们自己拥有的守护进程的帮助下实现的。
    2)Keventd守护进程:为在内核中运行计划执行的函数提供进程上下文。
    3)Kswapd守护进程:也称为页面调出守护进程。它将脏页面低速写到磁盘上,从而使这些页面在需要时仍可回收使用,这种方式支持虚存子系统。
    4)bdflush和kupdated守护进程:Linux内核使用两个守护进程,即bdflush和kupdated,将调整缓存中的数据冲洗到磁盘上。当可用内存达到下限时,bdflush守护进程将脏缓冲区从缓冲池中冲洗到磁盘上,每隔一定时间间隔,kupdated守护进程将脏页面冲洗到磁盘上,以便在系统失效时减少丢失的数据。
    5)portmap端口映射守护进程:提供将RPC(远程过程调用)程序号映射为网络端口号的服务。
    6)syslogd守护进程:可由帮助操作人员把系统消息记入日志的任何程序使用。
    7)inetd守护进程(xinetd):它侦听系统网络接口,以便取得来自网络的对各种网络服务进程的请求。
    8)nfsd、lockd、rpciod守护进程:提供对网络文件系统(NFS) 的支持。
    9)cron守护进程:在指定的日期和时间执行指定的命令。许多系统管理任务是由cron定期地执行相关程序而实现的。
    10)cupsd守护进程:是打印假脱机进程,它处理对系统提出的所有打印请求。

    Tips:大多数守护进程都以超级用户(用户ID0)特权运行,并且在后台运行,其所对应的终端号显示为问号(?)。

    2 编写守护进程的要点

    (1)创建子进程,终止父进程
        由于守护进程是脱离控制终端的,因此首先复制子进程,终止父进程,使得程序在shell终端里造成一个已经运行完毕的假象。之后所有的工作都在子进程中完成,而用户在shell终端里则可以执行其他的命令,从而使得程序以僵尸进程形式运行,在形式上做到了与控制终端的脱离。
        创建子进程,终止父进程的代码如下:
    pid=fork();
    if(pid>0)
      {exit(0);}    /*终止父进程*/

    (2)在子进程中创建新会话
            这个步骤是创建守护进程中最重要的一步,虽然它的实现非常简单,在这里使用的是系统函数setsid。
           setsid函数用于创建了一个新的会话,并担任该会话组的组长。调用setsid有下面三个作用:让进程摆脱原会话的控制、让进程摆脱原进程组的控制和让进程摆脱原控制终端的控制。
            在调用fork函数时,子进程全盘拷贝父进程的会话期、进程组、控制终端等,虽然父进程退出了,但原先的会话期、进程组、控制终端等并没有改变,因此,还不是真正意义上独立开来,而setsid函数能够使进程完全独立出来,从而脱离所有其他进程的控制。
    (3)改变工作目录
            使用fork创建的子进程也继承了父进程的当前工作目录。由于在进程运行过程中,当前目录所在的文件系统不能卸载。因此,把当前工作目录换成其他的路径,如“/”或“/tmp”等。改变工作目录的常见函数是chdir。
    (4)重设文件创建掩码
            文件创建掩码是指屏蔽掉文件创建时的对应位。由于使用fork函数新建的子进程继承了父进程的文件创建掩码,这就给该子进程使用文件带来了诸多的麻烦。因此,把文件创建掩码设置为0,可以大大增强该守护进程的灵活性。设置文件创建掩码的函数是umask。在这里,通常的使用方法为umask(0)。
    (5)关闭文件描述符
            用fork函数新建的子进程会从父进程那里继承一些已经打开了的文件。这些被打开的文件可能永远不会被守护进程读或写,但它们一样消耗系统资源,而可能导致所在文件系统无法卸载。
            通常按如下方式关闭文件描述符:
    for(i=0;i<NOFILE;i++)
         close(i);
    或者也可以用如下方式:
    for(i=0;i<MAXFILE;i++)
         close(i);

    Tips:父进程创建了子进程,而父进程退出之后,此时该子进程就变成了“孤儿进程”。在Linux中,每当系统发现一个孤儿进程,就会自动由1号进程(也就是init进程)收养它,原先的子进程就会变成init进程的子进程了。

    3 守护进程的编写

    根据第2节的编写要点就可以编制具体的守护进程程序了,具体例子可参考文后的实验二则。

    Tips:在编写守护进程的调试过程中会发现,程序运行成为守护进程后,完全脱离控制终端,调试的时候没法像普通程序调试一样,在终端中看到错误信息,甚至用gdb也无法正常调试。在Linux系统中,编写调试守护进程,一般是利用系统的日志服务,通过系统守护进程syslogd控制自己编写的守护进程的告警信息。LinuxC语言中,只要调用syslog函数,将守护进程的出错信息写入“/var/log/messages”系统日志文件,就可以做到这一点。

    --------------------------------------------------------------------------------------------------------------------------------------------------

    【实验1】

             编写一程序,要求运行后成为守护进程,复制守护进程的子进程,子进程往某个文件里写入字符串“测试守护进程”,守护进程的错误信息输出到系统日志文件“/var/log/messages”。请把产生守护进程的部分分割成独立的程序文件。

    参考代码

    (1)init.c

    #include<stdio.h>
    #include<stdlib.h>
    #include<sys/types.h>
    #include<unistd.h>
    #include<sys/wait.h>
    #include<syslog.h>
    #include<signal.h> 
    #include<sys/param.h> 
    #include<sys/stat.h> 
    void init_daemon(void)
    {
    	pid_t child0;
    	int i;
    	openlog("1-1程序信息",LOG_PID,LOG_DAEMON);
    	child0=fork();
    	if(child0>0)
    		exit(0);
    	else if(child0<0)
    	{
    		syslog(LOG_INFO,"创建守护进程失败");
    		exit(1);
    	}
    	setsid();
    	chdir("/tmp");
    	umask(0);
    	for(i=0;i< NOFILE;++i)    
    		close(i);
    	return;
    }
    


    (2)1-1.c

    #include<stdio.h>
    #include<stdlib.h>
    #include<sys/types.h>
    #include<unistd.h>
    #include<sys/wait.h>
    #include<syslog.h>
    #include<signal.h>
    #include<sys/param.h>
    #include<sys/stat.h>
    void init_daemon(void);
    int main()
    {
    	FILE *fp;
    	pid_t child;
    	init_daemon();
    	openlog("",LOG_PID,LOG_DAEMON);
    	child=fork();
    	if(child<0)
    	{
    		syslog(LOG_INFO,"创建子进程失败");
    		exit(1);
    	}
    	else if(child==0)
    	{
    		while(1)
    		{
    			sleep(5);
    			if((fp=fopen("test.txt","a+"))>0)
    			{
    				fprintf(fp,"测试守护进程\n");
    				fclose(fp);
    			}
    			else
    				syslog(LOG_INFO, "打开文件失败"); 
    		}
    	}
    	else
    	{
    		waitpid(child,NULL,0);
    		while(1)
    		{
    			sleep(10);
    		}
    	}
        return 0;
    }
    


    (3)编译成可执行目标1-1:

    gcc init.c 1-1.c -o 1-1

     

    【实验2】

             编写一程序,要求运行后成为守护进程,每隔5分钟修改一次本机的IP地址。所有的IP地址分行放在一个文本文件中,每隔5分钟随机读取一个,Linux C中可以用“ioctl”和“sysctl”函数实现,也可以调用系统命令“ifconfig”,例如“ifconfig eth0 192.168.0.20 netmask 255.255.255.0”。

     参考代码

     1-2.c

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<fcntl.h>
    #include<time.h>
    #include<sys/types.h>
    #include<unistd.h>
    #include<sys/wait.h>
    #include<syslog.h>
    #include<signal.h> 
    #include<sys/param.h> 
    #include<sys/stat.h> 
    int main()
    {
    	FILE *fp;
    	pid_t child;
    	int i,lines,line,move;
    	char str[20],command[100];
    	child=fork();
    	if(child>0)
    		exit(0);
    	else if(child<0)
    	{
    		perror("创建子进程失败");
    		exit(1);
    	}
    	setsid();                 
    	chdir("/tmp");             
    	umask(0);                 
    	for(i=0;i< NOFILE;++i)   
    		close(i);
    	fp=fopen("ip.txt","r");
    	if(fp<=0)
    	{
    		perror("打开文件失败");
    		exit(1);
    	}
    	lines=0;
    	while(fscanf(fp,"%s",&str)!=EOF)
    	{
    		lines++;
    	}
    	while(1)
    	{
    		fseek(fp,0,SEEK_SET);
    		srand((int)time(0));
    		line=rand()%lines+1;
    		move=0;
    		while(move<line)
    		{
    			fscanf(fp,"%s",&str);
    			move++;
    		}
    		strcpy(command,"ifconfig eth0 ");
    		strcat(command,str);
    		strcat(command," netmask 255.255.255.0");
    		system(command);
    		sleep(5*60);
    	}
    	fclose(fp);
        return 0;
    }
    



     


     

    展开全文
  • Linux分析日志

    2021-02-11 02:45:02
    目录标题日志的功能日志文件的分类系统日志保存位置主要日志文件介绍查看主配置文件/etc/rsyslog.conf内核日志消息的级别由系统服务rsyslog统一管理日志记录的一般格式用户日志分析程序日志分析日志管理策略 ...
  • Linux系统日志管理

    2020-08-06 20:43:45
    常见的日志文件(系统、进程、应用程序)3.rsyslogd配置3.1相关程序3.2启动程序3.3相关文件4.主配置文件三.任务二详解 一.简介 任务一:rsyslog系统日志管理 哪类程序—》产生的什么日志—》放到什么地方 任务二:...
  • 入门linux基础之日志管理篇

    千次阅读 2020-03-03 21:09:43
    第二类日志:httpd/nginx/mysql :各类应用程序,可以以自己的方式记录日志。 查看rsyslogd程序进程 ps aux | grep rsyslogd 日志文件(messages,httpd/access.log),存放日志的目录 /var/log,日...
  • solaris porting linux
  • linux log rotation日志滚动详解

    千次阅读 2020-03-27 01:02:12
    Linux 系统会每隔一天(或间隔更长的时间)或根据日志文件的大小自动进行一次日志滚动。如果你需要滚动日志以释放存储空间,又或者将某一部分日志从当前的活动中分割出来,这很容易做到,具体要取决于文件滚动规则 ...
  • Linux日志管理   对运维人员来说,无论管理什么系统,对日志文件的监控、调用、管理都是其中重要的一部分。服务器问题的解决都是从查看系统(错误)日志开始的。本篇文章,我们就来了解一下Linux系统中的日志管理...
  • linux日志基础知识

    2016-08-06 21:52:56
    大致可以分为系统日志、程序日志、用户日志三类 系统日志:包括/var/log/{secure,cron,maillog,dmesg,boot.log}等,具体可以通过cat /etc/rsyslog.conf 查看;这些日志文件统一由系统服务rsyslog管理; rsyslog 安装...
  • Linux 日志管理

    千次阅读 2020-02-27 18:08:26
    rsyslog 系统日志管理 一、处理日志的进程 第一类: rsyslogd: 系统专职日志程序。 处理绝大部分日志记录, 系统操作有关的信息,如登录信息,...二、常见的日志文件(系统、进程、应用程序) # tail -10 /var/log/...
  • 就让我们用这篇移植技术指导向您展示如何将 Solaris 应用程序移植到 Linux 平台上吧。 移植概述 移植过程本身非常简单: 1. 清理代码和头文件,并删除与体系结构相关的部分和非标准做法。2. 编译代码,并修正在编译
  • Linux日志文件

    2020-12-30 15:24:22
    日志文件 日志的功能 ...由各种应用程序独立管理的日志文件,记录格式不统一 日志保存位置 默认位于: /var/log目录下 内核及系统日志由系统服务rsyslog 统一管理,主配置文件为/etc/rsyslog.conf Li
  • linux的系统日志rsyslog

    千次阅读 2017-11-23 12:53:49
     Linux保存了系统中所发生事件的详细记录,这些记录称作日志文件或消息文件。可以查阅日志文件来确定系统当前状态,观察入侵者踪迹,寻找某特定程序(或事件)相关的数据。centos6使用rsyslog替代syslog来 二。...
  • Linux日志概述一、日志的功能二、常见日志文件的位置及记录内容三、日志记录的一般格式四、常用日志概述4.1 内核及系统日志4.1.1 查看rsyslog.conf 配置文件4.1.2 Linux系统内核日志消息的优先级别4.2 用户日志4.3 ...
  • linux系统日志概念及rsyslog服务配置 日志是什么 日志是系统用来记录系统运行时候的一些相关信息的纯文本文件 日志的目的是为了保存...应用程序信息 Rsyslog linux系统中用来实现日志功能的服务称之为rsysl...
  • 移植概述移植过程本身非常简单: 清理代码和头文件,并删除与体系结构相关的部分和非标准做法。... 移植指导移植 Solaris 应用程序至少需要两个平台:一个源平台和一个(或多个)Linux 目标平台。在将应用程序
  • 应用程序(httpd,mysql) 3.rsyslog程序管理 安装:yum install -y rsyslog 启动:systemctl start rsyslog 查询:systemctl status rsyslog 查询:ps aux | grep rsyslog 4.rsyslog程序,维护配置文件 升级:yum ...
  • 并行启动应用程序从而加速 Linux 的引导 使用 initng 和 upstart 级别: 中级 M. Tim Jones (mtj@mtjones.com), 顾问工程师, Emulex
  • 日志文件对于诊断和解决系统中的问题很有帮助,因为在 Linux 操作系统中运行的程序 通常会把系统消息和错误消息写入相应的日志文件,这样系统一旦出现问题就会“有据可查”。 此外,当主机遭受攻击时,日志文件还...
  • 第二类:httpd/nginx/mysql: 各类应用程序,可以以自己的方式记录日志。 2、常见的日志文件(系统、进程、应用程序) # tail -f /var/log/messages //动态查看日志文件的尾部 # tailf /var/log/secure //认证、...
  • Linux nohup不输出日志文件的方法

    万次阅读 2018-11-16 11:37:39
    最近在Linux上部署视频流推送应用时,由于网络不稳定等原因程序会不断的输出错误信息,结果导致程序运行一天下来日志文件直接占满磁盘,解决方法就是不再输出日志文件,命令如下: 只输出错误信息到日志文件: ...
  • Linux日志管理227

    2020-02-27 23:01:27
    在千峰学习的第18天,今天我学习了Linux中的日志管理,知道了各种程序日志的存放位置,还有日志轮转。 善读者日攻、日扫。攻则直透重围,扫则了无一物。 日志进程rsyslog /var/log/messages //系统主日志文件 /...
  • 本文描述linux程序开发中返回的错误码具体含义和查询方式。
  • linux_日志管理和轮转

    千次阅读 2020-02-27 21:41:53
    那类程序会产生哪些日志要给放到哪里 logrotate 日志的轮转 将大量的日志分割管理,删除旧日志 处理日志的进程 第一类 rsyslog 系统专职日志程序 处理绝大部分的日志程序 系统有关的信息,如登陆信息,程序启动关闭...
  • Linux 日志系统组成详解

    千次阅读 2017-10-07 09:58:08
     Linux 系统日志文件的标准格式: 事件发生的时间 哪台主机的日志 产生日志信息的系统 系统发生的事件。 它们各字段之间使用空格隔开。说明: 事件发生的时间: Jun 12 10:01:01 哪台主机的日志: node2 产生...
  • Linux(Centos7)日志管理

    万次阅读 2018-08-04 11:12:56
    日志管理 处理日志的进程 ...应用程序日志:各类应用程序以自己的方式记录的日志。 常见日志文件 # tail /var/log/messages //系统主日志文件 # tail -20 /var/log/messages # tail -f /var/log/m...
  • 处理日志的进程分为两类:rsyslog和各类应用程序 启动程序: sysemctl start rsyslog.service 系统的日志文件查看: tailf /var/log/messages 查看相关的文件:rpm -qc rsyslog 规则:设备.级别 文件路径 查看配置...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 41,238
精华内容 16,495
关键字:

linux应用程序日志丢失

linux 订阅