linux输出信息_linux脚本输出信息 - CSDN
  • Linux系统在开机的过程中我们可以看见很多打印信息,这都是Linux内核内部调用printk(level,message)函数打印出来的 其中level是定义的打印优先级,当优先级小于console_loglevel时定义的优先级小于当前日志的打印...

    一、printk()的介绍

    Linux系统在开机的过程中我们可以看见很多打印信息,这都是Linux内核内部调用printk(level,message)函数打印出来的

    其中level是定义的打印优先级,当优先级小于console_loglevel时定义的优先级小于当前日志的打印级别时,信息才会打印在控制终端(根据要打印信息的类型,分为0~7,其中0位最高级别),通常宏来指示日志优先级

    #define KERN_EMERG      "<0>"    /* system is unusable */
    #define KERN_ALERT      "<1>"    /* action must be taken immediately */
    #define KERN_CRIT       "<2>"    /* critical conditions */
    #define KERN_ERR        "<3>"    /* error conditions */
    #define KERN_WARNING    "<4>"    /* warning conditions */
    #define KERN_NOTICE     "<5>"    /* normal but significant */
    #define KERN_INFO       "<6>"    /* informational */

    #define KERN_DEBUG      "<7>"    /* debug-level messages */

     

    其中console_loglevel的初始值是DEFAULT_CONSOLE_LOGLEVEL,可以通过sys_syslog()系统调用进行修改,或者修改文件/proc/sys/kernel/printk下的优先级,,这个文件中包含了4个整数值,分别是当前日志优先级,未明确指定的日志级别时的默认日志优先级,最小允许的日志优先级,引导时的默认日志优先级。向该文件中写入一个整数值,就会把当前日志文件的优先级修改为该值,修改方式为

    echo 4 > /proc/sys/kernel/printk(linux内核2.6日志默认的优先级是4)

    message是我们要打印出调试的信息

     

    二、消息被记录的原理

    在内核中有一个内核自定义的一个长度为__LOG_BUF_LEN(在内核配置时为该变量配置值,范围是4kb~1mb)字节ring buffer(循环缓冲区),Linux系统中所有的系统信息输出的信息都是调用printk()都被输出到这里(包含内核信息),

    通常获得我们想要的信息,有两种方式,一种是直接读取ring buffer中的信息,另一种是查看/var/log下的文件。

    1、直接使用dmesg命令

    该命令直接从循环缓冲区中读取数据到stdout

    2、通过查看/var/log下的文件

    在Linux中有两个守护程序,klogd和syslogd

    klogd这个进程会通过syslog()这个系统调用或者读取proc文件系统来得到printk()从ring buffer中得到的信息,也就是我们的内核信息。并且klogd也会把信息传给syslog这个进程的。

    LINUX系统启动后,由/etc/init.d/sysklogd先后启动klogd,syslogd两个守护进程,其中syslogd通过/etc/syslog.conf这个配置文件将系统产生的信息分类记录到相应的log中,因此这个目录下会有很多文件,其中将klogd传输过来的内核信息记录到/var/log/messgae中。

     

    需要注意的是!!!,syslogd获取内核信息依赖进程klogd,因此要想通过syslogd获得内核的信息,klogd和syslogd这两个守护进程必须同时存在(这时无论当前日志的级别是多少,klogd都会把内核消息输出到/var/log/messgae下。这里我的理解是把打印级别高的输出到控制台,而把所有的内核信息,无论打印级别高低,都输出到/var/log/messgae下),如果klogd没有运行,内核不会传递信息到用户空间,因此此时/var/log/messgae不会有信息,此时只能通过查看内核专门用来存放打印信息的目录/proc/kmsg。

    因为循环缓冲区的大小是固定的因此不能无限制的存储日志信息,因此当缓冲区满了之后,printk()函数会从缓冲区的开头,通过覆盖之前的日志信息继续存储最新的信息,这样做会导致原来的信息丢失,但一般之前的信息对我们的调试没什么作用,因此这样做是有利的。

     

    为了避免大量的输出信息影响调试,可以通过klogd -f选项指定文件,将信息输出到指定的文件内,或者强制杀死进程klogd,然后打开一个新的终端,使用命令cat /proc/kmsg将信息显示在新打开的终端。

     

    一.查看日志方式

    命令格式: tail[必要参数][选择参数][文件]

    这个是我最常用的一种查看方式
    1.tail

       -f 循环读取
       -q 不显示处理信息
       -v 显示详细的处理信息
       -c<数目> 显示的字节数
       -n<行数> 显示行数
       -q, --quiet, --silent 从不输出给出文件名的首部 
       -s, --sleep-interval=S 与-f合用,表示在每次反复的间隔休眠S秒
    
       tail  -n  10   test.log   查询日志尾部最后10行的日志;
       tail  -n +10   test.log   查询10行之后的所有日志;
       tail  -fn 10   test.log   循环实时查看最后1000行记录(最常用的)
    
       //一般还会配合着grep用, 例如 :  tail -fn 1000 test.log | grep '关键字'
       如果一次性查询的数据量太大,可以进行翻页查看,
       例如:tail -n 4700  aa.log |more -1000 可以进行多屏显示(ctrl + f 或者 空格键可以快捷键)

    2.head

    head -n  10  test.log   //查询日志文件中的头10行日志;
    head -n -10  test.log   //查询日志文件除了最后10行的其他所有日志;

    head其他参数与tail 类似

    3.cat
    cat 是由第一行到最后一行连续显示在屏幕上

    一次显示整个文件 : $ cat filename
    从键盘创建一个文件 : $ cat > filename  
    将几个文件合并为一个文件: $cat file1 file2 > file //只能创建新文件,不能编辑已有文件.
    将一个日志文件的内容追加到另外一个 : $cat -n textfile1 > textfile2
    清空一个日志文件 $cat : >textfile2 

    注意:>意思是创建,>>是追加。千万不要弄混了。
    cat其他参数与tail 类似

    4.tac
    tac 则是由最后一行到第一行反向在萤幕上显示出来

    5.sed

    这个命令可以查找日志文件特定的一段 , 也可以根据时间的一个范围查询

      //按照行号
      sed -n '5,10p' filename //这样你就可以只查看文件的第5行到第10行。
      //按照时间段
      sed -n '/2014-12-17 16:17:20/,/2014-12-17 16:17:36/p'  test.log

    6.less

    less log.log 
    
    shift + G 命令到文件尾部  然后输入 ?加上你要搜索的关键字例如 ?1213
    
    shift+n  关键字之间进行切换

    二.其他会应用到的命令

    history // 所有的历史记录
    
    history | grep XXX  // 历史记录中包含某些指令的记录
    
    history | more // 分页查看记录
    
    history -c // 清空所有的历史记录
    
    !! 重复执行上一个命令
    
    查询出来记录后选中 : !323
    

    linux日志文件说明

    /var/log/message 系统启动后的信息和错误日志,是Red Hat Linux中最常用的日志之一
    /var/log/secure 与安全相关的日志信息
    /var/log/maillog 与邮件相关的日志信息
    /var/log/cron 与定时任务相关的日志信息
    /var/log/spooler 与UUCP和news设备相关的日志信息
    /var/log/boot.log 守护进程启动和停止相关的日志消息
    /var/log/wtmp 该日志文件永久记录每个用户登录、注销及系统的启动、停机的事件

    展开全文
  • 在运行linux的时候有所有的...1、 bootloader输出信息 U-Boot 1.3.2(Nov 19 2016 - 22:02:08) DRAM: 64 MB Flash: 512 kB NAND: 64 MiB In: serial Out: serial Err: serial Hit any key to sto
    
    

     

    在运行linux的时候有所有的调试信息可以分为三个部分

     

    1、 bootloader输出信息

    U-Boot 1.3.2(Nov 19 2016 - 22:02:08)
    DRAM: 64 MB
    Flash: 512 kB
    NAND: 64 MiB
    In: serial
    Out: serial
    Err: serial
    Hit any key to stop autoboot: 0
    [yqliu2410 #] tftp
    Found DM9000 ID:90000a46 at address 10000000 !
    DM9000 work in 16 bus width
    bd->bi_entaddr: 08:00:3e:26:0a:5b
    [eth_init]MAC:8:0:3e:26:a:5b:
    TFTP from server 192.168.1.152; ourIP address is 192.168.1.155
    Filename 'uImage'.
    Load address: 0x30008000
    Loading: T T#######################################################done
    Bytes transferred = 1617316 (18ada4 hex)
    [up-tech2410 #] bootm
    ## Booting image at 30008000 ...
       Image Name: Linux-2.6.24.4
       Created: 2016-11-19 14:05:29 UTC
       Image Type: ARM Linux Kernel Image(uncompressed)
       Data Size: 1617252 Bytes= 1.5 MB
       Load Address: 30008000
       Entry Point: 30008040
       Verifying Checksum ... OK
    Starting kernel ...

    2、 linux低级调试信息输出

    Uncompressing Linux............................................................. done, booting the kernel.

    3、 linux调试信息输出

    Linux version 2.6.24.4(root@vm-dev)(gcc version 3.4.6) #100 Sat Nov 19 07:47:35 CST 2016
    CPU: ARM920T [41129200] revision 0(ARMv4T), cr=00007177
    Machine: SMDK2410
    Memory policy: ECC disabled, Data cache writeback
    CPU S3C2410A (id 0x32410002)
    S3C2410: core 202.800 MHz, memory 101.400 MHz, peripheral 50.700 MHz
    S3C24XX Clocks, (c) 2004 Simtec Electronics
    CLOCK: Slow mode (1.500 MHz), fast, MPLL on, UPLL on
    CPU0: D VIVT write-back cache
    CPU0: I cache: 16384 bytes, associativity 64, 32byte lines, 8sets
    CPU0: D cache: 16384 bytes, associativity 64, 32byte lines, 8sets
    Built 1 zonelists in Zone order, mobility grouping on. Total pages: 16256
    Kernel command line: root=/dev/mtdblock2 noinitrd console=ttySAC1,115200
    irq: clearing subpending status 00000010
    PID hash table entries: 256 (order: 8, 1024 bytes)
    timer tcon=00500000, tcnt a509, tcfg 00000200,00000000, usec 00001e4c
    Console: colour dummy device 80x30
    console [ttySAC1] enabled

    ............................

     

    现在要将所有的调试信息输出到别的串口。以com1为例(com0开始计算)

    一、bootloader的输出信息输出到com1

    这里以u-boot1.3.2为例:很简单只需要修改一个宏定义就ok

    Vi inlcude/configs/xxxconfig.h(xxx为你定义的开发板的名字)

    更改原有的宏

     

    /*
     * select serial console configuration
     */
    //#define CONFIG_SERIAL1 1 /* we use SERIAL 1 on SMDK2410*/
    //modify for xxx2410
    //by lyj_uptech
    #define CONFIG_SERIAL2 1 /* we use SERIAL 2 on SMDK2410*/

    二、low_level的调试信息输出到com1

    在改之前我们先分析一下在linux启动之前它是如何使用串口的(以linux-2.6.24为例)。

    1、 arch/arm/boot/compressed/misc.c文件中有定义

     

    staticvoid putstr(constchar *ptr)
    {
            char c;
            while ((c= *ptr++)!= '\0') {
                    if (c =='\n')
                            putc('\r');
                    putc(c);
            }     
            flush();
    }

    2、 arch/arm/boot/compressed/misc.中的函数decompress_kernel就是使用的putstr来打印的如下输出信息:

    Uncompressing Linux............................................................. done, booting the kernel

    3、 追根溯源,putstr函数最终调用的是putc(请注意这里的putc不是在misc.c函数中定义的icedcc_putc,因为没有CONFIG_CPU_V6宏定义),真正的底层操作在文件include/asm-arm/plat-s3c/uncompress.h

        4、 解析该文件

    /* we can deal with the case the UARTs are being run
     * in FIFO mode, so that we don't hold up our execution
     * waiting for tx to happen...
    */

    static voidputc(int ch)
    {
            if (uart_rd(S3C2410_UFCON)& S3C2410_UFCON_FIFOMODE){
                    int level;
                    while (1) {
                            level = uart_rd(S3C2410_UFSTAT);
                            level &= fifo_mask;
     
                            if (level < fifo_max)
                                    break;
                    }
            } else{
                    /* not using fifos */
                    while ((uart_rd(S3C2410_UTRSTAT)& S3C2410_UTRSTAT_TXE)!= S3C2410_UTRSTAT_TXE)
                            barrier();
            }
            /* write byte to transmission register */
            uart_wr(S3C2410_UTXH, ch);
    }

    该函数中调用的两个函数,uart_rd uart_wr在同一个文件中定义

    #define uart_base S3C24XX_PA_UART+ (0x4000*CONFIG_S3C_LOWLEVEL_UART_PORT)
    static __inline__void
    uart_wr(unsignedint reg, unsigned int val)
    {
            volatile unsignedint *ptr;
            ptr = (volatileunsigned int*)(reg+ uart_base);
            *ptr = val;
    }
    static __inline__unsigned int
    uart_rd(unsignedint reg)
    {
            volatile unsignedint *ptr;
            ptr = (volatileunsigned int*)(reg+ uart_base);
            return *ptr;
    }

    从宏定义uart_base中就可以清楚的看到,当CONFIG_S3C_LOWLEVEL_UART_PORT0,uart_base的值为0x50000000,也就是uart0的控制寄存器基地址。如果要使用uart1的话就把CONFIG_S3C_LOWLEVEL_UART_PORT赋值为1就可以了。

    5、真正更改的地方只有一个

    下级目录

     

    修改为1ok

    6、 需要注意的地方(你使用的串口初始化了么

    我在整个内核中找遍了解压内核之前运行的代码,都找不到关于串口初始化的代码。所以说,linux在启动之前的串口初始化是依赖bootloader的,要想正常的输出,就必须使用你的bootloader使用的串口,因为在bootloader中进行了对要使用的串口进行了初始化。要保证你的bootloader兼容性很好,那就在bootloader中把所有的串口都初始化一遍。

    如果你没有初始化串口,一旦调用putstr,程序就死掉了!

    三、linux的信息输出到com1

    linux运行的信息输出到com1就太简单了,直接到bootloader里面改linux的传递参数就可以了。

    setenv bootargs root=/dev/mtdblock2 noinitrd console=ttySAC1,115200
    saveenv

    现在启动一切ok

    感谢yqliu29的支持,没有他的调试程序,我始终的无法知道linux的内核是否正确调用,也无法定位问题!

    这里附上他给我的程序(这里的三个灯分别对应的io管脚是GPF5/6/7

    #if 0
            asm volatile(
                    "ldr r6, =0x5400\n\r"
                    "ldr r7, =0x56000020\n\r"
                    "str r6, [r7]\n\r"
                    "ldr r6, =0xC0\n\r"
                    "ldr r7, =0x56000024\n\r"
                    "str r6, [r7]");
    #endif

     

     

     

     

    include/s3c6410.h 里

    #define ELFIN_UART_BASE                0x7F005000 // Assembly 阶段吃这里


    #define ELFIN_UART0_OFFSET        0x0000
    #define ELFIN_UART1_OFFSET        0x0400
    #define ELFIN_UART2_OFFSET        0x0800

    #ifdef CONFIG_SERIAL1 // 这一句在 include/config/smdk6410.h
    #define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART0_OFFSET)
    #elif defined(CONFIG_SERIAL2)
    #define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART1_OFFSET)
    #else
    #define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART0_OFFSET)
    #endif

    展开全文
  • 由于Linux输出有缓冲区,也就是说Printf打印的信息不是马上输出到屏幕上,而是先输入到缓存中,等缓存区满了后才会输出 怎样解决: 不要每次只输出一个字符,就算只输出一个字符,在后面也要加上一个换行符 用...

    今天莫名奇妙不打印信息,找了半天原理是,Linux的缓冲区问题

    由于Linux的输出有缓冲区,也就是说Printf打印的信息不是马上输出到屏幕上,而是先输入到缓存中,等缓存区满了后才会输出

    怎样解决:

    1. 不要每次只输出一个字符,就算只输出一个字符,在后面也要加上一个换行符
    2. 用fflush函数进行冲洗缓存区

     

     

     

     

     

     

     

     

     

     

     

    展开全文
  • 【tail -f log &gt; a.out】把log打出的末尾信息输出到a.out文件

    【tail -f log > a.out】把log打出的末尾信息输出到a.out文件

    展开全文
  • 输出转向就可以了   例子:  $ ls > ls.txt #或者ls-->ls.txt #把ls命令的运行结果保存到文件ls.txt中  [lhd@hongdi ~]$ ls > ls.txt  [lhd@hongdi ~]$ cat ls.txt  ...
  • 在做批量实验室,例如跑批量MR的作业,我们会写好shell脚本,然后启动脚本,等所有作业执行完再去看结果,但是这些执行时的信息如何保存下来到文件中呢?下面这个命令可以完成这个任务。 sh batchjob.sh 2>&1 | ...
  • 在做调试的时候,需要观察终端输出的内容,有时候终端输出太多会被覆盖掉,并且直接在终端观察不太方便。将终端输出的内容保存在日志文件中,一方面可以便于查看输出内容,另一方面可以永久保存,便于回看。因此本文...
  • Linux 日志输出控制

    2019-03-11 13:48:38
    在嵌入式Linux设备中,系统资源比较有限,在产品开发时我们会打印很多的日志信息... Linux内核调试信息printk函数,它的输出等级在Linux内核中已经帮我们定义好。可以通过命令查看和设置系统日志等级: / # cat ...
  • Linux重定向输出日志

    2019-02-22 09:43:15
    Linux重定向输出日志 重定向类型 0:标准输入。 1:标准输出。 2:错误信息输出。 2&gt;&amp;1:将错误信息重定向到标准输出。 重定向格式 1,./spark-submit.sh 2&gt;spark.log,将./spark-submit.sh...
  • linux分屏输出信息

    2014-01-19 11:10:56
    linux中,有时候对某个命令,敲击帮助,会由于信息太多,只看见最后一屏的信息,为此,我们在输入命令时,增加 |less 即可。 如 shutdown --help |less 这样就会将帮助信息分屏输出,最后,我们在敲击q命令即可...
  • 最近在安装Apache sentry,发现启动metastore和hiveserver2服务的时候会弹出大量的debug信息,有时候需要在一长串的信息...1、下面先简要介绍一下Linux重定向0、1和2分别表示标准输入、标准输出和标准错误信息输出,可
  • linux 错误信息输出

    2019-05-12 09:26:00
    /dev/null linux下的黑洞,类似于垃圾桶,任何东西到里面都会被粉碎 > 重定向 >>追加 1 标准输出 2 错误输出 & 表示等同于的意思, 2>&1 表示2的重定向等同于1 bash xxx.sh > /dev/...
  • linux命令行日志输出

    2015-10-10 15:04:16
    linux中运行命令行时,会输出一些日志信息,特别典型的是启用WebLogic命令时,输出一些信息,当启用demon模式运行时,又想收集这些信息咋办? 解决的办法就是使用输出重定向,如下面的命令: nohup ./start...
  • 然而在linux下,事情往往不如我所愿,特别是在编译一些大型的开源项目,比如u-boot、linux内核、qt等程序的源码时,一方面本身这些代码的规模就极其庞大,就算所有模块全部没有警告,仅仅是编译输出的其...
  • 0、1和2分别表示标准输入、标准输出和标准错误信息输出,可以用来指定需要重定向的标准输入或输出,比如 2>a.txt 表示将错误信息输出到文件a.txt中。 同时,还可以在这三个标准输入输出之间实现重定向,比如将...
  • Linux中的标准输入输出 标准输入0 从键盘获得输入 /proc/self/fd/0  标准输出输出到屏幕(即控制台) /proc/self/fd/1  错误输出输出到屏幕(即控制台) /proc/self/fd/2      /dev/null代表linux的...
  • Linux重定向是指修改原来默认的一些东西,对原来系统命令的默认执行方式进行改变,比如说简单的我不想看到在显示器的输出而是希望输出到某一文件中就可以通过Linux重定向来进行这项工作。    Linux默认输入是...
  • Linux top命令输出到文件——持续输出某个进程的信息 有的时候可能需要持续输出某个进程在top命令中显示的信息,使用top命令的-b选项可以容易的将输出重定向到其他进程或者文件,配合-n选项指定top命令输出多少次就...
  • Linux Shell输出文本中的指定行 在Linux系统上如何快速查看文本中指定行呢?有时文本较大比如有10w行,想要快速查看第99行该怎么做呢? 本文以文件名test.txt为例,介绍3种方式快速查看test.txt的第99行。相信你...
  • 1.Linux常用的有: 1) 标准输入 stdin 代码为0,使用 2) 标准输出 stdout 代码为1,使用> 或 >> ,这里把1给省略了, 3) 标准错误输出 stderr代码为2,使用 2> 或2>> 其中:标准输出指的是『命令运行所...
1 2 3 4 5 ... 20
收藏数 522,405
精华内容 208,962
关键字:

linux输出信息