Andy Niu �����ĵ�

Andy Niu

Andy Niu Help  1.0.0.0
Linux

模块

 Awk
 
 Cmake
 
 Flawfinder
 
 Gdb
 
 Git
 
 Grep
 
 Help
 
 IO多路复用
 
 Iptables
 
 Linux版本
 
 Nm
 
 Ntp
 
 Sed
 
 Shell变量
 
 Ssh
 
 Ubuntu
 
 Vim
 
 启动关机
 
 常用的服务
 
 常见问题
 
 打包和压缩
 
 文件与目录
 
 文件系统和目录树
 
 用户管理
 
 管道和管道命令
 
 编译
 
 网络有关
 
 进程管理
 

变量

 dmesg
 
 lsof
 
 read
 
 strace
 
 top命令详解
 
 valgrind
 
 Linux数据流重定向
 
 日期时间
 

详细描述

变量说明

dmesg
1、dmesg【dmessage】显示内核缓冲区信息,包括设备启动,系统架构,cpu,挂载的硬件,网线连接等重要系统信息。
2、通过dmesg常常诊断设备的故障,dmesg常常结合管道和其它命令一起使用,比如more,less,head,tail
参见
Linux数据流重定向
1、标准输出:代码是1,使用>和>>,前者是覆盖,后者是追加。
    xxx > aaa.txt 
    xxx >> aaa.txt
2、对于错误的数据,需要使用标准错误输出,标准错误输出:代码是2,使用2>和2>>
3、正常信息和错误信息输出到不同的文件,如下:
    xxx >info.txt 2>err.txt
4、正常信息和错误信息输出到同一个文件,
    xxx >info.txt 2>info.txt 是错误的写法,info.txt的内容会乱掉。正确的写法是:
    xxx >info.txt 2>&1
5、如果信息既不想显示也不想存储呢,比如操作的历史记录,为了安全,不想存储。怎么办?
    使用黑洞设备,xxx >/dev/null 2>&1
6、标准输入,代码是0,使用<和<<,解决的问题将原本需要键盘输出的数据,改由从文件读取。
7、cat >tmp.txt 从键盘输入数据到tmp.txt,ctrl+d结束输入。如果从其他文件读取,是:cat >tmp.txt <aaa.txt。
8、标准输入,<<表示遇到某个输入,结束输入。如下:
    [root@localhost home]# cat >tmp.txt <<'0'
    > aaa
    > bbb
    > 0
    [root@localhost home]# 
    输入0之后,按下enter 就结束了输入,不需要ctrl+d退出输入。
lsof
1、lsof list open file 列出系统打开的文件
2、对于父进程监听的端口转移到子进程的例子,使用lsof可以查看相关的信息,如下:
    [root@localhost niu]# netstat -anp|grep 9000
    tcp        0      0 0.0.0.0:9000                0.0.0.0:*                   LISTEN      5334/main           
    [root@localhost niu]# lsof -p5334
    COMMAND  PID USER   FD   TYPE  DEVICE    SIZE    NODE NAME
    main    5334 root  cwd    DIR     8,2    4096 4547126 /home/niu/socket
    main    5334 root  rtd    DIR     8,2    4096       2 /
    main    5334 root  txt    REG     8,2    9025 4547150 /home/niu/socket/main
    main    5334 root  mem    REG     8,2  125736 1932033 /lib/ld-2.5.so
    main    5334 root  mem    REG     8,2 1611564 1932046 /lib/libc-2.5.so
    main    5334 root  mem    REG     8,2  208352 1932058 /lib/libm-2.5.so
    main    5334 root  mem    REG     8,2  936908  207797 /usr/lib/libstdc++.so.6.0.8
    main    5334 root  mem    REG     8,2   46636 1932061 /lib/libgcc_s-4.1.2-20080825.so.1
    main    5334 root    0u   CHR   136,4               6 /dev/pts/4
    main    5334 root    1u   CHR   136,4               6 /dev/pts/4
    main    5334 root    2u   CHR   136,4               6 /dev/pts/4
    main    5334 root    3u  IPv4 1191891             TCP *:cslistener (LISTEN)
    [root@localhost niu]# lsof -i:9000
    COMMAND  PID USER   FD   TYPE  DEVICE SIZE NODE NAME
    main    5334 root    3u  IPv4 1191891       TCP *:cslistener (LISTEN)
    test.sh 5335 root    3u  IPv4 1191891       TCP *:cslistener (LISTEN)
    ping    5336 root    3u  IPv4 1191891       TCP *:cslistener (LISTEN)
3、lsof -p5334查看进程打开的文件,包括工作目录,可执行文件,文件描述符,0,1,2,3
    分别是:0[标准输入],1[标准输出],2[错误输出],3[Socket监听文件]
4、lsof -i:9000查看哪些进程监听端口9000,在没有使用close-on-exec的情况下,可以看到父子进程关系的3个进程都在打开同一个文件
    也就是监听端口9000,而使用netstat -anp|grep 9000只能看到父进程。
5、如果使用了close-on-exec,lsof -i:9000 只有父进程打开文件,如下:
    [root@localhost niu]# netstat -anp|grep 9000
    tcp        0      0 0.0.0.0:9000                0.0.0.0:*                   LISTEN      5776/main           
    [root@localhost niu]# lsof -i:9000
    COMMAND  PID USER   FD   TYPE  DEVICE SIZE NODE NAME
    main    5776 root    3u  IPv4 1196591       TCP *:cslistener (LISTEN)
参见
read
1、考虑下面的需求,在shell脚本运行过程中,提示用户输入,并且打印,也就是与用户进行交互。
    使用read如下:
    #! /bin/sh
    read -p "please input your name: " name
    echo "hello $name, welcome"
2、检查用户的输入,如果名字太短,提示重新输入,直到满足要求。如下:
    #! /bin/sh
    read -p "please input your name: " name
    
    while [ ${#name} -lt 4 ]
    do
            echo "sorry, your name is too short"
            read -p "try input again: " name
    done
    
    echo "hello $name, welcome"
3、如果用户没有输入,就一直卡在这里,怎么解决?
    给出超时时间,没有输入,直接跳过去。如下:
    #! /bin/sh
    read -t5 -p "please input your name: " name
    echo "hello $name, welcome"
4、考虑输入密码,密码的位数最长是6位,输入6位后,直接返回,不等待输入enter,如下:
    #! /bin/sh
    read -n6 -p "please input your passwd: " passwd
    echo "hello, password is $passwd"
5、对于密码的输入,用户不期望显示输入的内容,使用-s 默读,如下:
    #! /bin/sh
    read -s -p "please input your passwd: " passwd
    echo "hello, password is $passwd"
参见
strace
1、strace跟踪进程运行时的系统调用和所接受的信息。
2、举例来说,示例代码:
    #include <stdio.h>
    int main(int argc, char* argv[])
    {
            printf("hello,world\n");
            getchar();
            return 0;
    }
3、运行strace ./main,如下:
    [root@localhost strace]# strace ./main
    execve("./main", ["./main"], [/* 23 vars */]) = 0
    brk(0)                                  = 0x99da000
    access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
    open("/etc/ld.so.cache", O_RDONLY)      = 3
    fstat64(3, {st_mode=S_IFREG|0644, st_size=44224, ...}) = 0
    mmap2(NULL, 44224, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7f68000
    close(3)                                = 0
    open("/usr/lib/libstdc++.so.6", O_RDONLY) = 3
    read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0P\234!\0024\0\0\0"..., 512) = 512
    fstat64(3, {st_mode=S_IFREG|0755, st_size=936908, ...}) = 0
    mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f67000
    mmap2(0x21da000, 961720, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x21da000
    mmap2(0x22ba000, 20480, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xdf) = 0x22ba000
    mmap2(0x22bf000, 23736, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x22bf000
    close(3)                                = 0
    open("/lib/libm.so.6", O_RDONLY)        = 3
    read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\20\244\201\0004\0\0\0"..., 512) = 512
    fstat64(3, {st_mode=S_IFREG|0755, st_size=208352, ...}) = 0
    mmap2(0x817000, 155760, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x817000
    mmap2(0x83c000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x24) = 0x83c000
    close(3)                                = 0
    open("/lib/libgcc_s.so.1", O_RDONLY)    = 3
    read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0`\366\316\0074\0\0\0"..., 512) = 512
    fstat64(3, {st_mode=S_IFREG|0755, st_size=46636, ...}) = 0
    mmap2(0x7cee000, 48196, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7cee000
    mmap2(0x7cf9000, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0xa) = 0x7cf9000
    close(3)                                = 0
    open("/lib/libc.so.6", O_RDONLY)        = 3
    read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\340\357m\0004\0\0\0"..., 512) = 512
    fstat64(3, {st_mode=S_IFREG|0755, st_size=1611564, ...}) = 0
    mmap2(0x6c9000, 1332676, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x6c9000
    mprotect(0x808000, 4096, PROT_NONE)     = 0
    mmap2(0x809000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x13f) = 0x809000
    mmap2(0x80c000, 9668, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x80c000
    close(3)                                = 0
    mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f66000
    set_thread_area({entry_number:-1 -> 6, base_addr:0xb7f66ad0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
    mprotect(0x809000, 8192, PROT_READ)     = 0
    mprotect(0x83c000, 4096, PROT_READ)     = 0
    mprotect(0x22ba000, 16384, PROT_READ)   = 0
    mprotect(0x6c5000, 4096, PROT_READ)     = 0
    munmap(0xb7f68000, 44224)               = 0
    fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 4), ...}) = 0
    mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f72000
    write(1, "hello,world\n", 12hello,world
    )           = 12
    fstat64(0, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 4), ...}) = 0
    mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f71000
    read(0, 
4、kill -9 6456,如下:
    read(0,  <unfinished ...>
    +++ killed by SIGKILL +++
参见
top命令详解
【第一行】任务队列信息      
16:44:36                            表示当前系统的时间
up 113 days, 36 min                 表示该机器已经启动了多长时间
1 user                              当前连接到该机器的有一个用户
load average: 0.10, 0.04, 0.00      分别对应1、5、15分钟内cpu的平均负载

关于该参数的详细说明:该叁数是平常监控机器的运行状况的一个主要指标,我们知道每个cpu都会维护一个"运行队列",
这里存放待执行的进程,只要不是在等待IO或者主动的wait就是可运行的进程,就会出现在这个队列里,
如果这样的进程越来越多,cpu就需要花很长的时间来处理这些进程。
这样cpu的负载其实就是指正在执行的进程以及处于运行队列中的进程的总和,平均负载就是在某段时间负载的平均值。   
【第二行】进程的运行情况
各个参数的具体含义分别是:总进程数,正在执行的进程数,休眠的进程数,停止运行的进程数,僵尸进程数。
Tasks: 111 total    进程总数;
2 running           正在运行的进程数;
108 sleeping        睡眠的进程数;
1 stopped           停止的进程数;
0 zombie            僵尸进程数;
【第三行】cpu的利用率 
Cpu(s):  0.0%us             用户空间占用CPU百分比;
0.0%sy                      内核空间占用CPU百分比;
0.0%ni                      用户进程空间内改变过优先级的进程占用CPU百分比;
99.9%id                     空闲CPU百分比;
0.0%wa                      等待输入输出的CPU时间百分比;
0.0%hi,  0.0%si,  0.0%st    不常用,不做介绍;
【第四行】物理内存的使用情况
Mem:   5242880k total       物理内存的总量;
4403900k used               已经使用的物理内存的总理;
838980k free                空闲内存总量;
285712k buffers             用作内核缓存的内存量
【第五行】交换区的使用情况
Swap:  2097144k total       交换区的总量;
112k used                   已经使用的交换区的量;
2097032k free               空闲交换区的量;
3127936k cached             缓冲的交换区总量。
内存中的内容被换出到交换区,而后又被换入到内存,但使用过的交换区尚未被覆盖。
该数据即为这些内容已经存在于内存中的交换区的大小。相应的内存再次被换出时不必再对交换区写入。
【第六行】 空行
【第七行】进程信息区
进行信息区的信息详细的描述了各个进程目前的运行状况:
序号      列名      含义
a           PID         进程id
b           PPID        父进程id
c           RUSER       Real user name
d           UID         进程所有者的用户id
e           USER        进程所有者的用户名
f           GROUP       进程所有者的组名
g           TTY         启动进程的终端名。不是从终端启动的进程则显示为 ?
h           PR          优先级
i           NI          nice值。负值表示高优先级,正值表示低优先级
j           P           最后使用的CPU,仅在多CPU环境下有意义
k           %CPU        上次更新到现在的CPU时间占用百分比
l           TIME        进程使用的CPU时间总计,单位秒
m           TIME+       进程使用的CPU时间总计,单位1/100秒
n           %MEM        进程使用的物理内存百分比
o           VIRT        进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES
p           SWAP        进程使用的虚拟内存中,被换出的大小,单位kb。
q           RES         进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA
r           CODE        可执行代码占用的物理内存大小,单位kb
s           DATA        可执行代码以外的部分(数据段+栈)占用的物理内存大小,单位kb
t           SHR         共享内存大小,单位kb
u           nFLT        页面错误次数
v           nDRT        最后一次写入到现在,被修改过的页面数。
w           S           进程状态。
                            D=不可中断的睡眠状态
                            R=运行
                            S=睡眠
                            T=跟踪/停止
                            Z=僵尸进程
x           COMMAND     命令名/命令行
y           WCHAN       若该进程在睡眠,则显示睡眠中的系统函数名
z           Flags       任务标志 
默认情况下仅显示的信息包括:PID  USER  PR  NI  VIRT  RES  SHR  S  %CPU  %MEM  TIME+  COMMAND,
可以通过如下的快捷方式来更改显示的内容:
通过【f】键可选择显示的内容,按f后会显示列的列表,按a-z即可显示或隐藏对应的列,按回车确定。
通过【o】键可改变列的显示顺序。按小写的a-z可以将相应的列向右移动,按大写的A-Z可以将相应的列向左移动,按回车确定。
按【F】或【O】,按a-z可将进程按相应的列进行排序,按【R】可将当前的排序倒转。
命令的使用方法
top [-] [d] [p] [c] [S] [s] 
d       指定每两次屏幕信息刷新之间的时间间隔。当然用户可以使用s交互命令来改变。
p       通过指定监控进程 ID来仅仅监控某个进程的状态;
s       使top命令在安全模式下运行,这将免出人意料交互命令所带来的潜在风险;
S       指定累积模式;
i       使top不显示任何闲置或僵死的进程;
c       显示整个命令行而不仅仅是显示命令名。
注意:top默认只列出活跃的进程,如果要列出所有的进程,使用 top -bn1
top的一些交互命令
h或者?        显示帮助画面,给出一些简短的命令总结说明。
k           终止一个进程,系统提示输入一个PID及需要发送给该进程的信号。一般终止进程用15信号,如果不能正常结束就使用9信号。 在安全模式下该命令被屏蔽。
i           忽略闲置和僵死的进程,这是一个开关式命令;
q           退出程序;
r           重新安排一个进程的优先级别。系统提示用户输入需要改变的进程PID及需要设置的进程优先级的值。输入一个正值使优先级降低,反之则使进程拥有高优先级,默认是10;
S           切换到累积模式;
s           改变两次刷新之间的延迟时间,系统提示用户输入新的时间,单位为s。输入0则系统不断刷新,默认值是5。
n           显示的进程数,系统会提示输入需要显示的进程数目;
f           从当前显示项目中添加或删除项目;
o           改变当前显示项目的顺序;
l           切换显示平均负载和启动时间的信息;
m           切换显示内存信息;
t           切换显示进程和CPU状态信息;
c           切换命令名称和完整命令行;
M           根据驻留内存大小进行排序;
P           根据CPU使用百分比大小进行排序;
T           根据时间/累积时间进行排序。 
F或者O        选择其它的字段排序   
常用的选项:
1、输入1,查看cpu的个数和使用情况
2、top -H -p7073 查看进程7073以及子进程的情况
    注意:在多核设备上,进程的cpu使用超过100%有可能是正常的。
    因为多个子进程在不同的cpu上面,每个都使用很低,在一起有可能超过100%
valgrind
1、valgrind是什么?
    valgrind是Linux下仿真调试工具的集合,由内核和基于内核的调试工具组成,valgrind模拟一个CPU环境。
2、valgrind包括的工具:
    Memcheck:   这是valgrind应用最广泛的工具,一个重量级的内存检查器,能够发现开发中绝大多数内存错误使用情况。
                比如,使用未初始化的内存,使用已经释放了的内存,内存访问越界等。
    Callgrind:  它主要用来检查程序中函数调用过程中出现的问题。
    Cachegrind:它主要用来检查程序中缓存使用出现的问题。
    Helgrind:   它主要用来检查多线程程序中出现的竞争问题。
    Massif: 它主要用来检查程序中堆栈使用中出现的问题。
    Extension:  可以利用core提供的功能,自己编写特定的内存调试工具
3、Memcheck能够检测出内存问题,关键在于其建立了两个全局表。
    Valid-Value表:记录内存的值是否初始化,是否有效。
    Valid-Address表:记录该地址是否能够被读写。
4、重点介绍内存的检测情况,内存没有初始化。
    代码:
    int main(int agc, char* argv[])
    {
            int* pi;
            int a = *pi;
            return 0;
    }
    测试:
    [root@localhost valgrind]# valgrind --tool=memcheck --leak-check=full ./main
    ==7422== Memcheck, a memory error detector
    ==7422== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
    ==7422== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
    ==7422== Command: ./main
    ==7422== 
    ==7422== Use of uninitialised value of size 4
    ==7422==    at 0x8048408: main (in /home/niu/valgrind/main)
    ==7422== 
    ==7422== 
    ==7422== HEAP SUMMARY:
    ==7422==     in use at exit: 0 bytes in 0 blocks
    ==7422==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
    ==7422== 
    ==7422== All heap blocks were freed -- no leaks are possible
    ==7422== 
    ==7422== For counts of detected and suppressed errors, rerun with: -v
    ==7422== Use --track-origins=yes to see where uninitialised values come from
    ==7422== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 15 from 8)
    指出上下文有一个错误,使用--track-origins=yes查看,栈上的内存没有初始化。
    [root@localhost valgrind]# valgrind --tool=memcheck --leak-check=full --track-origins=yes ./main
    ==7483== Memcheck, a memory error detector
    ==7483== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
    ==7483== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
    ==7483== Command: ./main
    ==7483== 
    ==7483== Use of uninitialised value of size 4
    ==7483==    at 0x8048408: main (in /home/niu/valgrind/main)
    ==7483==  Uninitialised value was created by a stack allocation
    ==7483==    at 0x8048402: main (in /home/niu/valgrind/main)
    ==7483== 
    ==7483== 
    ==7483== HEAP SUMMARY:
    ==7483==     in use at exit: 0 bytes in 0 blocks
    ==7483==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
    ==7483== 
    ==7483== All heap blocks were freed -- no leaks are possible
    ==7483== 
    ==7483== For counts of detected and suppressed errors, rerun with: -v
    ==7483== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 15 from 8)
5、内存泄露
    代码:
    int main(int agc, char* argv[])
    {
            int* pi = new int[10];  
            return 0;
    }
    测试:
    [root@localhost valgrind]# valgrind --tool=memcheck --leak-check=full ./main
    ==7636== Memcheck, a memory error detector
    ==7636== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
    ==7636== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
    ==7636== Command: ./main
    ==7636== 
    ==7636== 
    ==7636== HEAP SUMMARY:
    ==7636==     in use at exit: 40 bytes in 1 blocks
    ==7636==   total heap usage: 1 allocs, 0 frees, 40 bytes allocated
    ==7636== 
    ==7636== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1
    ==7636==    at 0x4005D2D: operator new[](unsigned int) (vg_replace_malloc.c:258)
    ==7636==    by 0x8048490: main (in /home/niu/valgrind/main)
    ==7636== 
    ==7636== LEAK SUMMARY:
    ==7636==    definitely lost: 40 bytes in 1 blocks
    ==7636==    indirectly lost: 0 bytes in 0 blocks
    ==7636==      possibly lost: 0 bytes in 0 blocks
    ==7636==    still reachable: 0 bytes in 0 blocks
    ==7636==         suppressed: 0 bytes in 0 blocks
    ==7636== 
    ==7636== For counts of detected and suppressed errors, rerun with: -v
    ==7636== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 15 from 8)
    内存泄露40个字节
6、内存申请释放不匹配
    代码:
    #include <stdlib.h>
    int main(int agc, char* argv[])
    {
            int* p1 = new int[10];
            delete p1;
    
            int* p2 = new int;
            free(p2);
    
            return 0;
    }
    测试:
    [root@localhost valgrind]# valgrind --tool=memcheck --leak-check=full ./main
    ==8162== Memcheck, a memory error detector
    ==8162== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
    ==8162== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
    ==8162== Command: ./main
    ==8162== 
    ==8162== Mismatched free() / delete / delete []
    ==8162==    at 0x4005234: operator delete(void*) (vg_replace_malloc.c:346)
    ==8162==    by 0x804852E: main (in /home/niu/valgrind/main)
    ==8162==  Address 0x4017028 is 0 bytes inside a block of size 40 alloc'd
    ==8162==    at 0x4005D2D: operator new[](unsigned int) (vg_replace_malloc.c:258)
    ==8162==    by 0x8048520: main (in /home/niu/valgrind/main)
    ==8162== 
    ==8162== Mismatched free() / delete / delete []
    ==8162==    at 0x400551D: free (vg_replace_malloc.c:325)
    ==8162==    by 0x8048548: main (in /home/niu/valgrind/main)
    ==8162==  Address 0x4017080 is 0 bytes inside a block of size 4 alloc'd
    ==8162==    at 0x40060D5: operator new(unsigned int) (vg_replace_malloc.c:214)
    ==8162==    by 0x804853A: main (in /home/niu/valgrind/main)
    ==8162== 
    ==8162== 
    ==8162== HEAP SUMMARY:
    ==8162==     in use at exit: 0 bytes in 0 blocks
    ==8162==   total heap usage: 2 allocs, 2 frees, 44 bytes allocated
    ==8162== 
    ==8162== All heap blocks were freed -- no leaks are possible
    ==8162== 
    ==8162== For counts of detected and suppressed errors, rerun with: -v
    ==8162== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 15 from 8)
7、踩内存
    代码:
    #include <stdlib.h>
    #include <memory.h>
    int main(int agc, char* argv[])
    {
            char* p1 = new char[4];
            char* p2 = "abcde";
            memcpy(p1,p2,5);
            return 0;
    }
    测试:
    [root@localhost valgrind]# valgrind --tool=memcheck --leak-check=full ./main
    ==8387== Memcheck, a memory error detector
    ==8387== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
    ==8387== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
    ==8387== Command: ./main
    ==8387== 
    ==8387== Invalid write of size 1
    ==8387==    at 0x80484A9: main (in /home/niu/valgrind/main)
    ==8387==  Address 0x401702c is 0 bytes after a block of size 4 alloc'd
    ==8387==    at 0x4005D2D: operator new[](unsigned int) (vg_replace_malloc.c:258)
    ==8387==    by 0x8048490: main (in /home/niu/valgrind/main)
    ==8387== 
    ==8387== 
    ==8387== HEAP SUMMARY:
    ==8387==     in use at exit: 4 bytes in 1 blocks
    ==8387==   total heap usage: 1 allocs, 0 frees, 4 bytes allocated
    ==8387== 
    ==8387== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1
    ==8387==    at 0x4005D2D: operator new[](unsigned int) (vg_replace_malloc.c:258)
    ==8387==    by 0x8048490: main (in /home/niu/valgrind/main)
    ==8387== 
    ==8387== LEAK SUMMARY:
    ==8387==    definitely lost: 4 bytes in 1 blocks
    ==8387==    indirectly lost: 0 bytes in 0 blocks
    ==8387==      possibly lost: 0 bytes in 0 blocks
    ==8387==    still reachable: 0 bytes in 0 blocks
    ==8387==         suppressed: 0 bytes in 0 blocks
    ==8387== 
    ==8387== For counts of detected and suppressed errors, rerun with: -v
    ==8387== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 15 from 8)
日期时间
1、date 查看日期时间,如下:
    [root@localhost ~]# date 
    Sat Sep 26 20:41:54 CST 2015
2、查看时区,使用-R,如下:
    [root@localhost ~]# date -R
    Sat, 26 Sep 2015 20:42:42 +0800
3、格式化输出时间
    [root@localhost ~]# date '+%Y-%m-%d %H:%M:%S'
    2015-09-26 20:43:36
    [root@localhost ~]# date '+%Y-%m-%d %I:%M:%S'
    2015-09-26 08:43:43
    小写m是月
    大写M是分钟
    大写H是24小时
    大写I是12小时
4、设置时间
    [root@localhost ~]# date -s '2015-09-26 20:47:00'
    Sat Sep 26 20:47:00 CST 2015
5、date打印出来的时间,看起来不直观,使用date '+%Y-%m-%d %H:%M:%S',但是每次输入比较麻烦,增加一个别名,如下:
    [root@localhost ~]# date
    Thu Dec 29 13:20:23 CST 2016
    [root@localhost ~]# alias date="date '+%Y-%m-%d %H:%M:%S'"
    [root@localhost ~]# date
    2016-12-29 13:20:32
    但是,假如我还想使用原始的date命令,怎么办?
    使用\date
考虑下面的需求,清除15天之前的日志文件
添加日志文件
#! /bin/sh
set -x

i=0
nowSeconds=$(date +%s)

while [ $i -lt $1 ]
do
    nowStr=$(date +%Y-%m-%d\ %H:%M:%S -d "1970-01-01 UTC $nowSeconds seconds")
    postfix=`date +%Y-%m-%d_%H:%M:%S -d "$nowStr"`
    touch log_$postfix
    sleep 1

    ((i=i+1))
    ((nowSeconds=nowSeconds-86400*5))
done

删除日志文件
#! /bin/sh
set -x

LogFile_SaveDays=15

# clear old log file
logList=`ls -t|grep log_`
for log in $logList
do 
        logDate=`echo $log|cut -d '_' -f 2`
        echo $logDate
        timeDiff=$(($(date +%s) - $(date +%s -d $logDate)));
        if [ $[$timeDiff/86400] -gt $LogFile_SaveDays ];then
                rm -f $log
        fi
        echo "$log"
done
考虑下面的需求,保留最新的三个dump core文件,其他的删除
添加core文件
#! /bin/sh
set -x

i=0
while [ $i -lt $1 ]
do
    ((i=i+1))
    postfix=`date +%Y-%m-%d_%H:%M:%S`
    touch core_$postfix
    sleep 1
done

删除core文件
#! /bin/sh
set -x

CoreFile_SaveNum=3

# clear old core file
CoreFile_SaveNum=$[$CoreFile_SaveNum+1]
ls -t|grep core_|sed -n "$CoreFile_SaveNum,$ p"|xargs rm -f
Copyright (c) 2015~2016, Andy Niu @All rights reserved. By Andy Niu Edit.