<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    so true

    心懷未來,開創(chuàng)未來!
    隨筆 - 160, 文章 - 0, 評論 - 40, 引用 - 0
    數(shù)據(jù)加載中……

    Linux學(xué)習(xí)菁華

    @import url(http://m.tkk7.com/CuteSoft_Client/CuteEditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css); gdb中顯示長字符串:

    1.       Gdb中可以調(diào)用printf做格式化打印:

    printf "%.2000s",s

    x /3uc 0x2341234 #打印地址0x2341234開始的3個(gè)單元,每個(gè)單元1個(gè)byte長,以unsigned int類型顯示出來
    p /t 23423 #以二進(jìn)制形式打印23423
    2000表示最多打印2000個(gè)字符。如果需要打印更長的字符,可以增大該數(shù)據(jù)。

    break write if $rdi == 2 #如果stderr上有輸出的話,就會(huì)break, 引自:https://blogs.oracle.com/ksplice/entry/8_gdb_tricks_you_should

     

    2.       Gdb可以將交互輸出到文件。需要調(diào)用如下兩個(gè)命令:

    set logging on

    set logging file xxx.txt

    以上兩個(gè)命令配合可以起到將長字符串打印到文件的作用。

    但是如果字符串中有若干不可見字符,就不能使用這種方法了。這時(shí)候我們需要把數(shù)據(jù) dump到文件中。命令如下:

    dump binary memory s.txt s s+1000

     s是一個(gè)字符串指針,表示dump的起始位置,s+1000表示dump的末尾。S.txt表示結(jié)果
    dump的文件名具體的參數(shù)意義可以看gdbmannual


    3.打印東西的長度設(shè)置項(xiàng)為

    (gdb) set print elements

    (gdb) set print elements 0

    為全部打出。
    3.1 所有打印的控制都是通過set print來進(jìn)行的,例如set print pretty on,如果打開printf pretty這個(gè)選項(xiàng),那么當(dāng)GDB顯示結(jié)構(gòu)體時(shí)會(huì)比較漂亮。

    4. 對于內(nèi)存版本的字符串,比如char buffer[1000],可以p buffer@300表示從300后開始打印

    gdb能調(diào)試,pstack能打印堆棧信息,core dump文件里有堆棧信息,以及運(yùn)行時(shí)變量的值信息,這些都?xì)w功于symbol table,symbole不光是指變量,也包括函數(shù)以及文件名等等,沒有symbol table上述的一切都不可能。gdb里可以通過symbole-file命令來加載一個(gè)symbol文件,它可以是可執(zhí)行的程序,也可以是僅僅含有symbol的文件,舉個(gè)例子來說:你把strip test -o test.stripped之后的test.stripped文件給別人去用,一旦core掉了,那個(gè)人把core文件給你,你可以用gdb test.stripped core來調(diào)試,并通過symbol-file test這個(gè)命令來加載symbol table,這樣依然可以正常debug。 當(dāng)然你也可以只保留test里面的symbol table,通過strip --only-keep-debug test -o test.dbg來生成這個(gè)文件,然后gdb test.stripped core,通過symbol-file test.dbg就可以了。
    在這里也提一下生成core文件,調(diào)用exit(1)是退出,調(diào)用abort()是會(huì)產(chǎn)生core文件的(當(dāng)然要ulimit -c unlimited)。

     

    pbt () {
        yes | gdb -p $1 --eval-command='thread apply all bt full' --eval-command='q'
    }

    bt #查看堆棧信息
    bt full #查看堆棧信息,并同時(shí)打印local變量
    f 2 #切換到當(dāng)前堆棧的第2層
    info locals #查看當(dāng)前的臨時(shí)變量
    info thread #查看目前所有的線程
    thread 2 #切換到2號線程
    break file.c:100 thread 3 #只在3號線程設(shè)置斷點(diǎn)
    set scheduler-locking on #只調(diào)試當(dāng)前線程,即不會(huì)在調(diào)試過程中被其他線程切進(jìn)來
    info macro DEBUG 你可以查看DEBUG這個(gè)宏在哪些文件里被引用了,以及宏定義是什么樣的。 macro DEBUG 你可以查看DEBUG宏展開的樣子;但需要在GCC編譯程序的時(shí)候,加上-ggdb3參數(shù),這樣,你就可以調(diào)試宏了。
     
    info source可以看到當(dāng)前運(yùn)行位置對應(yīng)的源文件信息;
    info sources可以看到當(dāng)前運(yùn)行程序所有的源文件列表;
    info frame可以看到當(dāng)前運(yùn)行位置的rip,args位置,棧(存放臨時(shí)變量)開始位置

    (gdb) set $idx = 0
    (gdb) p a[$idx++]  #然后就可以一路回車下去了,哈哈
    有時(shí)候需要打印一個(gè)范圍內(nèi)的變量值,可以這樣搞:
    while $idx < upper_limit
    p a[$idx++]
    end
    設(shè)置條件斷點(diǎn):b 234 if page == 48
    修改變量的值,用set var a=3,也可以用p a=3

    x/x 以十六進(jìn)制輸出 x/d 以十進(jìn)制輸出 x/c 以單字符輸出 x/i  反匯編 – 通常,我們會(huì)使用 x/10i $ip-20 來查看當(dāng)前的匯編($ip是指令寄存器)x/s 以字符串輸出 bt #查看堆棧信息
    bt full #查看堆棧信息,并同時(shí)打印local變量
    f 2 #切換到當(dāng)前堆棧的第2層
    info locals #查看當(dāng)前的臨時(shí)變量
    info thread #查看目前所有的線程
    thread 2 #切換到2號線程
    break file.c:100 thread 3 #只在3號線程設(shè)置斷點(diǎn)
    set scheduler-locking on #只調(diào)試當(dāng)前線程,即不會(huì)在調(diào)試過程中被其他線程切進(jìn)來
    info macro DEBUG 你可以查看DEBUG這個(gè)宏在哪些文件里被引用了,以及宏定義是什么樣的。 macro DEBUG 你可以查看DEBUG宏展開的樣子;但需要在GCC編譯程序的時(shí)候,加上-ggdb3參數(shù),這樣,你就可以調(diào)試宏了。
       
    (gdb) set $idx = 0
    (gdb) p a[$idx++]  #然后就可以一路回車下去了,哈哈

    gdb -c core.2234 //可以從打印到屏幕上的信息的最后部分看到產(chǎn)生這個(gè)core文件的命令包括參數(shù)
    gdb a.out core.2234 //可以查看bt信息,也可以看到產(chǎn)生core文件的命令和參數(shù),然后運(yùn)行set args XXXX就可以設(shè)定參數(shù)了,然后run就可以重新跑起來,可以在core之前設(shè)定breakpoints,當(dāng)運(yùn)行到要產(chǎn)生core的那一行(例如是38行),可以用jump 39來跳過該行的執(zhí)行,這么調(diào)試的好處在于可以隨時(shí)print 一個(gè)函數(shù)的運(yùn)行結(jié)果,例如print obj.do(),而程序沒有正在運(yùn)行時(shí),是無法print一個(gè)函數(shù)的執(zhí)行結(jié)果的.

    gdb里查看源代碼需要增加額外路徑:
    (gdb) show directories 
    Source directories searched: $cdir:$cwd
    (gdb) directory //這個(gè)命令會(huì)清空所有路徑,最好別這么干
    (gdb) directory XXX/XXX //這個(gè)命令會(huì)增加一個(gè)搜索的路徑
    gdb查看指針類型時(shí),如果是基類指針,希望看到到底是哪個(gè)子類時(shí),使用:
    (gdb) set print object //這個(gè)命令可以讓print一個(gè)基類指針時(shí),可以看到其到底是哪個(gè)子類指針
    gdb查看一個(gè)變量的類型,簡單點(diǎn)可以用whatis,如果要查看其完整的聲明,用ptype,如果只想看里面的成員變量,用p *XXX;
    gdb里調(diào)用函數(shù),需要程序當(dāng)前在run才行,例如p str.length();對于std::string類型,調(diào)試core文件時(shí)用下面命令查看里面的內(nèi)容:
    printf "String \t\t\t= \"%s\"\n", $arg0._M_dataplus._M_p
    printf "String size/length \t= %u\n", (((std::string::_Rep*) ($arg0._M_dataplus._M_p))[-1])._M_length
    printf "String capacity \t= %u\n", (((std::string::_Rep*) ($arg0._M_dataplus._M_p))[-1])._M_capacity
    printf "String ref-count \t= %d\n", (((std::string::_Rep*) ($arg0._M_dataplus._M_p))[-1])._M_refcount
    完整的.gdbinit文件請參見另外一篇帖子http://m.tkk7.com/bacoo/archive/2012/11/07/390979.html

    x/x 以十六進(jìn)制輸出 x/d 以十進(jìn)制輸出 x/c 以單字符輸出 x/i  反匯編 – 通常,我們會(huì)使用 x/10i $ip-20 來查看當(dāng)前的匯編($ip是指令寄存器)x/s 以字符串輸出

    如果需要調(diào)試stl里面的東西,即可以step into libstdc++中,在ubuntu下的方法如下:
    1。安裝libgcc1-dbg和libstdc++6-4.4-dbg;安裝完之后會(huì)發(fā)現(xiàn)在/usr/lib/debug/下多了些東西:lib  libstdc++.a  libstdc++.so  libstdc++.so.6  libstdc++.so.6.0.13
    2。$ gdb --quiet test
    (gdb) start
    Temporary breakpoint 1 at 0x8048977: file t5.cpp, line 14.
    Starting program: /home/bacoo/test
    [Thread debugging using libthread_db enabled]

    Temporary breakpoint 1, main (argc=1, argv=0xbfffed64) at t5.cpp:14
    14          size_t pos, begin_pos = 0;
    (gdb) info sharedlibrary
    From        To          Syms Read   Shared Object Library
    0x00110830  0x001277af  Yes (*)     /lib/ld-linux.so.2
    0x00133610  0x0013fad8  Yes (*)     /lib/libpthread.so.0
    0x0018d2e0  0x001fecd8  Yes (*)     /usr/lib/libstdc++.so.6
    0x002374b0  0x002517f8  Yes (*)     /lib/libm.so.6
    0x0025bf50  0x00272438  Yes         /lib/libgcc_s.so.1
    0x0028cac0  0x00396a74  Yes (*)     /lib/libc.so.6
    (*): Shared library is missing debugging information.
    (gdb) show debug-file-directory
    The directory where separate debug symbols are searched for is "/usr/lib/debug".
    (gdb)
    注意,上面的libgcc_s.so.1和libstdc++.so.6兩個(gè)lib,其中l(wèi)ibgcc已經(jīng)有symbol了,而libstdc++還沒有symbol(這個(gè)是根據(jù)Yes之后是否有(*)看出來的),
    如果是這種情況的話,那退出gdb,然后執(zhí)行:
    $ LD_LIBRARY_PATH=/usr/lib/debug gdb --quiet test
    (gdb) start
    Temporary breakpoint 1 at 0x8048977: file t5.cpp, line 14.
    Starting program: /home/bacoo/test
    [Thread debugging using libthread_db enabled]

    Temporary breakpoint 1, main (argc=1, argv=0xbfffed44) at t5.cpp:14
    14          size_t pos, begin_pos = 0;
    (gdb) info sharedlibrary
    From        To          Syms Read   Shared Object Library
    0x00110830  0x001277af  Yes (*)     /lib/ld-linux.so.2
    0x00133610  0x0013fad8  Yes (*)     /lib/libpthread.so.0
    0x001913a0  0x00212b58  Yes         /usr/lib/debug/libstdc++.so.6
    0x0024c4b0  0x002667f8  Yes (*)     /lib/libm.so.6
    0x00270f50  0x00287438  Yes         /lib/libgcc_s.so.1
    0x002a1ac0  0x003aba74  Yes (*)     /lib/libc.so.6
    (*): Shared library is missing debugging information.
    (gdb)
    哈哈,libstdc++也有了symbol了,這樣就可以設(shè)置斷點(diǎn),然后step into就可以跟蹤到stl的內(nèi)部了。

    ============================================
    linux下用vpn,安裝openconnect這個(gè)包,
    sudo /usr/bin/openconnect --script=/etc/vpnc/vpnc-script Your-Vpn-Server-Address
    ============================================
    > cat close.gdb
    p close(1)
    p close(2)
    #p dup2(open("/dev/null",0),1) #another way to close stdout
    #p dup2(open("/dev/null",0),2) #another way to close stderr
    #p open("/dev/pts/4", 1)     #redirect stdout to another tty
    #p open("/tmp/myerrlog", 1)  #redirect stdout to another file
    detach
    q
    > gdb -p 3465 -x close.gdb

    如果希望每次程序中斷后可以看到即將被執(zhí)行的下一條匯編指令,可以使用命令
    "display /i $pc"
    其中 $pc 代表當(dāng)前匯編指令,/i 表示以十六進(jìn)行顯示。當(dāng)需要關(guān)心匯編代碼時(shí),此命令相當(dāng)有用。
    undispaly,取消先前的display設(shè)置,編號從1開始遞增。
    b *main”在 main 函數(shù)的 prolog 代碼處設(shè)置斷點(diǎn)(prolog、epilog,分別表示編譯器在每個(gè)函數(shù)的開頭和結(jié)尾自行插入的代碼)
    info registers #查看所有寄存器變量
    info registers rax #查看寄存器rax的值
    p $rax #查看寄存器rax的值
    disassemble #查看匯編代碼
    set disassembly-flavor intel # 設(shè)置反匯編格式
    x/1uw $rbp-0x8 #查看某個(gè)內(nèi)存地址里的值
    info proc mappings #查看進(jìn)程地址空間中各塊內(nèi)存的分配
    set follow-fork-mode child #調(diào)試子進(jìn)程
    layout src #使用tui(Text User Interface),打開src和cmd兩個(gè)窗口
    layout split #使用tui,打開src,assemble,cmd三個(gè)窗口
    使用ctrl+x ctrl+a 或者 ctrl+x A 關(guān)閉tui
    使用ctrl+x o來切換active的窗口
    set environment varname [=value] 設(shè)置環(huán)境變量。如:set env USER=user
    部分引用自:http://laokaddk.blog.51cto.com/368606/945057 以及http://blog.csdn.net/kuike/article/details/2065999
    打印符號所處的源代碼位置:
    info line <function_name>
    python (lambda s: [print(i.symtab,":",i.line) for i in gdb.lookup_static_symbols(s)])("one")
    python (lambda s: print(s.symtab,":",s.line))(gdb.lookup_symbol("<variable_name>")[0])
    ============================================================================================
    如果有部分swap內(nèi)存被使用了,而這個(gè)時(shí)候主存還有地方,可以把swap里的內(nèi)容挪動(dòng)到主存里,方法是:
    sudo swapoff -a && sudo swapon -a

     

    =============================================================================================

    在本機(jī)假設(shè)一個(gè)最簡單的http server的方法是:python -m SimpleHTTPServer &  #會(huì)偵聽本機(jī)的8000端口,服務(wù)目錄就是當(dāng)前目錄
    用netstat查看tcp協(xié)議監(jiān)聽的端口:netstat -nlpt
    用netstat查看udp協(xié)議監(jiān)聽的端口:netstat -nlpu
    當(dāng)然也可以用netstat -nlptu一并查看tcp和udp協(xié)議監(jiān)聽的端口

    用netstat查看tcp的連接:netstat -anpt
    用netstat查看udp的連接:netstat -anpu
    當(dāng)然也可以用netstat -anptu一并查看tcp和udp協(xié)議的連接

    探測一臺(tái)remote機(jī)器是否打開了某個(gè)端口,一般我們用telnet ip port,但這種方法不成功的時(shí)候并不能肯定這個(gè)端口就一定是closed,而且對于udp協(xié)議的端口,該方法也不奏效,正確的方法是:
    nc -z ip port && echo tcp port open || (nc -z ip port && echo udp port open || echo no tcp/udp port open)
    或許一些機(jī)器上沒有安裝nc,可以試試看是否安裝了netcat,這兩個(gè)工具是一樣的。
    再簡要說說netcat這個(gè)工具,這個(gè)工具很有用,從名字上就看得出來它的用途,我們知道cat是針對文件進(jìn)行bytes流的in/out,而netcat是針對網(wǎng)絡(luò)端口進(jìn)行bytes流的in/out。
    比如
    1。netcat -l -p 13001 > t3.3 &   #listening 0.0.0.0:13001,把收到的內(nèi)容重定向到t3.3文件中,或許該命令需要修改為netcat -l 127.0.0.1 13001 > t3.3 &
    2。echo "hello world" | netcat 127.0.0.1 13001  #向127.0.0.1:13001端口灌入一定的bytes
    3。cat t3.3  #t3.3中的內(nèi)容就是hello world
    網(wǎng)絡(luò)上有一篇介紹基于udp的ssh tunnel的文章,就是用到了netcat這個(gè)工具:http://zarb.org/~gc/html/udp-in-ssh-tunneling.html

    可以通過tcpdump來查看一個(gè)端口上收發(fā)的所有包:
    tcpdump -vv -n -i lo 'tcp port 10000'

    ===================================================================

    vi小技巧:

    先按q再按:,則會(huì)出現(xiàn)歷史命令

    使用sudo權(quán)限保存w !sudo tee %

    在命令模式下,Ctrl+w,然后再按q即可退出,ZZ也可以退出

    Ctrl+o是退回到上次編輯的位置

    Ctrl+g可以顯示當(dāng)前編輯的文件名以及編輯的行數(shù)和列數(shù)

    %是匹配括號

    在~/.vimrc中輸入以下兩行可以實(shí)現(xiàn)再次打開文件時(shí)光標(biāo)位置被保存:

    " 打開文件時(shí),按照 viminfo 保存的上次關(guān)閉時(shí)的光標(biāo)位置重新設(shè)置光標(biāo)
    au BufReadPost * if line("'\"") > 0|if line("'\"") <= line("$")|exe("norm '\"")|else|exe "norm $"|endif|endif

    命令行Readline的快捷鍵:

    Ctrl+a/e:跳到行首/尾;Ctrl+u/k:刪除前/后面的內(nèi)容;Ctrl+h/d:刪除前/后一個(gè)字符;Ctrl+b/f:移動(dòng)前/后一個(gè)字符;Ctrl+p/n:查看前/后一條命令;Ctrl+Esc+r:恢復(fù)該行最初始的狀態(tài);Ctrl+r/s:向前/后根據(jù)搜索詞在歷史命令中進(jìn)行搜索(其實(shí)還有 Ctrl+s 是正向增量查找的,但是由于這個(gè)快捷鍵被終端預(yù)設(shè)成鎖屏幕了,沒有效果。不過可以使用命令 stty -ixon -ixoff來解除綁定,恢復(fù)可以用stty ixon ixoff<其此處的設(shè)置對應(yīng)了Ctrl+s/q這組命令,即鎖定/解鎖屏幕,尤其用在屏幕上出現(xiàn)飛速的碼流的時(shí)候有效果>);Alt+b/f:向前/后移動(dòng)一個(gè)單詞;Alt+Backspace/d:向前/后刪除一個(gè)單詞;要想了解更多這方面的快捷鍵可以使用bind -P

    syndaemon -d -i 4可以使得:當(dāng)你輸入文字時(shí),觸摸板失效4秒

    showkey -a可以顯示鍵盤上任意一個(gè)鍵的ascii碼值,Ctrl+v加Ctrl+<key>能顯示該鍵的鍵盤碼

    grep的-I選項(xiàng)(大寫的i)可以讓它不搜索binary文件,而-a選項(xiàng)是搜索所有文件,binary文件也會(huì)當(dāng)成文本文件去搜索,此外還可以配合--exclude/include=GLOB來排除文件或者搜索特定文件,--exclude-dir=DIR可以排除一個(gè)或多個(gè)文件夾,-o選項(xiàng)只搜索出匹配的部分,比如你要在~目錄下搜索隱藏文件中的配置文件中的一些信息,可以這樣: grep <searchword> -RI --include=.*  --exclude-dir=.ies4linux .

    在所有命令中查找匹配的命令: ls ${PATH//:/\ /} | grep <searchword>

    有關(guān)對readline的控制,強(qiáng)烈推薦下面這兩篇文章:

    http://blog.chinaunix.net/u1/43271/showart_340284.html

    http://hi.baidu.com/riant/blog/item/aacf7cd9d0f91fe939012f88.html

    這里我對bind命令作一下說明,舉個(gè)例子好了,設(shè)定Ctrl+t是正向搜索歷史命令(相對于Ctrl+r反向搜索):如果臨時(shí)使用,那么bind '"\C-t": forward-search-history'即可;如果長久保存,那么首先在~/.bashrc中設(shè)定export INPUTRC=/etc/inputrc,然后編輯/etc/inputrc,增加一行:"\C-t": forward-search-history即可。我還在/etc/inputrc中設(shè)定了"C-xf": dump-functions和"C-xv": dump-variables以及"C-xm": dump-macros三行,分別用于打印出所有可以設(shè)置的函數(shù)、變量、以及宏。注意:每次你修改完/etc/inputrc文件后,需要Ctrl-x然后Ctrl-r才能使修改發(fā)揮作用。

    在X的終端里,Ctrl+Shift+up/down可以實(shí)現(xiàn)屏幕的上下滾動(dòng),一行一行的滾動(dòng);shift+pageup/pagedown實(shí)現(xiàn)一屏一屏的滾動(dòng)

    ls的小技巧:

    alias ls='ls --color=tty'
    alias ll='ls -l --color=tty'
    alias l.='ls -a -d .* --color=tty'
    alias lD='ls -a -d --color=tty .*/; ls -d */ --color=tty'
    alias la='ls -A'

    strace -p <PID>可以看到該進(jìn)程執(zhí)行的系統(tǒng)調(diào)用,其實(shí)該命令會(huì)把一個(gè)進(jìn)程先attach然后分析,最后再釋放。

    還是bind的使用,我們可以配置ctrl+m來選擇一個(gè)目錄下的文件,這個(gè)特性對于那些文件名字特別難輸入的文件或目錄特別有幫助,你可以設(shè)想一下當(dāng)在字符終端上沒有鼠標(biāo),且沒安裝中文輸入法時(shí),你想打開一個(gè)含有中文文件名的文件是多么困難,但是有了這個(gè)特性,你就可以自由選擇了。實(shí)施方法如下:

    編輯/etc/inputrc,找到類似這行的(沒有就添加):
    代碼:
    $if mode=emacs
    "\C-o": menu-complete

    或者在命令行直接使用bind '"\C-o":menu-complete'也可以。

    ================================

    mv foo.{jpeg,jpg}#這個(gè)命令將把foo.jpeg改名為foo.jpg。
    !! 是整條命令和所有參數(shù)
    !* 將代替上一個(gè)命令的所有參數(shù)
    !$ 上一條命令的最后一個(gè)參數(shù)
    !:3  上一條命令的第3個(gè)參數(shù) 

    ===========================================

    vi學(xué)習(xí)
    :r !command: 將命令command的輸出結(jié)果放到當(dāng)前行
    :e filename: 打開文件filename進(jìn)行編輯(會(huì)關(guān)閉當(dāng)前文檔重新打開新文檔,可以使用Ctrl+O/I來切換)
    :n1,n2 d: 將 n1行到n2行之間的內(nèi)容刪除
    :r filename: 將文件中的內(nèi)容全部插入到當(dāng)前位置

    Ctrl+a: 如果當(dāng)前光標(biāo)下的字符串中,從當(dāng)前位置起能在后續(xù)連續(xù)的字符串中找到數(shù)字,那么按一次Ctrl+a就會(huì)使得該數(shù)字加1,比如abc23, 那么就會(huì)使得23變?yōu)?4
    s: 刪除當(dāng)前字符,并切換到插入模式,可以允許你輸入文本
    H: 光標(biāo)移至屏幕頂行
    M: 光標(biāo)移至屏幕中間行
    L: 光標(biāo)移至屏幕最后行
    nz: 將第n行滾至屏幕頂部,不指定n時(shí)將當(dāng)前行滾至屏幕頂部,注意需要回車一下才生效。

    vi +n filename: 打開文件,并將光標(biāo)置于第n行首
    ?pattern: 從光標(biāo)開始處向文件首搜索pattern

    w或W : 光標(biāo)右移一個(gè)字至字首
    b或B : 光標(biāo)左移一個(gè)字至字首
    dw: 刪除右邊的一個(gè)字
    db: 刪除左邊的一個(gè)字

    browse vs/split: 用瀏覽窗口輔助你打開文件
    Ctrl+w,w  用于窗口間切換, 用Ctrl+w,Ctrl+w也可以, 這里主要考慮到了按鍵方便
    Ctrl+w,o  只保留當(dāng)前窗口, 關(guān)閉其他窗口
    Ctrl+w,=  平均分配各個(gè)窗口
    Ctrl+w,數(shù)字<  在垂直切分窗口時(shí),縮小當(dāng)前窗口尺寸
    Ctrl+w,數(shù)字>  在垂直切分窗口時(shí),放大當(dāng)前窗口尺寸
    Ctrl+w,數(shù)字-  在水平切分窗口時(shí),縮小當(dāng)前窗口尺寸
    Ctrl+w,數(shù)字+  在水平切分窗口時(shí),放大當(dāng)前窗口尺寸
    Ctrl+w,c  關(guān)閉當(dāng)前窗口
    Ctrl+w,s  將當(dāng)前窗口橫著切割出另一個(gè)窗口, Ctrl+w,n也可以
    Ctrl+w,v  將當(dāng)前窗口豎著切割出另一個(gè)窗口
    :split 文件名  用于在當(dāng)前窗口中橫著切割出一個(gè)新的窗口, 并且將文件打開
    :vs 文件名  用于在當(dāng)前窗口中豎著切割出一個(gè)新的窗口, 并且將文件打開

    mark標(biāo)記: 新建一個(gè)標(biāo)記用m, 后面可接數(shù)字或字母,  小寫字母僅能用于本文件中根據(jù)標(biāo)記定位光標(biāo)位置, 大寫字母可以實(shí)現(xiàn)文件之間的切換, 例如ma,m3,mA; 定位一個(gè)標(biāo)記用單引號, 例如'a,'3,'A. 這里再舉個(gè)應(yīng)用mark的例子, 在命令行模式下:'a,'b d用于刪除從'a到'b之間所有的行. 查看所有的mark的命令是:marks

    vi的寄存器: 用雙引號來建立, vim常用的寄存器有:
    ""     無名寄存器,包含最近刪除或抽出的文本
    "%     當(dāng)前文件名
    "#     輪換文件名
    "*     剪貼板內(nèi)容 (X11中表示 鼠標(biāo)選擇的區(qū)域)
    "+     剪貼板內(nèi)容
    "/     最近的搜索模式
    ":     最近的命令行
    ".     最近插入的文本
    "_     黑洞
    更為詳細(xì)的內(nèi)容請參見http://blog.chinaunix.net/u/553/showart_361240.html和http://blog.chinaunix.net/u/9465/showart_448822.html
    調(diào)用寄存器時(shí), 在普通模式可以用雙引號來調(diào)用, 如"a, 在插入模式下可以用Ctrl+r,a來調(diào)用寄存器a;對于用大寫字母表示的寄存器比如A, 代表向寄存器a中追加內(nèi)容; 查看所有寄存器的內(nèi)容用:reg
    "+y用于把vi中選中的部分復(fù)制到系統(tǒng)剪貼板上; "+yy用于把當(dāng)前行復(fù)制到系統(tǒng)剪貼板上;"+p用于把系統(tǒng)剪貼板上的東西復(fù)制到當(dāng)前位置

    查看所有對文件的改動(dòng)用:changes

    vi使用ctags和taglist:
    在工程的頂層目錄下ctags -R
    vi –t main//可以打開所有定義了main函數(shù)的cpp文件
    :ts//會(huì)列出所有定義了main函數(shù)的位置, 你可以通過鍵入數(shù)字來選擇
    :tp//會(huì)在選擇下一個(gè)出現(xiàn)了main函數(shù)的cpp文件來顯示
    :tn//會(huì)在選擇上一個(gè)出現(xiàn)了main函數(shù)的cpp文件來顯示
    說明: 上面的ts,tp,tn都是針對vi -t main這個(gè)應(yīng)用來談的, 其實(shí)它們也可以脫離這種場景去使用, 總之它們就是構(gòu)建在ctags之上的, 用于搜索所有源文件中定義的變量或函數(shù)名之類的東西.

    WEB相對于web來說是長單詞移動(dòng)命令,即只認(rèn)識(shí)空格和換行
    {/}到上/下一段落
    [[/]]到上/下一個(gè)代碼塊{...}的開始處
    [{/]}到當(dāng)前代碼塊{...}的{/}
    (/)移動(dòng)到句首/尾
    S在當(dāng)前行的任何一個(gè)位置運(yùn)行該命令,可以把當(dāng)前行的內(nèi)容清空,然后移動(dòng)到行首進(jìn)入插入模式等待你輸入字符, 該命令等同于cc命令
    3S把當(dāng)前的三行內(nèi)容清空,并移動(dòng)到行首且進(jìn)入插入模式等待輸入
    s清空當(dāng)前字符,并進(jìn)入插入模式等你輸入字符
    10s清空當(dāng)前的10個(gè)字符,并進(jìn)入插入模式等你輸入字符,實(shí)際上對s和S的比較標(biāo)準(zhǔn)的翻譯是s多字符替換單字符,S整行替換
    .可以重復(fù)執(zhí)行上一次的改變, 所謂改變指的是插入(i)或者刪除(d)或者替換(r)或者改變(c)的一次原子操作, 也就是不能將先刪除(d)3個(gè)字符再插入(i)5個(gè)字符這件事作為一個(gè)整體來對待, 如果想把這種情況用一次原子操作來完成, 你可以用c命令, 該命令會(huì)先直接把你想要改變的那個(gè)3個(gè)字符刪掉再允許你輸入5個(gè)字符作為替換
    qa開始錄制宏,并報(bào)存在寄存器a中,再次輸入q即可停止錄制宏,錄制宏的時(shí)候要注意在使用hjkl這些移動(dòng)光標(biāo)的命令時(shí)確保應(yīng)用宏的時(shí)候不會(huì)有什么偏差,建議最好使用命令能定位光標(biāo),比如fFtT這樣的一行內(nèi)的查找命令,有一篇文章舉的例子非常好:http://autodev.net/autodev/discuz/viewthread.php?tid=33
    :ab可以list出目前所有已經(jīng)有的縮寫
    :ab hl hello world!可以用hl這個(gè)縮寫來代替hello world!,當(dāng)你在insert模式下輸入hl后,再鍵入空格或者換行時(shí)就會(huì)發(fā)生上述的替換
    :unab hl撤銷hl這個(gè)縮寫
    d3w將刪除光標(biāo)后 3 個(gè)單詞
    d2j將刪除當(dāng)前行和下兩行
    :%s/regexp/replacement/gc可以讓你在替換之前確認(rèn)一下
    <</>>將當(dāng)前行向左/右縮進(jìn)一次,縮進(jìn)一次的大小取決于tabstop被設(shè)定的大小
    Ctrl+d/t在插入模式下向左/右縮進(jìn)當(dāng)前行
    ^移動(dòng)到當(dāng)前行的第一個(gè)非空白字符
    -/+移動(dòng)到上/下一行的第一個(gè)非空白字符
    ]p粘貼的時(shí)候會(huì)考慮到縮進(jìn)

    下面這個(gè)映射能夠使得在可視模式下選擇的文本,當(dāng)你按下'/'鍵時(shí)由擴(kuò)展可視范圍改為搜索選擇的文本

    :vmap / y/<C-R>"<CR>

    下面的鍵映射能夠使得在insert mode下移動(dòng)光標(biāo):

    " 在插入模式下,移動(dòng)光標(biāo)
    imap <C-h> <C-o>h
    imap <C-j> <C-o>j
    imap <C-k> <C-o>k
    " to the left character, this way can go to the behind of last character
    imap <C-l> <ESC>la
    " to the begin of line
    imap <C-a> <ESC>0i
    " to the end of line
    imap <C-u> <ESC>A


    set list
    set listchars=tab:>-,trail:-
    highlight WhitespaceEOL ctermbg=magenta guibg=magenta
    match WhitespaceEOL /\s\+$\|\t/
    "highlight __SPACE ctermbg=yellow guibg=yellow
    "2match __SPACE / /

    ====================================
    ls -sSh
    ====================================
    發(fā)現(xiàn)驚天大秘密:呵呵,以前總覺得^A^B這些東西很奇怪,現(xiàn)在不覺得奇怪了,其實(shí)是有這樣一種邏輯在里面的:^A代表ascii碼為1的不可見字符,^B代表ascii碼為2的不可見字符,以此類推,因此我們最最熟悉的^M就代表ascii碼為13的字符了,也就是回車符號,而在linux的文本中都是使用換行符號作為行與行之間的分隔符的,因此^J就代表了換行符號,你可以用showkey -a來驗(yàn)證我說的這些東西,但^這個(gè)符號要用ctrl鍵來代替,因此你要輸入ctrl+m才能看到效果。

    =============================
    top使用:
    f/o:選擇其他列;F/O:選擇要按之排序的列;R:反向排序;c:顯示完整的命令
    行;u:指定顯示某個(gè)用戶相關(guān)的信息;1:數(shù)字1顯示分開顯示多核 CPU;k:殺死
    某個(gè)PID;s:設(shè)置刷新的時(shí)間間隔;A:分四屏從不同角度顯示;G:從四種可供選
    擇的顯示組合中選定一種特定的顯示組合;B:加粗顯示 head里的數(shù)字信息;z:
    切換為紅黃顏色顯示;Z:選擇顏色顯示;</>:默認(rèn)按照%CPU排序,選定的排序的
    列向左/右移動(dòng)一列。
    ========================
    info的使用:
    b是到開頭,e是到結(jié)尾;到了某個(gè)結(jié)點(diǎn)回車是進(jìn)入,u是返回上級;l(小寫的L)相當(dāng)于后退;空格是向下翻頁,page up/down是向上/下翻頁;?是幫助;n和p分別是到下一個(gè)或上一個(gè)結(jié)點(diǎn)。
    ===========================
    screen使用:
    配置~/.screenrc為:

    altscreen on
    startup_message off
    defscrollback 100000
    #escape ^Xx
    backtick 1 0 0 sh -c 'echo $(ifconfig | grep Mask: | cut -d: -f2 | cut -d" " -f1 | grep -v 127.0.0.1; curl -s ifconfig.me)'
    backtick 2 60 60 sh -c 'uptime | sed -e "s/.*up *//" -e "s/,.*//"'
    #caption always "%{= wk} %{= KY} [%n]%t @ %H %{-} %= %{= KR} %l %{-} | %{= KG} %Y-%m-%d %{-} "
    ##hardstatus alwayslastline " %-Lw%{= Bw}%n%f %t%{-}%+Lw %=| %0c:%s "
    hardstatus alwayslastline "%{= KY} %-Lw%{= Bw}%n%f %t%{-}%+Lw %=@%H(%1`) %{=b KG}||%{-} %m/%d %0c %{=b KG}||%{-} up %2` %{=b KG}||%{-} %l"
    # mouse tracking allows to switch region focus by clicking, and you can't select texts by double-click texts if you open this flag
    # mousetrack on
    # get rid of silly xoff stuff
    bind s split
    # layouts
    layout autosave on
    # layout one region
    layout new one
    select 1
    # layout two region
    layout new two
    select 1
    split
    resize -v +8
    focus down
    select 4
    focus up
    # layout three region
    layout new three
    select 1
    split
    resize -v +7
    focus down
    select 3
    split -v
    resize -h +10
    focus right
    select 4
    focus up
    layout attach one
    layout select one
    # navigating regions with Ctrl-arrows
    bindkey "^[[1;5D" focus left
    bindkey "^[[1;5C" focus right
    bindkey "^[[1;5A" focus up
    bindkey "^[[1;5B" focus down
    # switch windows with F3 (prev) and F4 (next)
    bindkey "^[OR" prev
    bindkey "^[OS" next
    # switch layouts with Ctrl+F3 (prev layout) and Ctrl+F4 (next)
    bindkey "^[[1;5R" layout prev
    bindkey "^[[1;5S" layout next
    # F2 puts Screen into resize mode. Resize regions using hjkl keys.
    bindkey "^[OQ" eval "command -c rsz" # enter resize mode
    # use hjkl keys to resize regions
    bind -c rsz h eval "resize -h -5" "command -c rsz"
    bind -c rsz j eval "resize -v -5" "command -c rsz"
    bind -c rsz k eval "resize -v +5" "command -c rsz"
    bind -c rsz l eval "resize -h +5" "command -c rsz"
    # quickly switch between regions using tab and arrows
    bind -c rsz \t    eval "focus"       "command -c rsz" # Tab
    bind -c rsz -k kl eval "focus left"  "command -c rsz" # Left
    bind -c rsz -k kr eval "focus right" "command -c rsz" # Right
    bind -c rsz -k ku eval "focus up"    "command -c rsz" # Up
    bind -c rsz -k kd eval "focus down"  "command -c rsz" # Down

    使用時(shí),新建一個(gè)tab是ctrl+a,c;退出一個(gè)tab是ctrl+d(其實(shí)就是正常退出即可,當(dāng)然你也可以使用screen為你提供的ctrl+a,k來實(shí)現(xiàn));退出所有的tab是ctrl+a,:quit或者是ctrl+a,ctrl+\也可以; 想退出screen干點(diǎn)別的事,但是卻不終止screen里面的進(jìn)程,這叫detach,用ctrl+a,d可以實(shí)現(xiàn),下次再想進(jìn)入那個(gè)screen的時(shí)候,需要screen -ls一下看看當(dāng)前都有那些screen, 然后screen -r <名字>來進(jìn)入你想進(jìn)入的screen, 當(dāng)然你也可以在啟動(dòng)screen的時(shí)候這么干: screen -S hello,當(dāng)你detach screen之后想再次進(jìn)入,那就screen -r hello即可.
    ctrl+a,': select a tab;
    ctrl+a,": open window manager to select a tab;

    Ctrl+a S split terminal horizontally into regions Ctrl+a c to create new window there
    Ctrl+a | split terminal vertically into regions Requires debian/ubuntu patched screen 4.0
    Ctrl+a :resize resize region  
    Ctrl+a :fit fit screen size to new terminal size Ctrl+a F is the same. Do after resizing xterm
    Ctrl+a :remove remove region Ctrl+a X is the same
    Ctrl+a tab Move to next region

    admin login
    screen -S class1
    Ctrl-a :multiuser on
    Ctrl-a :acladd lili

    lili login
    screen -x admin/session
    Ctrl-a :aclchg lili -w "#"

    Ctrl-a :wall message

    For detail info, plz refer to: http://www.linux.com/archive/feed/56443
    如果screen的sock文件被刪了(默認(rèn)是在/tmp/下),導(dǎo)致無法attach,可以重建sock文件,方法是kill -CHLD 30860 #30860為screen進(jìn)程的pid
    ===============================
    對于sudo這個(gè)命令,修改配置文件/etc/sudoers時(shí)直接用visudo就可以了,連文件名都省略了,而且還可以幫助你檢查格式,關(guān)于怎么寫配置文件的內(nèi)容,請使用man sudoers,在幫助的最后部分給出了大量的實(shí)例,足夠你使用了,如果覺得看英文不爽,網(wǎng)上有很多這份man sudoers的中文版,比如http://www.fengnet.com/showart.asp?art_id=587&cat_id=10 我來總結(jié)一下,其實(shí)定義的格式就是who hosts = (可以偽裝成的用戶) [NOPASSWD:] commands
    ==============================
    對于sort命令, 最復(fù)雜的莫過于對POS1和POS2的設(shè)定了, 先給出結(jié)構(gòu):
    -k POS1,POS2 -k POS3,POS4, 例如sort -t : -n -k 5b,5b -k 3,3 /etc/passwd
    多個(gè)-k可以指定多個(gè)排序的鍵, 通常我們很少使得排序的鍵是跨越field的, 因此通常你會(huì)看到像上面那個(gè)例子里描述的那樣, 兩個(gè)5, 兩個(gè)3
    下面就來說一下POS的規(guī)則, 分為新標(biāo)準(zhǔn)和舊標(biāo)準(zhǔn), 新標(biāo)準(zhǔn):F[.C][Mbdfinr], 詳細(xì)說明如下:
    F是數(shù)字,代表第幾個(gè)Field;
    C是數(shù)字,代表Field內(nèi)部的第幾個(gè)字符;
    Mbdfinr代表選項(xiàng), 與sort -[Mbdfinr]一樣, 只不過前者只對當(dāng)前POS有效, 后者對所有有效, 不過前者的優(yōu)先級高于后者, 此處還有一點(diǎn)要說明: 因?yàn)橐粋€(gè)-k會(huì)指定兩個(gè)POS,只要有一個(gè)POS中指定了Mbdfinr即可, 兩個(gè)都指定同一個(gè)也行
    再說說舊標(biāo)準(zhǔn): +POS1 -POS2
    POS的規(guī)則和前面一樣, 但舊標(biāo)準(zhǔn)就只能指定一個(gè)key了, 不能像-k那樣可以搞出多個(gè)來; 而且在舊標(biāo)準(zhǔn)中的Field采用的是間隔的方式, 如果你期望按照第一個(gè)key來排序,那么就得使用+0 -1來實(shí)現(xiàn), 而在新標(biāo)準(zhǔn)中是采用 -k 1,1
    ==================================
    簡要說說lsof最常用的幾種方法:
    lsof 文件 ==>查看文件被那些進(jìn)程占用
    lsof -c bash ==>查看被進(jìn)程名以bash開頭的進(jìn)程占用的文件
    lsof -u root ==>查看root用戶使用到的文件
    lsof -p 2343 ==>查看被進(jìn)程2343打開的文件
    lsof 目錄名 ==>查看目錄下打開的文件, 不遞歸, 深度為1
    lsof +D 目錄名 ==>查看目錄下打開的文件, 遞歸
    lsof -i ==>顯示所有端口建立的連接
    lsof -i :80 ==>顯示所有打開80端口的連接
    lsof -d 4==> 顯示fd為4的進(jìn)程
    lsof -a -d4 -p $$ ==>這里的選項(xiàng)a表示將對d選項(xiàng)和p選項(xiàng)的結(jié)果的AND操作
    ========================
    關(guān)閉筆記本的屏幕的方法: xset dpms force off
    ================================
    vim 提供 6中折疊方式
              manual           手工定義折疊(默認(rèn),常用)
              indent             更多的縮進(jìn)表示更高級別的折疊(常用)
              expr                用表達(dá)式來定義折疊
              syntax             用語法高亮來定義折疊(常用)
              diff                  對沒有更改的文本進(jìn)行折疊
              marker            對文中的標(biāo)志折疊

    set fdm=indent
    如果使用了indent方式,vim會(huì)自動(dòng)的對大括號的中間部分進(jìn)行折疊,我們可以直接使用這些現(xiàn)成的折疊成果。
    indent 對應(yīng)的折疊代碼有:
    zc      折疊
    zC     對所在范圍內(nèi)所有嵌套的折疊點(diǎn)進(jìn)行折疊
    zo      展開折疊
    zO     對所在范圍內(nèi)所有嵌套的折疊點(diǎn)展開
    [z       到當(dāng)前打開的折疊的開始處。
    ]z       到當(dāng)前打開的折疊的末尾處。
    zj       向下移動(dòng)。到達(dá)下一個(gè)折疊的開始處。關(guān)閉的折疊也被計(jì)入。
    zk      向上移動(dòng)到前一折疊的結(jié)束處。關(guān)閉的折疊也被計(jì)入。

    set fdm=manual
    可以使用下面的命令來創(chuàng)建和刪除折疊:
    zf      創(chuàng)建折疊,比如在marker方式下:
                       zf56G,創(chuàng)建從當(dāng)前行起到56行的代碼折疊;
                       10zf或10zf+或zf10↓,創(chuàng)建從當(dāng)前行起到后10行的代碼折疊。
                       10zf-或zf10↑,創(chuàng)建從當(dāng)前行起到之前10行的代碼折疊。
                       在括號處zf%,創(chuàng)建從當(dāng)前行起到對應(yīng)的匹配的括號上去((),{},[],<>等)。
    zd      刪除 (delete) 在光標(biāo)下的折疊。僅當(dāng) 'foldmethod' 設(shè)為 "manual" 或 "marker" 時(shí)有效。
    zD     循環(huán)刪除 (Delete) 光標(biāo)下的折疊,即嵌套刪除折疊。
              僅當(dāng) 'foldmethod' 設(shè)為 "manual" 或 "marker" 時(shí)有效。
    zE     除去 (Eliminate) 窗口里“所有”的折疊。
              僅當(dāng) 'foldmethod' 設(shè)為 "manual" 或 "marker" 時(shí)有效。
           因此,對于fdm=indent之后,如果想消除通篇的折疊,簡單方法就是set fdm=manual,然后zE
    可以通過下面兩個(gè)來控制通篇折疊的啟停:
    :set nofoldenable
    :set foldenable

    ===============================================================
    vim的幫助很詳細(xì),但若不了解有時(shí)的確不知道應(yīng)該如何輸入關(guān)鍵詞,所以總結(jié)一下:
    -----------------------------------------------------------------------------
    條目                                      前綴                       例子
    -----------------------------------------------------------------------------
    Normal模式命令                    無                          :h k
    CTRL控制字符                       CTRL-                     :h CTRL-r
    Visual視圖模式                      v                            :h v_u
    Insert插入模式命令                i                             :h i_CTRL-o
    ex-模式命令                           :                            :h :set                                                                                         
    Command-line命令行編輯     c                            :h c_<BS>
    命令參數(shù)                                -                            :h -m
    選項(xiàng)                                      '                             :h 'winminwidth'
    ------------------------------------------------------------------------------
    哦,還有一些關(guān)鍵詞是用尖括號<>括起來的,如
    :h <Left>
    :h <CR>
    :h <Up>
    :helpg[rep] {pattern}  搜索所有的幫助文本并給出一個(gè)匹配 {pattern} 行的列表, 用:cw打開quickfix窗口看到所有的匹配位置, :cn/p用于向后/前翻看

    另外,在輸入關(guān)鍵詞的時(shí)候,可以按Tab鍵補(bǔ)全,ctrl-d列出與光標(biāo)前面的關(guān)鍵詞所匹配的名字,ctrl-a列出全部模式
    =======================================
    在安裝了vim的插件之后,雖然幫助文檔已經(jīng)放到doc目錄下了,但是還是需要調(diào)用vim的一個(gè)命令才能讓help找到,該命令是::helptags ~/.vim/doc
    =======================================
     vim里面的tab:
    vim *.cpp -p //用多個(gè)tab打開多個(gè)文件
    在normal模式下:
      gt //切換到下一個(gè)tab
      gT //切換到上一個(gè)tab
      Ctrl-w T //把當(dāng)前的window放到一個(gè)新的tab中打開
    在command模式下:
      :tabnew [filename] //打開一個(gè)新的tab
      :tabn //切換到下一個(gè)tab
      :tabp //切換到上一個(gè)tab
      :tabs //list出當(dāng)前所有的tab

    vim里面的gf:
    在noraml模式下:
      gf //打開鼠標(biāo)下的文件
      gF //打開鼠標(biāo)下的文件,并且跳轉(zhuǎn)到指定的行(例如 t1.cpp 20)
      Ctrl+w f //水平切分出一個(gè)新的窗口,里面打開鼠標(biāo)下的文件
      Ctrl+w F //水平切分出一個(gè)新的窗口,里面打開鼠標(biāo)下的文件,并且跳轉(zhuǎn)到指定的行(例如 t1.cpp 20)
      Ctrl+w gf //打開一個(gè)新的tab,里面打開鼠標(biāo)下的文件
      Ctrl+w gF //打開一個(gè)新的tab,里面打開鼠標(biāo)下的文件,并且跳轉(zhuǎn)到指定的行(例如 t1.cpp 20)
    gf, gF, Ctrl+w gf, Ctrl+w gF均支持在visual模式下,只處理visual部分對應(yīng)的文件
    ======================================================================
    gcc/g++步驟拆解:
    gcc -E hello.c -o hello.i//使用cpp命令
    gcc -S hello.i -o hello.s//使用cc1命令
    gcc -c hello.s -o hello.o//使用as命令
    gcc hello.o -o hello//使用ld命令
    注意事項(xiàng):
    1. 這些步驟是對文件名的后綴有要求的,例如-E產(chǎn)生hello.E,然后在-S步驟是不行的;
    2. 用g++可以對cpp文件做同樣的步驟;
    gcc 參數(shù):
    -S: 生成匯編文件
    -E: 輸出預(yù)編譯結(jié)果 或者 用cpp t.cpp也行; 基本上g++ -E就等于cpp
    -H: 編譯并打印出引用的頭文件
    -E -dD: 預(yù)編譯, 并且將用到的宏擴(kuò)展都給列了出來
    -###: 打印出編譯gcc時(shí)用到的參數(shù)
    # 與宏有關(guān)的
    gcc -dM -E - <<< '' -o a.E #查看gcc builtin的宏
    gcc -dM -E a.cpp -o a.dM #查看所有相關(guān)的宏定義
    gcc -dD -E a.cpp -o a.dD #查看所有相關(guān)的宏定義,并且指明出處
    gcc -E a.cpp -o a.E #查看宏替換完成,預(yù)編譯后的結(jié)果
    # 與頭文件有關(guān)的
    gcc -H a.cpp -o a.H #查看所有依賴的頭文件,而且引用關(guān)系通過行前綴.的多少能夠體現(xiàn)出來
    gcc -M a.cpp -o a.M #查看所有依賴的文件
    gcc -MM a.cpp -o a.MM #查看所有依賴的文件,但不包括系統(tǒng)頭文件
    gcc -MM -MP -MD -MF a.dep a.cpp -c -o a.o #正常編譯,但同時(shí)產(chǎn)出一個(gè)附屬品a.dep用于描述編譯a.cpp所有依賴的東西,a.dep可用于Makefile檢測a.cpp依賴是否有變化,這會(huì)比我們通常寫的a.o: a.cpp這種要強(qiáng)大的多;-MD是為了讓編譯繼續(xù)(-E會(huì)導(dǎo)致停在預(yù)編譯階段,-M/-MM/-MP等都會(huì)暗含-E參數(shù),加上-MD則會(huì)又把-E給省略掉);-MP是為了讓a.dep里除了a.cpp的所有依賴之外,還能有每一個(gè)依賴的phony target;-MF是用于指定附屬品的文件名,如果沒有這個(gè)參數(shù),默認(rèn)會(huì)使用a.d(a.d的由來是根據(jù)-o a.o得來的,如果是-o XXX.o,那么就是XXX.d)
    生成靜態(tài)庫用ar crs libtest.a *.o;還可以生成thin archive,用ar crsT libtest.a *.o. thin archive只是存了真正的.o的位置,因此體積很小,而且ar crsT libtest.a libanother.a會(huì)把libanother.a中的.o的位置提取出來放到libtest.a中,對于local build,thin archive非常棒。
    對于從靜態(tài)庫生成動(dòng)態(tài)庫,標(biāo)準(zhǔn)的方法是ar x libtest.a(注意thin archive是不能ar x的,這里的libtest.a是普通的archive),然后再g++ -shared -o libtest.so *.o,但也可以直接用.a來生成.so,如果是普通archive,需要用-Wl,--whole-archive libtest.a -Wl,--no-whole-archive -lpthread -ld(這種方法,當(dāng)多個(gè).a中含有相同符號時(shí),會(huì)出現(xiàn)沖突,因?yàn)樵摲绞綍?huì)把.a中的所有符號都鏈接進(jìn)來);除了可以用--whole-archive方法,還可以用-Wl,--start-group *.a -Wl,--end-group,這種方法會(huì)解決repeated查找中間那些.a文件中的符號,可以解決交叉依賴的問題,但要注意的是位于--start-group和--end-group之間的那些.a,它們只是被用于從中抽取必須的symbol,至于哪些symbol需要被用到,這個(gè)是由為生成.so所顯示指定的.o來決定的,如果不指定任何.o,僅僅用一大堆.a,那么生成的.so中不會(huì)有任何有用的symbol,例如g++ -shared -o libt28.so -Wl,--start-group libt28_1.a libt28_2.a libdict.a -Wl,--end-group產(chǎn)生的libt28.so中就不會(huì)含有l(wèi)ibt28_1.a libt28_2.a libdict.a中的任何symbol;但如果是g++ -shared -o libt28.so -Wl,--start-group libt28_1.a libt28_2.a libdict.a test.o -Wl,--end-group,那么會(huì)根據(jù)test.o中哪些symbol需要從libt28_1.a libt28_2.a libdict.a中得到來決定哪些symbol進(jìn)入最終的libt28.so。雖然.a的本質(zhì)就是.o的集合,但ld對待.a和.o是很不一樣的。ld還有一個(gè)鏈接選項(xiàng)是-u,可以顯示讓某個(gè)symbol變?yōu)閡ndified。
    ==========================================
    清除log中的顏色控制字符:sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g"
    ================================
    more或less里面,默認(rèn)搜索的時(shí)候是大小寫*不敏感*的, 要想改為*敏感*的, 直接在正常狀態(tài)下鍵入-i即可, 再次鍵入-i即可切換到*不敏感*; 在vi里面默認(rèn)搜索是大小寫*敏感*的, 可以在搜索的時(shí)候通過添加\c的suffix改為*不敏感*, 例如輸入/abc\c
    =========================================
    svn merge -r 854:853 test.cpp
    svn diff --summarize -r 853:854
    svn pg svn:externals .
    svn ps svn:externals 'seg_tc https://bj-scm.tencent.com/search/search_discuz_rep/discuz_code_proj/trunk/rela_content/encode3.0/seg_tc' .
    svn ps svn:externals -F svn.externals .
    =========================================
    awk中的map真的很好使,此前沒用到這個(gè)東西,以后要多加利用了,哈哈。
    netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
    =========================================
    ps -eo pid,ppid,lstart,etime,cmd  | grep XXX #lstart代表進(jìn)程開始執(zhí)行的時(shí)間,etime是進(jìn)程運(yùn)行到現(xiàn)在歷時(shí)多久
    ps -ef 可以看到ppid
    =========================================
    grep -P 'a\tb'
    grep "a"$'\t'"b"
    grep 'a    b' #tab鍵的輸入方法是Ctrl+v,然后按tab鍵
    =============================================
    find -size +1000c -size -2000c #查找文件大小在(1000,2000)之間的文件
    find -size 1000c #查找文件大小正好等于1000的文件
    find -mmin -1 #查找近1分鐘之內(nèi)修改過的文件
    find -amin -1 #查找近1分鐘之內(nèi)訪問過的文件
    find -empty #查找空文件或空目錄

    ==============================================

    cat input_file | python -c "import zlib,sys;print zlib.compress(sys.stdin.read())" #用于壓縮,當(dāng)然改為uncompress就可用于解壓縮

    ==================================================

    1. 查看內(nèi)核版本命令:
    cat /proc/version
    uname -a
    2. 查看Linux版本:
    lsb_release -a
    cat /etc/issue
    cat /etc/*release*
    =====================================================
    vim下的cursorline和cursorcolumn
    set   cursorline
    highlight CursorLine ctermbg=lightmagenta term=bold cterm=bold
    "set   cursorcolumn                                                                                                                                                                                                                            
    "set   startofline! "當(dāng)cursorcolumn激活時(shí),當(dāng)ctrl+f/b翻頁時(shí),光標(biāo)會(huì)跑,取消了這個(gè)選項(xiàng)后,光標(biāo)就不跑了
    highlight CursorColumn ctermbg=lightmagenta term=bold cterm=bold

    ==================================================================
    在vi中執(zhí)行命令處理當(dāng)前文檔的內(nèi)容

    :! ls #執(zhí)行一下ls命令
    :.! for i in {1..100}; do echo $i; done #.代表當(dāng)前行,即把當(dāng)前行的內(nèi)容輸入給!后面的命令,!后面的命令用處理后的結(jié)果替換當(dāng)前行
    :%!sort | uniq -c #%代表所有行,即把所有行的內(nèi)容作為input給sort | uniq -c,輸出的結(jié)果再替換原有的所有行的內(nèi)容
    :23,28!grep ok #把23行到28行之間的內(nèi)容輸入給grep ok命令,用處理后的結(jié)果替換23行到28行之間的內(nèi)容
    :%! sudo tee % #第一個(gè)%代表該文檔的所有行,第2個(gè)%代表當(dāng)前的文件名,這個(gè)命令相當(dāng)于cat current_file | sudo tee current_file,其實(shí)就是相當(dāng)于用sudo權(quán)限重新把當(dāng)前內(nèi)容寫到文檔里,這對于我們忘記了用sudo vi current_file的人來說是多么美妙的一件事情啊

     ==============================================

    nm -C //demangle symbol
    nm -D -C //just dynamic symbol, 該選項(xiàng)用于查看so文件中的可以導(dǎo)出的符號,即便so被strip也沒問題
    nm -l -C //print line number

    ==========================================

    編譯時(shí),第一步一般都是./configure
    這個(gè)shell腳本里面是通過pkg-config工具來辨認(rèn)依賴的包是否已經(jīng)安裝,configure過程的日志記錄在config.log文件中,如果configure失敗,可以查看該文件來進(jìn)行診斷
    ./configure --help | grep '\(dis\|en\)able' #查看可以配置的features
    pkg-config工具會(huì)讀取/usr/share/pkgconfig/目錄下的*.pc文件,*.pc文件中記錄了編譯包時(shí)的CFlags以及這個(gè)包在當(dāng)前機(jī)器里的includedir和libdir等信息。有時(shí)候通過dpkg -l會(huì)發(fā)現(xiàn)包已經(jīng)安裝,但卻沒有包對應(yīng)的pc文件,這個(gè)時(shí)候需要安裝該包的dev版。
    可以通過apt-file search XXX.pc來找到包含該文件的安裝包。
    如果某些時(shí)候無法通過apt-get install來安裝dev版的包,可以下載一個(gè)源碼包,然后./configure && make, make -n install可以查看都哪些文件要install,確認(rèn)之后make install,默認(rèn)是安裝到/usr/local/XXX/下面,這時(shí)可以cp /usr/local/XXX/lib/pkgconfig/XXX.pc /usr/share/pkgconfig/下,然后安裝;更好的方法是mkdir here_installation; ./configure --prefix=$PWD/here_installation; make; make install;然后export PKG_CONFIG_PATH=/home/admin/zbar-0.10+doc/ImageMagick-6.8.6-8/here_installation/lib/pkgconfig/,然后再編譯zbar-0.10+doc即可找到需要的pc文件了。
    cmake也是通過pkg-config來檢測包的安裝情況的,它的配置文件是CMakeLists.txt。
    下面這種編譯方式可以編譯出來debug版本的,而且只有靜態(tài)庫:
    ./configure --prefix=$PWD/here_installation --disable-shared CFLAGS="-g -O0" CPPFLAGS="-g -O0" CXXFLAGS="-g -O0"
    ======================================================
    如果ssh連接很慢,可以用ssh -v來看一下debug信息,試試配置一下/etc/ssh/ssh_config文件里的GSSAPIAuthentication no選項(xiàng)。
    ======================================================
    sort -R file 或者shuf file可以random打亂文件順序,可以設(shè)置一個(gè)random的seed通過--random-source=FILE
    ======================================================
    通過gzip壓縮得到的*.gz文件和通過zlib庫壓縮出來的東西不一樣,前者通過zcat或者gunzip可以解壓縮,后者必須通過zlib庫來解壓縮,沒有現(xiàn)成的工具,不過可以使用cat XXX | python -c "import zlib,sys;print repr(zlib.decompress(sys.stdin.read()))"
    =======================================================

     

    wget -e http-proxy=proxy.satwe.com:8080 --proxy=on --proxy-user=hamo --proxy-passwd=8888 -c http://www.satwe.com
    =======================================================

     

    ssh-copy-id user@host

     

    man less | col -b > less.txt #這個(gè)命令可以讓你把man文件轉(zhuǎn)成純文本文件
    PAGER=cat man less > less.txt #這個(gè)命令可以讓你把man文件轉(zhuǎn)成純文本文件
    vim scp://username@host//path/to/somefile #vim一個(gè)遠(yuǎn)程文件
    curl ifconfig.me #當(dāng)你的機(jī)器在內(nèi)網(wǎng)的時(shí)候,可以通過這個(gè)命令查看外網(wǎng)的IP
    wget --random-wait -r -p -e robots=off -U mozilla http://www.example.com #下載整個(gè)www.example.com網(wǎng)站
    screen -d -m -S some_name ping my_router #后臺(tái)運(yùn)行一段不終止的程序,并可以隨時(shí)查看它的狀態(tài)。-d -m參數(shù)啟動(dòng)“分離”模式,-S指定了一個(gè)session的標(biāo)識(shí)。可以通過-R命令來重新“掛載”一個(gè)標(biāo)識(shí)的session。更多細(xì)節(jié)請參考screen用法 man screen
    ssh user@host cat /path/to/remotefile | diff /path/to/localfile - #比較一個(gè)遠(yuǎn)程文件和一個(gè)本地文件
    ssh user@server bash < /path/to/local/script.sh #在遠(yuǎn)程機(jī)器上運(yùn)行一段腳本。這條命令最大的好處就是不用把腳本拷到遠(yuǎn)程機(jī)器上
    man ascii #顯示ascii碼表
    mtr coolshell.cn #mtr命令比traceroute要好
    echo "ls -l" | at midnight #在某個(gè)時(shí)間運(yùn)行某個(gè)命令
    curl -u username -s "https://mail.google.com/mail/feed/atom" | perl -ne 'print "\t" if /<name>/; print "$2\n" if /<(title|name)>(.*)<\/\1>/;' #檢查你的gmail未讀郵件
    tr -c "[:digit:]" " " < /dev/urandom | dd cbs=$COLUMNS conv=unblock | GREP_COLOR="1;32" grep --color "[^ ]" #想看看Marix的屏幕效果嗎?
    echo 123456 | dd cbs=2 conv=unblock #把一行內(nèi)的字符按照固定寬度切分為多行
    ls | xargs -P 5 -i echo "This is:{}" #并行度為5來執(zhí)行命令

    ======================================================================

    搭建web-based ssh terminal
    參考:http://en.wikipedia.org/wiki/Web-based_SSH
    下載https://code.google.com/p/shellinabox/,運(yùn)行:sudo ./shellinaboxd -t -b -q --css=shellinabox/white-on-black.css
    =======================================================================
    jar的使用:
    jar tvf XX.jar;
    jar xvf XX.jar;
    jar cvf XX.jar a.class;
    javac的使用:
    javac -classpath /home/admin/a/b.jar:a/b/c.jar a.java
    使用jode把*.class文件反編譯成*.java文件:
    下載地址:http://jode.sourceforge.net/download.php
    jar xvf jode-1.1.2-pre1.jar
    java jode.decompiler.Main a.jar
    java的使用:
    java -h
    Usage: java [-options] class [args...]
               (to execute a class)
       or  java [-options] -jar jarfile [args...]
               (to execute a jar file)
    java jode.decompiler.Main a.jar #如果jode-1.1.2-pre1.jar里的META-INF/MANIFEST.MF文件里是這么寫的Main-Class: jode.decompiler.Main,那么也可以用java -jar jode-1.1.2-pre1.jar a.jar
    java -jar a.jar arg1 arg2 arg3
    =========================================================
    如果聲音異常,重啟聲卡:
    sudo alsa force-reload
    ===========================================================
    sudo apt-add-repository ppa:werner-jaeger/ppa-werner-vpn
    sudo apt-get update
    sudo apt-get install l2tp-ipsec-vpn

     

    ===========================================================
    man -l XXX.1 可以對指定文件用man
    ===========================================================
    今天觸發(fā)了一個(gè)bug,當(dāng)只有.a文件時(shí),下面兩種編譯是不一樣的:
    g++ -o WpuServer -Ithrift-0.9.0/here_installation/include/ -Iboost_1_53_0  -I../gen-cpp -Lthrift-0.9.0/here_installation/lib/ -pthread -lrt WpuServer.cpp ../gen-cpp/WorkitemProcessUnit.cpp ../gen-cpp/wpu_types.cpp ../gen-cpp/wpu_constants.cpp -lthrift #ld ok
    g++ -o WpuServer -Ithrift-0.9.0/here_installation/include/ -Iboost_1_53_0  -I../gen-cpp -Lthrift-0.9.0/here_installation/lib/ -pthread -lrt -lthrift WpuServer.cpp ../gen-cpp/WorkitemProcessUnit.cpp ../gen-cpp/wpu_types.cpp ../gen-cpp/wpu_constants.cpp #ld error
    ===========================================================
    hadoop fs -cat /home/mr/hadoop/tmp/mapred/system/job_201306051048_50459/job.jar | jar x #用于拿到任務(wù)相關(guān)的所有信息,包括map/reduce相關(guān)的程序和配置以及數(shù)據(jù)文件
    ===========================================================
    perl -e "alarm 2; exec @ARGV" "sleep 3; echo 35" #設(shè)置超時(shí)來運(yùn)行命令
    ===========================================================
    cat myfile | perl -MList::Util=shuffle -e 'print shuffle(<STDIN>);' #替代shuf命令
    ===========================================================
    tac #按照行reverse
    rev #行內(nèi)按照字符reverse
    diff #按照行進(jìn)行diff
    cmp #按照字符進(jìn)行diff
    > test.txt echo "hello world!" #輸出到test.txt文件中
    < test.txt cat #從text.txt文件中讀取內(nèi)容
    cat <(echo "abcd") #cat讀的是一個(gè)文件
    cat < <(echo "abcd") #cat讀的是stdin
    cat <<<"abcd" #cat讀的是stdin
    cat <<{{
    abcd
    {{ #cat讀的是stdin
    cat <<{{ test.txt
    abcd
    {{ #cat讀的是stdin和test.txt文件
    cmp -bl <(echo "abcde") <(echo "abCdE") #比較兩個(gè)等長的字符串,并打印出不同的字符
    =============================================================
    echo a我bc' | grep -P "[\x20-\x7F]"
    grep -o -P '(?<=<text><!\[CDATA\[).*?(?=\]\]></text>)'
    regex有BRE(Basic Regular Expression),ERE(Extended Regular Expression),PCRE(Perl Compatible Regular Expression)三種,GNU的BRE和ERE是一樣的,PCRE支持正反向預(yù)查以及非貪婪模式,上面那個(gè)正則用于從xml中找出<text>...</text>之間的文字,注意.*?,這里的?是表示非貪婪匹配,即盡可能短的去匹配。

    ==============================================================

    $ printf "\xe6\x88\x91\xe4\xbb\xac\n" 
    我們
    $ printf "%'d\n" 23423423423
    23,423,423,423
    < t1.cpp tee >(column -t > t3.3) >(cat -n > t3.4) >/dev/null
    paste -d'@' t3.3 t3.4
    $ echo {1..8} | sed 's/ /\n/' | xargs -n 2
    1 2
    3 4
    5 6
    7 8
    $ echo {1..8} | sed 's/ /\n/g' | xargs -L 2
    1 2
    3 4
    5 6
    7 8
    =============================================================
    screen usage:
    {Ctrl+a x} lock screen
    {Ctrl+a "} select window from list
    {Ctrl+a X} remove one region that is generated by {Ctrl+a S} or {Ctrl+a |}
    {Ctrl+a [} or {Ctrl+a Esc} enter copy mode,
    After enter copy mode, how to mark characters and copy them:
    1. copy one line, Y;
    2. copy one word, W;
    3. copy a range from specific pos in one line: <space> firstly, move cursor, <space> secondly;
    4. copy multiple lines: y, move cursor, <space>;
    {Ctrl+a ]} or {Esc} exit copy mode
    {Ctrl+a >} write paste buffer to file(/tmp/screen-exchange)
    {Ctrl+a <} read from file(/tmp/screen-exchange) into paste buffer
    {Ctrl+a ]} paste buffer into current cmdline

    ================================================================

    如何更改一個(gè)已經(jīng)運(yùn)行的程序的輸入輸出
    gdb attach 1323
    (gdb) call creat("/tmp/myprog.stdout",0600)
    $1 = 7
    (gdb) call dup2(7,1)
    $2 = 1
    (gdb) call creat("/tmp/myprog.stderr",0600)
    $3 = 8
    (gdb) call dup2(8,2)
    $4 = 2 

     ================
    useradd或usermod添加當(dāng)前用戶到某個(gè)group之后,通過id命令發(fā)現(xiàn)自身仍然不在那個(gè)group里,可以用如下命令:newgrp - new_group_name
    =============

    解決`locale -a`發(fā)現(xiàn)en_US.UTF-8缺失的問題:localedef -i en_US -f UTF-8 en_US.UTF-8
    =============

     

    所有man文件里搜索:
    man -wK FIFO
    man -wK --regex 'call.*main'

    posted on 2009-06-13 11:14 so true 閱讀(2097) 評論(0)  編輯  收藏 所屬分類: Linux

    主站蜘蛛池模板: 国产卡一卡二卡三免费入口| 一级视频在线免费观看| 亚洲日本国产精华液| 亚洲欧洲日韩不卡| 亚洲视屏在线观看| 亚洲综合免费视频| 亚洲日韩乱码久久久久久| 久久久久久久亚洲Av无码| 久久亚洲春色中文字幕久久久| 国产亚洲综合网曝门系列| 亚洲国产婷婷六月丁香| 亚洲一区二区三区夜色 | 无码精品一区二区三区免费视频 | 77777亚洲午夜久久多喷| 在线综合亚洲中文精品| 亚洲成年网站在线观看| 亚洲色欲色欲www在线播放 | 久久精品亚洲一区二区| 亚洲高清免费在线观看| 亚洲校园春色另类激情| 亚洲AV无码国产精品永久一区| 国产成人亚洲精品播放器下载| 深夜久久AAAAA级毛片免费看| 五月天婷婷精品免费视频| 韩日电影在线播放免费版| 三年片在线观看免费大全电影 | 成年免费大片黄在线观看岛国| 成全视频在线观看免费高清动漫视频下载 | 高清免费久久午夜精品| 中国一级全黄的免费观看| 95老司机免费福利| 在线精品免费视频无码的| 亚洲一级片免费看| 亚洲综合无码一区二区| 亚洲国产精品99久久久久久| 免费在线观看自拍性爱视频| 久久大香香蕉国产免费网站| 成年女人男人免费视频播放| 亚洲精品97久久中文字幕无码| 久久精品国产亚洲| 亚洲欧美一区二区三区日产|