Linux sed 15個(gè)參數(shù)
|
版權(quán)聲明:原創(chuàng)作品,允許轉(zhuǎn)載,轉(zhuǎn)載時(shí)請(qǐng)務(wù)必以超鏈接形式標(biāo)明文章 原始出處 、作者信息和本聲明。否則將追究法律責(zé)任。http://future.blog.51cto.com/26959/88400
|
|
一、15個(gè)參數(shù)
1、r 從文件讀入
[root@watchout2 ~]# cat file
1 2 3 4 5 [root@watchout2 ~]# cat newfile
a b c d e [root@watchout2 ~]# sed '/a/r file' newfile (讀入文件file,并顯示在newfile文件中匹配行a之后)
a 1 2 3 4 5 b c d e [root@watchout2 ~]# touch /file [root@watchout2 ~]# echo "aaaaaaaaaaaaaaaaaaaaaaaaaa" > /file [root@watchout2 ~]# sed '/a/r /file' newfile (讀入的文件在不同的路徑) a aaaaaaaaaaaaaaaaaaaaaaaaaa b c d e [root@watchout2 ~]# 2、w寫入文件
[root@watchout2 ~]# sed '/a/w bo' newfile
a b c d e [root@watchout2 ~]# cat bo ([root@watchout2 ~]# sed -n '/a/w bobo' newfile ) a 3、a 追加命令
[root@watchout2 ~]# sed '/b/a \bobo' newfile
a b bobo
c d e 4、i 插入
[root@watchout2 ~]# sed '/a/i \bobo' newfile
bobo a b c d e 5、n 下一個(gè)
[root@watchout2 ~]# sed -n '/a/{n;p}' newfile(打印匹配行的下一行)
b [root@watchout2 ~]# sed '/a/{n;s/b/c/p}' newfile
a c c c d e 6、y 變形命令
[root@watchout2 ~]# sed '1,3y/abc/ABC/' newfile
A B C d e y命令就是將小寫轉(zhuǎn)換成了大寫,正則表達(dá)式元字符不能使用這個(gè)命令。
7、q 退出命令
[root@watchout2 ~]# sed '3q' newfile
a b c 打印前三行后退出。
8、h命令 是將pattern space 模式空間(臨時(shí)緩沖區(qū))的內(nèi)容復(fù)制到holding buffer保持緩沖區(qū)
9、G命令 是將holding buffer中的內(nèi)容取得,爾后放回pattern space中,且追加到相應(yīng)行的末 尾
g命令是將holding buffer 中的內(nèi)容取得,爾后放回pattern space 中,且替換相應(yīng)的行
[root@watchout2 ~]# sed -e '/a/h' -e '/d/G' newfile
a b c d a e h命令會(huì)把a(bǔ)匹配行,放入保持緩沖區(qū),G命令會(huì)把保持緩沖區(qū)中的內(nèi)容放入模式空間,并追加到匹配行d的下一行。
[root@watchout2 ~]# sed -e '/a/h' -e '$G' newfile
a b c d e a 與上相同,只是$代表最后一行。
[root@watchout2 ~]# sed -e '/a/h' -e '/b/g' newfile
a a c d e [root@watchout2 ~]# sed -e '/a/h' -e '$g' newfile a b c d a 以上h命令會(huì)把匹配行a,放入保持緩沖區(qū),g命令會(huì)讀取保持緩沖區(qū)的內(nèi)容,將匹配行b(第二個(gè)例子就是$最后一行)替換為a 。注:a將覆蓋匹配行b(第二個(gè)例子就是$最后一行)
10、x命令 是pattern space模式空間將被holding buffer保持緩沖區(qū)中的內(nèi)容替換
[root@watchout2 ~]# sed -e '/a/h' -e '/d/x' newfile
a b c a e 匹配行d 將被匹配行a替換。
11、-n選項(xiàng)取消sed的默認(rèn)行為,sed 默認(rèn)行為是-p ,
root:/tmp>sed '/6/p' num -p參數(shù)打印num的內(nèi)容,爾后匹配“6”在次打印6,所以6會(huì)出現(xiàn)兩次。
1 2 3 4 5 6 6 7 8 root:/tmp>sed -n '/6/p' num -n選項(xiàng)取消sed的默認(rèn)行為(-p ),所以只打印“6” 6 root:/tmp> 12、刪除:d命令
刪除第6行
root:/tmp>sed '6d' num
1 2 3 4 5 7 8 root:/tmp> 從第6行刪除到行尾
root:/tmp>sed '6,$d' num
1 2 3 4 5 root:/tmp> d刪除最后一行
root:/tmp>sed '$d' num
1 2 3 4 5 6 7 root:/tmp> d刪除匹配行
root:/tmp>sed '/6/d' num
1 2 3 4 5 7 8 root:/tmp> 13、替換:s命令
s表示替換,g表示作用范圍整個(gè)行,如果沒有g(shù)標(biāo)志則只有每行第一個(gè)被替換
root:/tmp>sed 's/1/8/g' num (sed默認(rèn)有-p參數(shù)打印搜索后的所有行。如g后面加p,那么匹配行就會(huì)打印兩次)
8 2 3 4 5 6 7 8 root:/tmp> 行首“1”開頭被替換為“8”
root:/tmp>sed 's/^1/8/g' num
8 2 3 4 5 6 7 8 root:/tmp> &符號(hào)表示替換字符串中被找到的部分,所以每個(gè)數(shù)字后面被追加.6789
root:/tmp>sed 's/[0-9]/&.6789/g' num
1.6789 2.6789 3.6789 4.6789 5.6789 6.6789 7.6789 8.6789 root:/tmp> \(..\) 保存匹配的字符到標(biāo)簽\1中。 s/\(5\)/\1.6789/ 藍(lán)色部分保存到標(biāo)簽\1中。從表達(dá)式最左邊開始,向右最多可以使用9個(gè)標(biāo)簽
root:/tmp>sed 's/\(5\)/\1.6789/g' num
1 2 3 4 5.6789 6 7 8 root:/tmp>sed 's/\([0-9]\)/\1.6789/g' num 1.6789 2.6789 3.6789 4.6789 5.6789 6.6789 7.6789 8.6789 root:/tmp> s后面的字符是分隔搜索字符串和替換字符串的分隔符。默認(rèn)分隔符是斜杠,不論什么字符緊跟s命令都被認(rèn)為是新的分隔符
root:/tmp>sed 's#6#shell#g' num
1 2 3 4 5 shell 7 8 root:/tmp> 14、多點(diǎn)編輯:e命令
root:/tmp>sed -e '1,6d' -e 's/8/8.shell/g' num
7 8.shell root:/tmp> 15、-f 引導(dǎo)sed腳本文件名
16、選定行的范圍:逗號(hào)
從第一行到第五行
root:/tmp>sed -n '1,5p' num
1 2 3 4 5 從第一行到第五行,然后在搜索
root:/tmp>sed '1,5s/3/3.linux/g' num 1 2 3.linux 4 5 6 7 8 顯示從第三行到行首為6的中間所有行
root:/tmp>sed -n '3,/^6/p' num 3 4 5 6 root:/tmp> 匹配1和5后面追加“******Total********”
root:/tmp>sed '/1/,/5/s/$/******Total********/g' num
1******Total******** 2******Total******** 3******Total******** 4******Total******** 5******Total******** 6 7 8 root:/tmp> |
| 在 Unix 上寫過程序的人一般都遇到過 Makefile,尤其是用 C 來開發(fā)程序的人。用 make 來開發(fā)和編譯程序的確很方便,可是要寫出一個(gè)MakeFile就不那么簡單了。偏偏介紹 Makefile 的文件不多,GNU Make 那份印出來要幾百頁的文件,光看完 Overview 自己就快要先Over了,難怪許多人聞 Unix色變。本文將介紹如何利用 GNU Autoconf 及 Automake 這兩套軟件來幫助『自動(dòng)』產(chǎn)生 Makefile 文件,并且讓開發(fā)出來的的軟件可以象 Apache, MySQL 和常見的 GNU 軟件一樣,只要會(huì) ``./configure'', ``make'', ``make install'' 就可以把程序安裝到系統(tǒng)中。如果您有心開發(fā) Open Source 的軟件,或只是想在 Unix 系統(tǒng)下寫寫程序。希望這份介紹文件能幫助您輕松的進(jìn)入 Unix Programming 的殿堂。 |
| 1. 簡介 |
| Makefile 基本上就是『目標(biāo)』(target), 『關(guān)聯(lián)』(dependencies) 和『動(dòng)作』三者所組成的一系列規(guī)則。而 make 就會(huì)根據(jù) Makefile 的規(guī)則來決定如何編譯 (compile) 和連接 (link) 程式。實(shí)際上,make 可做的不只是編譯和連接程序,例如 FreeBSD 的 port collection 中,Makefile還可以做到自動(dòng)下載遠(yuǎn)程程序,解壓縮 (extract) , 打補(bǔ)丁 (patch),設(shè)定,然后編譯,安裝到系統(tǒng)中。 |
| Makefile 基本結(jié)構(gòu)雖然很簡單,但是妥善運(yùn)用這些規(guī)則就可以變換出許多不同的花樣。卻也因?yàn)檫@樣,許多剛剛開始學(xué)習(xí)寫Makefile 時(shí)會(huì)覺得沒有規(guī)范可以遵循,每個(gè)人寫出來的Makefile都不大一樣,不知道從哪里下手,而且常常會(huì)受到自己的開發(fā)環(huán)境的限制,只要環(huán)境參數(shù)不同或者路徑更改,可能 Makefile 就得跟著修改修改。雖然有 GNU Makefile Conventions (GNU Makefile慣例例)訂出一些使用 GNU 程式設(shè)計(jì)時(shí)撰寫 Makefile 的一些標(biāo)準(zhǔn)和規(guī)范,但是內(nèi)容很長而且很復(fù)雜,并且經(jīng)常作一些調(diào)整,為了減輕程序開發(fā)人員維護(hù)Makefile 的負(fù)擔(dān),因此出現(xiàn)了Automake。 |
| 程序設(shè)計(jì)者只需要寫一些預(yù)先定義好的宏 (macro),提交給Automake處理后會(huì)產(chǎn)生一個(gè)可以供 Autoconf 使用的 Makefile.in文件。再配合利用 Autoconf產(chǎn)生的自動(dòng)培植設(shè)置文件 configure 即可產(chǎn)生一份符合符合 GNU Makefile 慣例的 Makeifle 了。 |
| 2. 上路之前 |
| 在開始使用 Automake 之前,首先確認(rèn)你的系統(tǒng)安裝有如下軟件: |
| 1. |
| GNU Automake |
| 2. |
| GNU Autoconf |
| 3. |
| GNU m4 |
| 4. |
| perl |
| 5. |
| GNU Libtool (如果你需要產(chǎn)生 shared library) |
| 建議最好也使用 GNU C/C++ 編譯器 、GNU Make 以及其它 GNU 的工具程序來作為開發(fā)的環(huán)境,這些工具都是屬于 Open Source Software 不但免費(fèi)而且功能強(qiáng)大。如果你是使用 Red Hat Linux 可以找到所有上述軟件的 rpm 文件,F(xiàn)reeBSD 也有現(xiàn)成的 package 可以直接安裝,或也可以自行下載這些軟件的源代碼回來安裝。下面的示例是在Red Hat Linux 5.2 + CLE2 的環(huán)境下所完成的。 |
| 3. 一個(gè)簡單的例子 |
| Automake 所產(chǎn)生的 Makefile 除了可以做到程式的編譯和連接,也已經(jīng)把如何產(chǎn)生程序文件 (如 manual page, info 文件及 dvi 文件) 的動(dòng)作,還有把源碼文件包裝起來以供發(fā)布都考慮進(jìn)去了,所以程序源代碼所存放的目錄結(jié)構(gòu)最好符合GNU 的標(biāo)準(zhǔn)慣例,接下來就用一個(gè)hello.c 來做為例子。 |
| 在工作目錄下建立一個(gè)新的子目錄"devel"',再在 devel 下建立一個(gè)"hello"' 的子目錄,這個(gè)目錄將作為存放 hello這個(gè)程序及其相關(guān)文件的地方: |
| % mkdir devel |
| % cd devel |
| % mkdir hello |
| % cd hello |
| 用編輯器寫一個(gè)hello.c文件, |
| #include |
| int main(int argc, char** argv) { |
| printf(``Hello, GNU!\n''); |
| return 0; |
| } |
| 接下來就要用 Autoconf 及 Automake 來產(chǎn)生 Makefile 文件了, |
| 1. |
| 用 autoscan 產(chǎn)生一個(gè) configure.in 的原型,執(zhí)行autoscan 后會(huì)產(chǎn)生一個(gè)configure.scan 的文件,可以用它作為 configure.in文件的藍(lán)本。 |
| % autoscan |
| % ls |
| configure.scan hello.c |
| 2. |
| 編輯 configure.scan文件,如下所示,並且改名為configure.in |
| dnl Process this file with autoconf to produce a configure script. AC_INIT(hello.c) AM_INIT_AUTOMAKE(hello, 1.0) |
| dnl Checks for programs. |
| AC_PROG_CC |
| dnl Checks for libraries. |
| dnl Checks for header files. |
| dnl Checks for typedefs, structures, and compiler characteristics. |
| dnl Checks for library functions. |
| AC_OUTPUT(Makefile) |
| 3. |
| 執(zhí)行 aclocal 和 autoconf ,分別會(huì)產(chǎn)生 aclocal.m4 及 configure 兩個(gè)文件 |
| % aclocal |
| % autoconf |
| % ls |
| aclocal.m4 configure configure.in hello.c |
| 4. |
| 編輯 Makefile.am 文件,內(nèi)容如下 |
| AUTOMAKE_OPTIONS= foreign |
| bin_PROGRAMS= hello |
| hello_SOURCES= hello.c |
| 5. |
| 執(zhí)行 automake --add-missing ,Automake 會(huì)根據(jù)Makefile.am 文件產(chǎn)生一些文件,包含最重要的 Makefile.in |
| % automake --add-missing automake: configure.in: installing `./install-sh' automake: configure.in: installing `./mkinstalldirs' automake: configure.in: installing `./missing' |
| 6. |
| 最后執(zhí)行 ./configure , |
| % ./configure creating cache ./config.cache checking for a BSD compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking whether make sets ${MAKE}... yes checking for working aclocal... found checking for working autoconf... found checking for working automake... found checking for working autoheader... found checking for working makeinfo... found checking for gcc... gcc checking whether the C compiler (gcc ) works... yes checking whether the C compiler (gcc ) is a cross-compiler... no checking whether we are using GNU C... yes checking whether gcc accepts -g... yes updating cache ./config.cache creating ./config.status creating Makefile |
| 現(xiàn)在你的目錄下已經(jīng)產(chǎn)生了一個(gè) Makefile 檔,下個(gè) ``make'' 指令就可以開始編譯 hello.c 成執(zhí)行檔,執(zhí)行 ./hello 和 GNU 打聲招呼吧! |
| % make gcc -DPACKAGE=\"hello\" -DVERSION=\"1.0\" -I. -I. -g -O2 -c hello.c gcc -g -O2 -o hello hello.o % ./hello Hello! GNU! |
| 你還可以試試 ``make clean'',''make install'',''make dist'' 看看會(huì)有什麼結(jié)果。你也可以把產(chǎn)生出來的 Makefile 秀給你的老闆,讓他從此對(duì)你刮目相看 :-) |
| 4. 追根問底 |
| 上述產(chǎn)生Makefile 的過程和以往自行編寫的方式非常不一樣,舍棄傳統(tǒng)自定義make 的規(guī)則,使用 Automake 只需用到一些已經(jīng)定義好的宏就可以了。我們把宏及目標(biāo) (target)寫在Makefile.am 文件內(nèi),Automake 讀入 Makefile.am 文件后會(huì)把這一串已經(jīng)定義好的宏展開并產(chǎn)生相對(duì)應(yīng)的 Makefile.in 文件,然后再由 configure這個(gè) shell script 根據(jù) Makefile.in 產(chǎn)生合適的Makefile。 |
|
|
|
利用 autoconf 及 automake產(chǎn)生Makefile 的流程 |
| 上圖表示在上一范例中要使用的文件檔案及產(chǎn)生出來的文件,有星號(hào) (*) 者代表可執(zhí)行文件。在此示例中可由 Autoconf 及 Automake 工具所產(chǎn)生的額外文件有 configure.scan、aclocal.m4、configure、Makefile.in,需要自行加入設(shè)置的有configure.in 及 Makefile.am。 |
| 4.1 編輯 configure.in 文件 |
| Autoconf 是用來產(chǎn)生 'configure'文件的工具。'configure' 是一個(gè) shell script,它可以自動(dòng)設(shè)定原始程序以符合各種不同平臺(tái)上Unix 系統(tǒng)的特性,并且根據(jù)系統(tǒng)參數(shù)及環(huán)境產(chǎn)生合適的Makefile文件或C 的頭文件(header file),讓原始程式可以很方便地在不同的平臺(tái)上進(jìn)行編譯。Autoconf會(huì)讀取 configure.in 文件然后產(chǎn)生'configure' 這個(gè) shell script。 |
| configure.in 文件內(nèi)容是一系列GNU m4 的宏,這些宏經(jīng)autoconf處理后會(huì)變成檢查系統(tǒng)特性的shell scripts。 configure.in 內(nèi)宏的順序并沒有特別的規(guī)定,但是每一個(gè)configure.in 文件必須在所有宏前加入 AC_INIT 宏,然后在所有宏的最后加上 AC_OUTPUT宏。可先用 autoscan 掃描原始文件以產(chǎn)生一個(gè) configure.scan 文件,再對(duì) configure.scan 做些修改成 configure.in 文件。在范例中所用到的宏如下: |
| dnl |
| 這個(gè)宏后面的字不會(huì)被處理,可以視為注釋 |
| AC_INIT(FILE) |
| 該宏用來檢查源代碼所在路徑,autoscan 會(huì)自動(dòng)產(chǎn)生,一般無須修改它。 |
| AM_INIT_AUTOMAKE(PACKAGE,VERSION) |
| 這個(gè)是使用 Automake 所必備的宏,PACKAGE 是所要產(chǎn)生軟件套件的名稱,VERSION 是版本編號(hào)。 |
| AC_PROG_CC |
| 檢查系統(tǒng)可用的C編譯器,若源代碼是用C寫的就需要這個(gè)宏。 |
| AC_OUTPUT(FILE) |
| 設(shè)置 configure 所要產(chǎn)生的文件,若是Makefile ,configure 便會(huì)把它檢查出來的結(jié)果帶入 Makefile.in 文件后產(chǎn)生合適的 Makefile。 |
| 實(shí)際上,這里使用 Automake 時(shí),還需要一些其他的宏,這些額外的宏我們用 aclocal來幫助產(chǎn)生。執(zhí)行 aclocal會(huì)產(chǎn)生aclocal.m4 文件,如果無特別的用途,可以不需要修改它,用 aclocal 所產(chǎn)生的宏會(huì)告訴 Automake如何動(dòng)作。 |
| 有了 configure.in 及 aclocal.m4兩個(gè)文件以后,便可以執(zhí)行 autoconf來產(chǎn)生 configure 文件了。 |
| 4.2 編輯Makefile.am 文件 |
| 接下來要編輯Makefile.am 文件,Automake 會(huì)根據(jù) configure.in 中的宏把Makefile.am 轉(zhuǎn)成 Makefile.in 文件。 Makefile.am 文件定義所要產(chǎn)生的目標(biāo): |
| AUTOMAKE_OPTIONS |
| 設(shè)置 automake 的選項(xiàng)。Automake 主要是幫助開發(fā) GNU 軟件的人員來維護(hù)軟件,所以在執(zhí)行 automake 時(shí),會(huì)檢查目錄下是否存在標(biāo)準(zhǔn) GNU 軟件中應(yīng)具備的文件,例如 'NEWS'、'AUTHOR'、'ChangeLog' 等文件。設(shè)置 foreign 時(shí),automake 會(huì)改用一般軟件的標(biāo)準(zhǔn)來檢查。 |
| bin_PROGRAMS |
| 定義要產(chǎn)生的執(zhí)行文件名。如果要產(chǎn)生多個(gè)執(zhí)行文件,每個(gè)文件名用空白符隔開。 |
| hello_SOURCES |
| 定義 'hello' 這個(gè)執(zhí)行程序所需要的原始文件。如果 'hello'這個(gè)程序是由多個(gè)原始文件所產(chǎn)生,必須把它所用到的所有原始文件都列出來,以空白符隔開。假設(shè) 'hello' 還需要 'hello.c'、'main.c'、'hello.h' 三個(gè)文件的話,則定義 |
| hello_SOURCES= hello.c main.c hello.h |
| 如果定義多個(gè)執(zhí)行文件,則對(duì)每個(gè)執(zhí)行程序都要定義相對(duì)的filename_SOURCES。 |
| 編輯好 Makefile.am 文件,就可以用 automake --add-missing來產(chǎn)生 Makefile.in。加上 --add-missing 選項(xiàng)來告訴 automake順便假如包裝一個(gè)軟件所必須的文件。Automake產(chǎn)生生出來的 Makefile.in 文件是完全符合 GNU Makefile 的慣例,只要執(zhí)行 configure這個(gè)shell script 便可以產(chǎn)生合適的 Makefile 文件了。 |
| 4.3 使用 Makefile |
| 利用 configure 所產(chǎn)生的 Makefile文件有幾個(gè)預(yù)先設(shè)定的目標(biāo)可供使用,這里只用幾個(gè)簡述如下: |
| make all |
| 產(chǎn)生設(shè)定的目標(biāo),既次范例中的執(zhí)行文件。只敲入make 也可以,此時(shí)會(huì)開始編譯源代碼,然后連接并產(chǎn)生執(zhí)行文件。 |
| make clean |
| 清除之前所編譯的執(zhí)行文件及目標(biāo)文件(object file, *.o)。 |
| make distclean |
| 除了清除執(zhí)行文件和目的文件以外,也把 configure 所產(chǎn)生的 Makefile 清除掉。 |
| make install |
| 將程序安裝到系統(tǒng)中,若源碼編譯成功,且執(zhí)行結(jié)果正確,便可以把程序安裝到系統(tǒng)預(yù)先設(shè)定的執(zhí)行文件存放路徑中,若用 bin_PROGRAMS 宏的話,程序會(huì)被安裝到 /usr/local/bin下。 |
| make dist |
| 將程序和相關(guān)的文檔包裝為一個(gè)壓縮文檔以供發(fā)布 (distribution) 。執(zhí)行完在目錄下會(huì)產(chǎn)生一個(gè)以PACKAGE-VERSION.tar.gz 為名稱的文件。PACKAGE 和 VERSION 這兩個(gè)參數(shù)是根據(jù) configure.in 文件中 AM_INIT_AUTOMAKE(PACKAGE, VERSION) 的定義。在此范例中會(huì)產(chǎn)生 'hello-1.0.tar.gz' 的文件。 |
| make distcheck |
| 和 make dist 類似,但是加入檢查包裝以后的壓縮文件是否正常,這個(gè)目標(biāo)除了把程序和相關(guān)文檔包裝成 tar.gz 文件外,還會(huì)自動(dòng)把這個(gè)壓縮文件解開,執(zhí)行 configure,并執(zhí)行 make all ,確認(rèn)編譯無錯(cuò)誤以后,戶顯示這個(gè) tar.gz 文件已經(jīng)準(zhǔn)備好可以發(fā)布了。這個(gè)檢查非常有用,檢查過關(guān)的套件,基本上可以給任何具備 GNU 開發(fā)環(huán)境的人去重新編譯成功。就 hello-1.tar.gz 這個(gè)范例而言,除了在Red Hat Linux 上,在 FreeBSD 2.2.x 也可以正確編譯。 |
| 要注意的是,利用 Autoconf 及 Automake 所產(chǎn)生出來的軟件套件是可以在沒有安裝 Autoconf 及 Automake 的環(huán)境使用的,因?yàn)?configure 是一個(gè) shell script,它己被設(shè)計(jì)為可以在一般 Unix 的 sh 這個(gè) shell 下執(zhí)行。但是如果要修改 configure.in 及 Makefile.am 文件再產(chǎn)生新的 configure 及 Makefile.in 文件時(shí)就一定要有 Autoconf 及 Automake 了。 |
| 5. 相關(guān)資料 |
| Autoconf 和 Automake 功能十分強(qiáng)大,可以從它們附帶的 info 穩(wěn)當(dāng)4中找到詳細(xì)的使用方法說明。你也可以從許多現(xiàn)有的GNU 軟件或 Open Source 軟件中找到相關(guān)的 configure.in 或 Makefile.am 文件,他們是學(xué)習(xí) Autoconf 及 Automake 更多技巧的最佳范例。 |
| 這個(gè)簡介只用到了 Autoconf 及 Automake 的皮毛罷了,如果你有心加入 Open Source 軟件開發(fā)的行列,希望這篇文章可以幫助你對(duì)產(chǎn)生 Makefile 有個(gè)簡單的了解。其它有關(guān)開發(fā) GNU 程式或 C 程序設(shè)計(jì)及 Makefile 的詳細(xì)運(yùn)用及技巧,建議從 GNU Coding Standards (GNU 編碼規(guī)定) 讀起,里面包含了 GNU Makefile 慣例,及開發(fā) GNU 軟件的標(biāo)準(zhǔn)程序和慣例。這些 GNU 軟件的在線說明文件可以在 http://www.gnu.org/ 上找到。 |
| 6. 結(jié)束語 |
| 利用 Autoconf 及 Automake,產(chǎn)生一個(gè) Makefile 似乎不再象以前那么困難了,而使用 Autoconf 也使得我們?cè)诓煌脚_(tái)上或各家 Unix 之間發(fā)布及便宜程序變的簡單,這對(duì)于在Unix 系統(tǒng)上程序開發(fā)員來說減輕了許多負(fù)擔(dān)。妥善運(yùn)用這些 GNU 的工具軟件,可以幫助我們更容易的去開發(fā)程序,而且更容易維護(hù)源代碼。 |
+-------------------------+----> 高地址
| EIP (上級(jí)函數(shù)返回地址) |
+-------------------------+
+--> | EBP (上級(jí)函數(shù)的EBP) | --+ <------當(dāng)前函數(shù)A的EBP (即SFP框架指針)
| +-------------------------+ +-->偏移量A
| | Local Variables | |
| | .......... | --+ <------ESP指向函數(shù)A新分配的局部變量,局部變量可以通過A的ebp-偏移量A訪問
| f +-------------------------+
| r | Arg n(函數(shù)B的第n個(gè)參數(shù)) |
| a +-------------------------+
| m | Arg .(函數(shù)B的第.個(gè)參數(shù)) |
| e +-------------------------+
| | Arg 1(函數(shù)B的第1個(gè)參數(shù)) |
| o +-------------------------+
| f | Arg 0(函數(shù)B的第0個(gè)參數(shù)) | --+ <------ B函數(shù)的參數(shù)可以由B的ebp+偏移量B訪問
| +-------------------------+ +--> 偏移量B
| A | EIP (A函數(shù)的返回地址) | |
| +-------------------------+ --+
+--- | EBP (A函數(shù)的EBP) |<--+ <------ 當(dāng)前函數(shù)B的EBP (即SFP框架指針)
+-------------------------+ |
| Local Variables | |
| .......... | | <------ ESP指向函數(shù)B新分配的局部變量
+-------------------------+ |
| Arg n(函數(shù)C的第n個(gè)參數(shù)) | |
+-------------------------+ |
| Arg .(函數(shù)C的第.個(gè)參數(shù)) | |
+-------------------------+ +--> frame of B
| Arg 1(函數(shù)C的第1個(gè)參數(shù)) | |
+-------------------------+ |
| Arg 0(函數(shù)C的第0個(gè)參數(shù)) | |
+-------------------------+ |
| EIP (B函數(shù)的返回地址) | |
+-------------------------+ |
+--> | EBP (B函數(shù)的EBP) | --+ <------ 當(dāng)前函數(shù)C的EBP (即SFP框架指針)
| +-------------------------+
| | Local Variables |
| | .......... | <------ ESP指向函數(shù)C新分配的局部變量
| +-------------------------+----> 低地址
frame of C
圖 1-1
sudo fdisk -l
df -T -h
mount
lspci
lsusb
sudo hdparm -d1 /dev/cdrom sudo cp /etc/hdparm.conf /etc/hdparm.conf_backup sudo gedit /etc/hdparm.conf
/dev/cdrom {
dma = on
}
sudo mount /media/cdrom0/ -o unhide
sudo umount /media/cdrom0/
sudo umount /media/cdrom0/ -l
sudo mount -a
sudo umount /dev/cdrom cdrecord dev=/dev/cdrom blank=fast
nautilus burn:///
檔案選單 -> 燒錄光盤... -> 燒錄
點(diǎn)選影像檔(ISO)右鍵 -> 燒錄光盤... -> 燒錄
sudo umount /dev/cdrom dd if=/dev/cdrom of=file.iso bs=1024
mkisofs -o file.iso /location_of_folder/
md5sum file.iso > file.iso.md5
md5sum -c file.iso.md5
sudo mkdir /media/iso sudo modprobe loop sudo mount file.iso /media/iso/ -t iso9660 -o loop
sudo umount /media/iso/
/ -> apps -> nautilus-cd-burner -> default_speed (設(shè)定/改變 燒錄速度)
/ -> apps -> nautilus-cd-burner -> burnproof (勾選)
/ -> apps -> nautilus-cd-burner -> overburn (勾選)
連線 -> 選擇 "以太網(wǎng)連線" -> 啟動(dòng)/停止使用
連線 -> 選擇 "以太網(wǎng)連線" -> 屬性 連線 -> 啟動(dòng)這個(gè)連線 (勾選) 連線設(shè)定 -> 組態(tài): 選擇 "DHCP/固定 IP 位址"
DNS -> DNS 服務(wù)器 -> 新增/刪除
sudo pppconfig
sudo pon provider_name
sudo poff
sudo pppoeconf
一般 -> 主機(jī)設(shè)定 -> 主機(jī)名稱: 指定計(jì)算機(jī)名稱
sudo cp /etc/samba/smb.conf /etc/samba/smb.conf_backup sudo gedit /etc/samba/smb.conf
... server string = %h server (Samba, Ubuntu) ...
server string = new_computer_descriptions
sudo testparm sudo /etc/init.d/samba restart
sudo cp /etc/samba/smb.conf /etc/samba/smb.conf_backup sudo gedit /etc/samba/smb.conf
... workgroup = MSHOME ...
workgroup = new_domain_or_workgroup
sudo testparm sudo /etc/init.d/samba restart
sudo apt-get install ipcheck sudo gedit /root/dyndns_update.sh
USERNAME=myusername PASSWORD=mypassword HOSTNAME=myhostname.dyndns.org
cd /root/ if [ -f /root/ipcheck.dat ]; then ipcheck -r checkip.dyndns.org:8245 $USERNAME $PASSWORD $HOSTNAME else ipcheck --makedat -r checkip.dyndns.org:8245 $USERNAME $PASSWORD $HOSTNAME fi
sudo chmod 700 /root/dyndns_update.sh sudo sh /root/dyndns_update.sh export EDITOR=gedit && sudo crontab -e
00 * * * * sudo sh /root/dyndns_update.sh
資料夾上按右鍵 -> 共享資料夾
共享資料夾 -> 共享為: 選擇 "SMB" 共享內(nèi)容 -> 名稱: 指定共享名稱
smb://192.168.0.1/linux
sudo mkdir /media/sharename sudo mount //192.168.0.1/linux /media/sharename/ -o username=myusername,password=mypassword
sudo umount /media/sharename/
sudo mkdir /media/sharename sudo mount //192.168.0.1/linux /media/sharename/ -o username=myusername,password=mypassword,dmask=777,fmask=777
sudo umount /media/sharename/
sudo mkdir /media/sharename sudo gedit /root/.smbcredentials
username=myusername password=mypassword
sudo chmod 700 /root/.smbcredentials sudo cp /etc/fstab /etc/fstab_backup sudo gedit /etc/fstab
//192.168.0.1/linux /media/sharename smbfs credentials=/root/.smbcredentials 0 0
sudo mkdir /media/sharename sudo gedit /root/.smbcredentials
username=myusername password=mypassword
sudo chmod 700 /root/.smbcredentials sudo cp /etc/fstab /etc/fstab_backup sudo gedit /etc/fstab
//192.168.0.1/linux /media/sharename smbfs credentials=/root/.smbcredentials,dmask=777,fmask=777 0 0
共享 -> 允許其他使用者觀看您的桌面 (勾選) 允許其他使用者控制您的桌面 (勾選)
安全性 -> 詢問您已確認(rèn) (不勾選) 使用者需要輸入密碼: (勾選) 密碼: 指定密碼
vncviewer -fullscreen 192.168.0.1:0
Press 'F8' -> Quit viewer
sudo mkdir /media/windows sudo mount /dev/hda1 /media/windows/ -t ntfs -o nls=utf8,umask=0222
sudo umount /media/windows/
sudo mkdir /media/windows sudo mount /dev/hda1 /media/windows/ -t vfat -o iocharset=utf8,umask=000
sudo umount /media/windows/
sudo mkdir /media/windows sudo cp /etc/fstab /etc/fstab_backup sudo gedit /etc/fstab
/dev/hda1 /media/windows ntfs nls=utf8,umask=0222 0 0
sudo mkdir /media/windows sudo cp /etc/fstab /etc/fstab_backup sudo gedit /etc/fstab
/dev/hda1 /media/windows vfat iocharset=utf8,umask=000 0 0
|
http://www.yuanma.org/data/2007/0406/article_2498.htm
gcc和g++的區(qū)別 我們?cè)诰幾gc/c++代碼的時(shí)候,有人用gcc,有人用g++,于是各種說法都來了,譬如c代碼用gcc,而c++代碼用g++,或者說編譯用 gcc,鏈接用g++,一時(shí)也不知哪個(gè)說法正確,如果再遇上個(gè)extern "C",分歧就更多了,這里我想作個(gè)了結(jié),畢竟知識(shí)的目的是令人更清醒,而不是更糊涂。
誤區(qū)一:gcc只能編譯c代碼,g++只能編譯c++代碼
兩者都可以,但是請(qǐng)注意: 1.后綴為.c的,gcc把它當(dāng)作是C程序,而g++當(dāng)作是c++程序;后綴為.cpp的,兩者都會(huì)認(rèn)為是c++程序,注意,雖然c++是c的超集,但是兩者對(duì)語法的要求是有區(qū)別的,例如:
#include <stdio.h>
int main(int argc, char* argv[]) {
if(argv == 0) return; printString(argv);
return;
} int printString(char* string) { sprintf(string, "This is a test.\n"); } 如果按照C的語法規(guī)則,OK,沒問題,但是,一旦把后綴改為cpp,立刻報(bào)三個(gè)錯(cuò):“printString未定義”;
“cannot convert `char**' to `char*”;
”return-statement with no value“;
分別對(duì)應(yīng)前面紅色標(biāo)注的部分。可見C++的語法規(guī)則更加嚴(yán)謹(jǐn)一些。
2.編譯階段,g++會(huì)調(diào)用gcc,對(duì)于c++代碼,兩者是等價(jià)的,但是因?yàn)間cc命令不能自動(dòng)和C++程序使用的庫聯(lián)接,所以通常用g++來完成鏈接,為了統(tǒng)一起見,干脆編譯/鏈接統(tǒng)統(tǒng)用g++了,這就給人一種錯(cuò)覺,好像cpp程序只能用g++似的。
誤區(qū)二:gcc不會(huì)定義__cplusplus宏,而g++會(huì)
實(shí)際上,這個(gè)宏只是標(biāo)志著編譯器將會(huì)把代碼按C還是C++語法來解釋,如上所述,如果后綴為.c,并且采用gcc編譯器,則該宏就是未定義的,否則,就是已定義。 誤區(qū)三:編譯只能用gcc,鏈接只能用g++
嚴(yán)格來說,這句話不算錯(cuò)誤,但是它混淆了概念,應(yīng)該這樣說:編譯可以用gcc/g++,而鏈接可以用g++或者gcc -lstdc++。因?yàn)間cc命令不能自動(dòng)和C++程序使用的庫聯(lián)接,所以通常使用g++來完成聯(lián)接。但在編譯階段,g++會(huì)自動(dòng)調(diào)用gcc,二者等價(jià)。 誤區(qū)四:extern "C"與gcc/g++有關(guān)系
實(shí)際上并無關(guān)系,無論是gcc還是g++,用extern "c"時(shí),都是以C的命名方式來為symbol命名,否則,都以c++方式命名。試驗(yàn)如下: me.h: extern "C" void CppPrintf(void); me.cpp:
#include <iostream> #include "me.h" using namespace std; void CppPrintf(void) { cout << "Hello\n"; } test.cpp:
#include <stdlib.h> #include <stdio.h> #include "me.h" int main(void) { CppPrintf(); return 0; } 1. 先給me.h加上extern "C",看用gcc和g++命名有什么不同
[root@root G++]# g++ -S me.cpp [root@root G++]# less me.s .globl _Z9CppPrintfv //注意此函數(shù)的命名 .type CppPrintf, @function [root@root GCC]# gcc -S me.cpp
[root@root GCC]# less me.s .globl _Z9CppPrintfv //注意此函數(shù)的命名 .type CppPrintf, @function 完全相同! 2. 去掉me.h中extern "C",看用gcc和g++命名有什么不同 [root@root GCC]# gcc -S me.cpp [root@root GCC]# less me.s .globl _Z9CppPrintfv //注意此函數(shù)的命名 .type _Z9CppPrintfv, @function [root@root G++]# g++ -S me.cpp
[root@root G++]# less me.s .globl _Z9CppPrintfv //注意此函數(shù)的命名 .type _Z9CppPrintfv, @function 完全相同! 【結(jié)論】完全相同,可見extern "C"與采用gcc/g++并無關(guān)系,以上的試驗(yàn)還間接的印證了前面的說法:在編譯階段,g++是調(diào)用gcc的。
|
|
http://blog.csdn.net/blade2001/archive/2007/06/10/1646530.aspx
gcc and g++分別是gnu的c & c++編譯器 gcc/g++在執(zhí)行編譯工作的時(shí)候,總共需要4步 1.預(yù)處理,生成.i的文件[預(yù)處理器cpp] 2.將預(yù)處理后的文件不轉(zhuǎn)換成匯編語言,生成文件.s[編譯器egcs] 3.有匯編變?yōu)槟繕?biāo)代碼(機(jī)器代碼)生成.o的文件[匯編器as] 4.連接目標(biāo)代碼,生成可執(zhí)行程序[鏈接器ld] [參數(shù)詳解] -x language filename 設(shè)定文件所使用的語言,使后綴名無效,對(duì)以后的多個(gè)有效.也就是根據(jù)約定C語言的后 綴名稱是.c的,而C++的后綴名是.C或者.cpp,如果你很個(gè)性,決定你的C代碼文件的后綴 名是.pig 哈哈,那你就要用這個(gè)參數(shù),這個(gè)參數(shù)對(duì)他后面的文件名都起作用,除非到了 下一個(gè)參數(shù)的使用。 可以使用的參數(shù)嗎有下面的這些 `c', `objective-c', `c-header', `c++', `cpp-output', `assembler', and `a ssembler-with-cpp'. 看到英文,應(yīng)該可以理解的。 例子用法: gcc -x c hello.pig -x none filename 關(guān)掉上一個(gè)選項(xiàng),也就是讓gcc根據(jù)文件名后綴,自動(dòng)識(shí)別文件類型 例子用法: gcc -x c hello.pig -x none hello2.c -c 只激活預(yù)處理,編譯,和匯編,也就是他只把程序做成obj文件 例子用法: gcc -c hello.c 他將生成.o的obj文件 -S 只激活預(yù)處理和編譯,就是指把文件編譯成為匯編代碼。 例子用法 gcc -S hello.c 他將生成.s的匯編代碼,你可以用文本編輯器察看 -E 只激活預(yù)處理,這個(gè)不生成文件,你需要把它重定向到一個(gè)輸出文件里面. 例子用法: gcc -E hello.c > pianoapan.txt gcc -E hello.c | more 慢慢看吧,一個(gè)hello word 也要與處理成800行的代碼 -o 制定目標(biāo)名稱,缺省的時(shí)候,gcc 編譯出來的文件是a.out,很難聽,如果你和我有同感 ,改掉它,哈哈 例子用法 gcc -o hello.exe hello.c (哦,windows用習(xí)慣了) gcc -o hello.asm -S hello.c -pipe 使用管道代替編譯中臨時(shí)文件,在使用非gnu匯編工具的時(shí)候,可能有些問題 gcc -pipe -o hello.exe hello.c -ansi 關(guān)閉gnu c中與ansi c不兼容的特性,激活ansi c的專有特性(包括禁止一些asm inl ine typeof關(guān)鍵字,以及UNIX,vax等預(yù)處理宏, -fno-asm 此選項(xiàng)實(shí)現(xiàn)ansi選項(xiàng)的功能的一部分,它禁止將asm,inline和typeof用作關(guān)鍵字。 -fno-strict-prototype 只對(duì)g++起作用,使用這個(gè)選項(xiàng),g++將對(duì)不帶參數(shù)的函數(shù),都認(rèn)為是沒有顯式的對(duì)參數(shù) 的個(gè)數(shù)和類型說明,而不是沒有參數(shù). 而gcc無論是否使用這個(gè)參數(shù),都將對(duì)沒有帶參數(shù)的函數(shù),認(rèn)為城沒有顯式說明的類型 -fthis-is-varialble 就是向傳統(tǒng)c++看齊,可以使用this當(dāng)一般變量使用. -fcond-mismatch 允許條件表達(dá)式的第二和第三參數(shù)類型不匹配,表達(dá)式的值將為void類型 -funsigned-char -fno-signed-char -fsigned-char -fno-unsigned-char 這四個(gè)參數(shù)是對(duì)char類型進(jìn)行設(shè)置,決定將char類型設(shè)置成unsigned char(前兩個(gè)參 數(shù))或者 signed char(后兩個(gè)參數(shù)) -include file 包含某個(gè)代碼,簡單來說,就是便以某個(gè)文件,需要另一個(gè)文件的時(shí)候,就可以用它設(shè) 定,功能就相當(dāng)于在代碼中使用#i nclude<filename> 例子用法: gcc hello.c -include /root/pianopan.h -imacros file 將file文件的宏,擴(kuò)展到gcc/g++的輸入文件,宏定義本身并不出現(xiàn)在輸入文件中 -Dmacro 相當(dāng)于C語言中的#define macro -Dmacro=defn 相當(dāng)于C語言中的#define macro=defn -Umacro 相當(dāng)于C語言中的#undef macro -undef 取消對(duì)任何非標(biāo)準(zhǔn)宏的定義 -Idir 在你是用#i nclude"file"的時(shí)候,gcc/g++會(huì)先在當(dāng)前目錄查找你所制定的頭文件,如 果沒有找到,他回到缺省的頭文件目錄找,如果使用-I制定了目錄,他 回先在你所制定的目錄查找,然后再按常規(guī)的順序去找. 對(duì)于#i nclude<file>,gcc/g++會(huì)到-I制定的目錄查找,查找不到,然后將到系統(tǒng)的缺 省的頭文件目錄查找 -I- 就是取消前一個(gè)參數(shù)的功能,所以一般在-Idir之后使用 -idirafter dir 在-I的目錄里面查找失敗,講到這個(gè)目錄里面查找. -iprefix prefix -iwithprefix dir 一般一起使用,當(dāng)-I的目錄查找失敗,會(huì)到prefix+dir下查找 -nostdinc 使編譯器不再系統(tǒng)缺省的頭文件目錄里面找頭文件,一般和-I聯(lián)合使用,明確限定頭 文件的位置 -nostdin C++ 規(guī)定不在g++指定的標(biāo)準(zhǔn)路經(jīng)中搜索,但仍在其他路徑中搜索,.此選項(xiàng)在創(chuàng)libg++庫 使用 -C 在預(yù)處理的時(shí)候,不刪除注釋信息,一般和-E使用,有時(shí)候分析程序,用這個(gè)很方便的 -M 生成文件關(guān)聯(lián)的信息。包含目標(biāo)文件所依賴的所有源代碼你可以用gcc -M hello.c 來測(cè)試一下,很簡單。 -MM 和上面的那個(gè)一樣,但是它將忽略由#i nclude<file>造成的依賴關(guān)系。 -MD 和-M相同,但是輸出將導(dǎo)入到.d的文件里面 -MMD 和-MM相同,但是輸出將導(dǎo)入到.d的文件里面 -Wa,option 此選項(xiàng)傳遞option給匯編程序;如果option中間有逗號(hào),就將option分成多個(gè)選項(xiàng),然 后傳遞給會(huì)匯編程序 -Wl.option 此選項(xiàng)傳遞option給連接程序;如果option中間有逗號(hào),就將option分成多個(gè)選項(xiàng),然 后傳遞給會(huì)連接程序. -llibrary 制定編譯的時(shí)候使用的庫 例子用法 gcc -lcurses hello.c 使用ncurses庫編譯程序 -Ldir 制定編譯的時(shí)候,搜索庫的路徑。比如你自己的庫,可以用它制定目錄,不然 編譯器將只在標(biāo)準(zhǔn)庫的目錄找。這個(gè)dir就是目錄的名稱。 -O0 -O1 -O2 -O3 編譯器的優(yōu)化選項(xiàng)的4個(gè)級(jí)別,-O0表示沒有優(yōu)化,-O1為缺省值,-O3優(yōu)化級(jí)別最高 -g 只是編譯器,在編譯的時(shí)候,產(chǎn)生調(diào)試信息。 -gstabs 此選項(xiàng)以stabs格式聲稱調(diào)試信息,但是不包括gdb調(diào)試信息. -gstabs+ 此選項(xiàng)以stabs格式聲稱調(diào)試信息,并且包含僅供gdb使用的額外調(diào)試信息. -ggdb 此選項(xiàng)將盡可能的生成gdb的可以使用的調(diào)試信息. -static 此選項(xiàng)將禁止使用動(dòng)態(tài)庫,所以,編譯出來的東西,一般都很大,也不需要什么 動(dòng)態(tài)連接庫,就可以運(yùn)行. -share 此選項(xiàng)將盡量使用動(dòng)態(tài)庫,所以生成文件比較小,但是需要系統(tǒng)由動(dòng)態(tài)庫. -traditional 試圖讓編譯器支持傳統(tǒng)的C語言特性 |