@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ù)意義可以看gdb的mannual
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
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'