99久久99这里只有免费费精品,日本精品久久久中文字幕,女人香蕉久久**毛片精品http://www.shnenglu.com/liu1061/category/7273.html生活和工作都要充滿激情,否則你無法體會到淋漓盡致的快樂與痛苦zh-cnSat, 19 Sep 2009 11:33:52 GMTSat, 19 Sep 2009 11:33:52 GMT60learn sed 參數http://www.shnenglu.com/liu1061/articles/95101.htmlT.S LiuT.S LiuWed, 02 Sep 2009 07:14:00 GMThttp://www.shnenglu.com/liu1061/articles/95101.htmlhttp://www.shnenglu.com/liu1061/comments/95101.htmlhttp://www.shnenglu.com/liu1061/articles/95101.html#Feedback0http://www.shnenglu.com/liu1061/comments/commentRss/95101.htmlhttp://www.shnenglu.com/liu1061/services/trackbacks/95101.html Linux sed 15個參數
2008-07-17 23:00:57
版權聲明:原創作品,允許轉載,轉載時請務必以超鏈接形式標明文章 原始出處 、作者信息和本聲明。否則將追究法律責任。http://future.blog.51cto.com/26959/88400
一、15個參數
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 下一個
[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命令就是將小寫轉換成了大寫,正則表達式元字符不能使用這個命令。
 
7、q 退出命令
[root@watchout2 ~]# sed '3q' newfile
a
b
c
打印前三行后退出。
 
8、h命令   是將pattern space 模式空間(臨時緩沖區)的內容復制到holding buffer保持緩沖區
9、G命令 是將holding buffer中的內容取得,爾后放回pattern space中,且追加到相應行的末 尾 
    g命令是將holding buffer 中的內容取得,爾后放回pattern space 中,且替換相應的行
 
[root@watchout2 ~]# sed -e '/a/h' -e '/d/G' newfile
a
b
c
d
a
e
h命令會把a匹配行,放入保持緩沖區,G命令會把保持緩沖區中的內容放入模式空間,并追加到匹配行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命令會把匹配行a,放入保持緩沖區,g命令會讀取保持緩沖區的內容,將匹配行b(第二個例子就是$最后一行)替換為a 。注:a將覆蓋匹配行b(第二個例子就是$最后一行)
 
10、x命令 是pattern space模式空間將被holding buffer保持緩沖區中的內容替換
[root@watchout2 ~]# sed -e '/a/h' -e '/d/x' newfile
a
b
c
a
e
匹配行d 將被匹配行a替換。
 
11、-n選項取消sed的默認行為,sed 默認行為是-p ,
root:/tmp>sed '/6/p' num   -p參數打印num的內容,爾后匹配“6”在次打印6,所以6會出現兩次。
1
2
3
4
5
6
6
7
8
root:/tmp>sed -n '/6/p' num  -n選項取消sed的默認行為(-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標志則只有每行第一個被替換
root:/tmp>sed 's/1/8/g' num    (sed默認有-p參數打印搜索后的所有行。如g后面加p,那么匹配行就會打印兩次)
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>
 
&符號表示替換字符串中被找到的部分,所以每個數字后面被追加.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>
 
\(..\) 保存匹配的字符到標簽\1中。  s/\(5\)/\1.6789/  藍色部分保存到標簽\1中。從表達式最左邊開始,向右最多可以使用9個標簽
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后面的字符是分隔搜索字符串和替換字符串的分隔符。默認分隔符是斜杠,不論什么字符緊跟s命令都被認為是新的分隔符
root:/tmp>sed 's#6#shell#g' num
1
2
3
4
5
shell
7
8
root:/tmp>
 
14、多點編輯:e命令
root:/tmp>sed -e '1,6d' -e 's/8/8.shell/g' num
7
8.shell
root:/tmp>
 
15、-f  引導sed腳本文件名
 
 
16、選定行的范圍:逗號
 
從第一行到第五行
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>


T.S Liu 2009-09-02 15:14 發表評論
]]>
linux學習入門指令!http://www.shnenglu.com/liu1061/articles/54897.htmlT.S LiuT.S LiuSun, 29 Jun 2008 02:14:00 GMThttp://www.shnenglu.com/liu1061/articles/54897.htmlhttp://www.shnenglu.com/liu1061/comments/54897.htmlhttp://www.shnenglu.com/liu1061/articles/54897.html#Feedback0http://www.shnenglu.com/liu1061/comments/commentRss/54897.htmlhttp://www.shnenglu.com/liu1061/services/trackbacks/54897.htmllinux目錄架構
/   根目錄
/bin    常用的命令 binary file 的目錄
/boot   存放系統啟動時必須讀取的檔案,包括核心 (kernel) 在內
/boot/grub/menu.lst   GRUB設置
/boot/vmlinuz   內核
/boot/initrd     核心解壓縮所需 RAM Disk
/dev    系統周邊設備     
/etc    系統相關設定文件
/etc/DIR_COLORS   設定顏色
/etc/HOSTNAME   設定用戶的節點名
/etc/NETWORKING   只有YES標明網絡存在
/etc/host.conf 文件說明用戶的系統如何查詢節點名
/etc/hosts 設定用戶自已的IP與名字的對應表
/etc/hosts.allow 設置允許使用inetd的機器使用 
/etc/hosts.deny 設置不允許使用inetd的機器使用
/etc/hosts.equiv 設置遠端機不用密碼
/etc/inetd.conf 設定系統網絡守護進程inetd的配置
/etc/gateways 設定路由器
/etc/protocols 設定系統支持的協議
/etc/named.boot 設定本機為名字服務器的配置文件
/etc/sysconfig/network-scripts/ifcfg-eth0   設置IP
/etc/resolv.conf    設置DNS 
/etc/X11  X Window的配置文件,xorg.conf 或 XF86Config 這兩個 X Server 的設定檔
/etc/fstab    記錄開機要mount的文件系統
/etc/inittab 設定系統啟動時init進程將把系統設置成什么樣的runlevel
/etc/issue 記錄用戶登錄前顯示的信息
/etc/group 設定用戶的組名與相關信息
/etc/passwd 帳號信息
/etc/shadow 密碼信息
/etc/sudoers 可以sudo命令的配置文件
/etc/securetty 設定哪些終端可以讓root登錄
/etc/login.defs 所有用戶登錄時的缺省配置
/etc/exports 設定NFS系統用的
/etc/init.d/   所有服務的預設啟動 script 都是放在這裡的,例如要啟動或者關閉
/etc/xinetd.d/  這就是所謂的 super daemon 管理的各項服務的設定檔目錄
/etc/modprobe.conf   內核模塊額外參數設定
/etc/syslog.conf   日志設置文件
/home   使用者家目錄
/lib    系統會使用到的函數庫
/lib/modules   kernel 的相關模塊
/var/lib/rpm   rpm套件安裝處
/lost+found    系統不正常產生錯誤時,會將一些遺失的片段放置於此目錄下
/mnt     外設的掛載點
/media   與/mnt類似
/opt     主機額外安裝的軟件
/proc    虛擬目錄,是內存的映射
/proc/version   內核版本
/proc/sys/kernel   系統內核功能
/root    系統管理員的家目錄
/sbin    系統管理員才能執行的指令
/srv     一些服務啟動之後,這些服務所需要取用的資料目錄
/tmp     一般使用者或者是正在執行的程序暫時放置檔案的地方
/usr     最大的目錄,存許應用程序和文件
/usr/X11R6:   X-Window目錄
/usr/src:    Linux源代碼
/usr/include:系統頭文件
/usr/openwin 存放SUN的OpenWin
/usr/man 在線使用手冊
/usr/bin           使用者可執行的 binary file 的目錄
/usr/local/bin     使用者可執行的 binary file 的目錄
/usr/lib           系統會使用到的函數庫
/usr/local/lib     系統會使用到的函數庫
/usr/sbin          系統管理員才能執行的指令
/usr/local/sbin    系統管理員才能執行的指令
/var   日志文件
/var/log/secure    記錄登入系統存取資料的檔案,例如 pop3, ssh, telnet, ftp 等都會記錄檔案中
/var/log/wtmp      記錄登入者的訊息資料, last
/var/log/messages  幾乎系統發生的錯誤訊息
/var/log/boot.log  記錄開機或者是一些服務啟動的時候,所顯示的啟動或關閉訊息
/var/log/maillog   紀錄郵件存取或往來( sendmail 與 pop3 )的使用者記錄
/var/log/cron      記錄 crontab 這個例行性服務的內容
/var/log/httpd, /var/log/news, /var/log/mysqld.log, /var/log/samba, /var/log/procmail.log:
分別是幾個不同的網路服務的記錄檔
一些常用的基本命令:
uname -a    查看內核版本      
ls -al    顯示所有文件的屬性
pwd         顯示當前路徑        
cd -    返回上一次目錄     cd ~    返回主目錄
date s      設置時間、日期         
cal      顯示日歷     cal 2006
bc          計算器具               
man  & info     幫助手冊
locale     顯示當前字體     locale -a    所有可用字體     /etc/sysconfig/i18n設置文件
LANG=en    使用英文字體            
sync       將數據同步寫入硬盤        
shutdonw -h now & half & poweroff  關機
reboot     重啟                  
startx  &  init 5   進入圖形介面
/work  & ?work    向上、下查找文檔內容
chgrp      改變檔案群組  chgrp testing install.log   
chown     改變所屬人   chown root:root install.log
chmod      改變屬性     chmod 777 install.log     read=4  write=2  execute=1
cp   復制   cp filename
rm   刪除文件  rm -rf filename   強制刪除文件
rmdir   刪除文件夾
mv  移動    mv 123.txt 222.txt  重命名
mkdir     創建文件夾
touch     創建文件  更新當前時間
cat       由第一行開始顯示     cat |more  分頁
nl        在內容前加行號
more  &  less   一面一面翻動
head -n filename   顯示第N行內容
tail -n filename  顯示后N行內容
od        顯示非純文檔
df -h 顯示分區空間
du  顯示目錄或文件的大小
fdisk   分區設置    fdisk -l /dev/hda  顯示硬盤分區狀態
mkfs    建立各種文件系統  mkfs -t ext3  /dev/ram15   
fsck    檢查和修復LINUX檔案
ln      硬鏈接   ln -s  軟件鏈接
whereis   查找命令
locate    查找
find      查找   find / -name "***.***"
which     查看工具
whoami    顯示當前用戶
gcc -v    查看GCC版本
chattr +i filename  禁止刪除   chattr -i filename  取消禁止
lsattr    顯示隱藏檔屬性
updatedb  更新資料庫
mke2fs    格式化   mkfs -t ext3
dd if=/etc/passwd of=/tmp/passwd.bak    備份
mount     列出系統所有的分區
mount -t iso9660 /dev/cdrom /mnt/cdrom   掛載光盤
mount -t vfat /dev/fd0 /mnt/floppy       掛載軟盤
mount -t vfat -o iocharset=utf8,umask=000 /dev/hda2 /mnt/hda2   掛載fat32分區
mount -t ntfs -o nls=utf8,umask=000 /dev/hda3 /mnt/hda3         掛載ntfs分區
Linux-NTFS Project:
http://linux-ntfs.sourceforge.net/
umount /mnt/hda3  缷載
ifconfig   顯示或設置網絡設備
service network restart   重啟網卡  
ifdown eth0  關閉網卡
ifup eth0    開啟網卡
clear    清屏
history    歷史記錄       !55  執行第55個指令
stty   設置終端    stty -a
fdisk /mbr   刪除GRUB
at     僅進行一次的工作排程
crontab   循環執行的例行性命令    [e]編輯,[l]顯示,[r]刪除任務
&       后臺運行程序    tar -zxvf 123.tar.gz & --------->后臺運行
jobs    觀看后臺暫停的程序   jobs -l
fg      將后臺程序調到前臺   fg n ------>n是數字,可以指定進行那個程序
bg      讓工作在后臺運行
kill    結束進程    kill -9 PID     [9]強制結束,[15]正常結束,[l]列出可用的kill信號
ps aux  查看后臺程序   
top     查看后臺程序   top -d 2    每兩秒更新一次        top -d 2 -p10604   觀看某個PID
        top -b -n 2 > /tmp/top.txt ----->將 top 的資訊進行 2 次,然後將結果輸出到 /tmp/top.txt   
pstree   以樹狀圖顯示程序    [A]以 ASCII 來連接, 列出PID, [p]列出帳號
killall   要刪除某個服務    killall -9 httpd
free      顯示內存狀態     free -m  -------->以M為單位顯示
uptime    顯示目前系統開機時間
netstat   顯示網絡狀態    netstat -tulnp------>找出目前系統上已在監聽的網路連線及其 PID
dmesg     顯示開機信息    demsg | more
nice      設置優先權      nice -n -5 vi & ----->用 root 給一個 nice 植為 -5 ,用於執行 vi
renice    調整已存在優先權
runlevel  顯示目前的runlevel
depmod    分析可載入模塊的相依性
lsmod     顯示已載入系統的模塊
modinfo   顯示kernel模塊的信息
insmod    載入模塊
modprobe   自動處理可載入模塊
rmmod     刪除模塊
chkconfig   檢查,設置系統的各種服務     chkconfig --list ----->列出各項服務狀態
ntsysv     設置系統的各種服務
cpio      備份文件

壓縮命令:
*.Z      compress 程式壓縮的檔案;
*.bz2    bzip2 程式壓縮的檔案;
*.gz     gzip 程式壓縮的檔案;
*.tar    tar 程式打包的資料,並沒有壓縮過;
*.tar.gz tar 程式打包的檔案,其中並且經過 gzip 的壓縮
compress filename  壓縮文件  加[-d]解壓  uncompress
gzip filename   壓縮  加[-d]解壓  zcat 123.gz 查看壓縮文件內容
bzip2 -z filename  壓縮  加[-d]解壓   bzcat filename.bz2  查看壓縮文件內容
tar -cvf /home/123.tar /etc  打包,不壓縮
tar -xvf 123.tar   解開包
tar -zxvf /home/123.tar.gz  以gzip解壓
tar -jxvf /home/123.tar.bz2  以bzip2解壓
tar -ztvf /tmp/etc.tar.gz   查看tar內容
cpio -covB  > [file|device]   份份
cpio -icduv
帳號管理
/etc/passwd    系統帳號信息
/etc/shadow    帳號密碼信息    經MD5 32位加密
     在密碼欄前面加『 * 』『 ! 』禁止使用某帳號
/etc/group     系統群組信息
/etc/gshadow
newgrp    改變登陸組
useradd  &  adduser    建立新用戶  ---------> useradd -m test  自動建立用戶的登入目錄
          useradd -m -g pgroup test --------->指定所屬級
/etc/default/useradd   相關設定
/etc/login.defs       UID/GID 有關的設定
passwd    更改密碼 -----------> passwd test
usermod   修改用戶帳號
userdel   刪除帳號 ----------->userdel -r test
chsh      更換登陸系統時使用的SHELL   [-l]顯示可用的SHELL;[-s]修改自己的SHELL
chfn      改變finger指令顯示的信息
finger    查找并顯示用戶信息
id        顯示用戶的ID ----------->  id test
groupadd   添加組
groupmod   與usermod類似
groupdel   刪除組
su test    更改用戶   su -    進入root,且使用root的環境變量
sudo       以其他身份來執行指令
visudo     編輯/etc/sudoers      加入一行『 test ALL=(ALL) ALL 』
           %wheel ALL = (ALL) ALL               系統里所有wheel群組的用戶都可用sudo
           %wheel ALL = (ALL) NOPASSWD: ALL     wheel群組所有用戶都不用密碼NOPASSWD
       User_Alias ADMPW = vbird, dmtsai, vbird1, vbird3         加入ADMPW組
       ADMPW ALL = NOPASSWD: !/usr/bin/passwd, /usr/bin/passwd [A-Za-z]*, \
       !/usr/bin/passwd root      可以更改使用者密碼,但不能更改root密碼 (在指令前面加入 ! 代表不可)
PAM (Pluggable Authentication Modules, 嵌入式模組)
who & w     看誰在線                     
last        最近登陸主機的信息
lastlog     最近登入的時間    讀取 /var/log/lastlog
talk        與其他用戶交談
write       發送信息    write test   [ctrl]+d 發送
mesg        設置終端機的寫入權限    mesg n 禁止接收     mesg y
wall        向所有用戶發送信息    wall this is q test
mail        寫mail   
/etc/default/useradd    家目錄默認設置
quota      顯示磁盤已使用的空間與限制     quota -guvs ----->秀出目前 root 自己的 quota 限制值
           quota -vu   查詢
quotacheck   檢查磁盤的使用空間與限制     quotacheck -avug  ----->將所有的在 /etc/mtab 內,含有 quota 支援的 partition 進行掃瞄
             [-m] 強制掃描  
     quota一定要是獨立的分區,要有quota.user和quota.group兩件文件,在/etc/fstab添加一句:
     /dev/hda3 /home ext3 defaults,usrquota,grpquota 1 2
     chmod 600 quota*         設置完成,重啟生效
edquota    編輯用戶或群組的quota  用戶,[g]群組,[p]復制,[t]設置寬限期限
           edquota -a yang       edquota -p yang -u young ----->復制   
quotaon    開啟磁盤空間限制     quotaon -auvg -------->啟動所有的具有 quota 的 filesystem
quotaoff   關閉磁盤空間限制     quotaoff -a  -------->關閉了 quota 的限制
repquota -av     查閱系統內所有的具有 quota 的 filesystem 的限值狀態
Quota 從開始準備 filesystem 的支援到整個設定結束的主要的步驟大概是:
1、設定 partition 的 filesystem 支援 quota 參數:
由於 quota 必須要讓 partition 上面的 filesystem 支援才行,一般來說, 支援度最好的是 ext2/ext3 ,
其他的 filesystem 類型鳥哥我是沒有試過啦! 啟動 filesystem 支援 quota 最簡單就是編輯 /etc/fstab ,
使得準備要開放的 quota 磁碟可以支援 quota 囉;
2、建立 quota 記錄檔:
剛剛前面講過,整個 quota 進行磁碟限制值記錄的檔案是 aquota.user/aquota.group,
要建立這兩個檔案就必須要先利用 quotacheck 掃瞄才行喔!
3、編輯 quota 限制值資料:
再來就是使用 edquota 來編輯每個使用者或群組的可使用空間囉;
4、重新掃瞄與啟動 quota :
設定好 quota 之後,建議可以再進行一次 quotacheck ,然後再以 quotaon 來啟動吧!
開機流程簡介
1、載入 BIOS 的硬體資訊,並取得第一個開機裝置的代號;
2、讀取第一個開機裝置的 MBR 的 boot Loader (亦即是 lilo, grub, spfdisk 等等) 的開機資訊;
3、載入 Kernel 作業系統核心資訊, Kernel 開始解壓縮,並且嘗試驅動所有硬體裝置;
4、Kernel 執行 init 程式並取得 run-level 資訊;
5、init 執行 /etc/rc.d/rc.sysinit 檔案;
6、啟動核心的外掛模組 (/etc/modprobe.conf);
7、init 執行 run-level 的各個批次檔( Scripts );
8、init 執行 /etc/rc.d/rc.local 檔案;
9、執行 /bin/login 程式,並等待使用者登入;
10、登入之後開始以 Shell 控管主機。
在/etc/rc.d/rc3.d內,以S開頭的為開機啟動,以K開頭的為關閉,接著的數字代表執行順序
GRUB vga設定
彩度\解析度  640x480  800x600  1024x768  1280x1024   bit
    256        769      771      773       775      8 bit
   32768       784      787      790       793     15 bit
   65536       785      788      791       794     16 bit
   16.8M       786      789      792       795     32 bit
./configure    檢查系統信息       ./configure --help | more  幫助信息
make clean     清除之前留下的文件
make           編譯
make install   安裝
rpm -q  ----->查詢是否安裝             rpm -ql ------>查詢該套件所有的目錄
rpm -qi ----->查詢套件的說明資料       rpm -qc[d] ----->設定檔與說明檔
rpm -ivh  ---->安裝                    rpm -V  -------->查看套件有否更動過
rpm -e  ------>刪除                    rpm -Uvh ------->升級安裝  
--nodeps ----->強行安裝                --test ----->測試安裝


T.S Liu 2008-06-29 10:14 發表評論
]]>
使用AutoMake輕松生成Makefile(轉)http://www.shnenglu.com/liu1061/articles/54540.htmlT.S LiuT.S LiuWed, 25 Jun 2008 03:18:00 GMThttp://www.shnenglu.com/liu1061/articles/54540.htmlhttp://www.shnenglu.com/liu1061/comments/54540.htmlhttp://www.shnenglu.com/liu1061/articles/54540.html#Feedback0http://www.shnenglu.com/liu1061/comments/commentRss/54540.htmlhttp://www.shnenglu.com/liu1061/services/trackbacks/54540.html 摘要:
在 Unix 上寫過程序的人一般都遇到過 Makefile,尤其是用 C 來開發程序的人。用 make 來開發和編譯程序的確很方便,可是要寫出一個MakeFile就不那么簡單了。偏偏介紹 Makefile 的文件不多,GNU Make 那份印出來要幾百頁的文件,光看完 Overview 自己就快要先Over了,難怪許多人聞 Unix色變。本文將介紹如何利用 GNU Autoconf 及 Automake 這兩套軟件來幫助『自動』產生 Makefile 文件,并且讓開發出來的的軟件可以象 Apache, MySQL 和常見的 GNU 軟件一樣,只要會 ``./configure'', ``make'', ``make install'' 就可以把程序安裝到系統中。如果您有心開發 Open Source 的軟件,或只是想在 Unix 系統下寫寫程序。希望這份介紹文件能幫助您輕松的進入 Unix Programming 的殿堂。
1. 簡介
Makefile 基本上就是『目標』(target), 『關聯』(dependencies) 和『動作』三者所組成的一系列規則。而 make 就會根據 Makefile 的規則來決定如何編譯 (compile) 和連接 (link) 程式。實際上,make 可做的不只是編譯和連接程序,例如 FreeBSD 的 port collection 中,Makefile還可以做到自動下載遠程程序,解壓縮 (extract) , 打補丁 (patch),設定,然后編譯,安裝到系統中。
Makefile 基本結構雖然很簡單,但是妥善運用這些規則就可以變換出許多不同的花樣。卻也因為這樣,許多剛剛開始學習寫Makefile 時會覺得沒有規范可以遵循,每個人寫出來的Makefile都不大一樣,不知道從哪里下手,而且常常會受到自己的開發環境的限制,只要環境參數不同或者路徑更改,可能 Makefile 就得跟著修改修改。雖然有 GNU Makefile Conventions (GNU Makefile慣例例)訂出一些使用 GNU 程式設計時撰寫 Makefile 的一些標準和規范,但是內容很長而且很復雜,并且經常作一些調整,為了減輕程序開發人員維護Makefile 的負擔,因此出現了Automake。
程序設計者只需要寫一些預先定義好的宏 (macro),提交給Automake處理后會產生一個可以供 Autoconf 使用的 Makefile.in文件。再配合利用 Autoconf產生的自動培植設置文件 configure 即可產生一份符合符合 GNU Makefile 慣例的 Makeifle 了。
2. 上路之前
在開始使用 Automake 之前,首先確認你的系統安裝有如下軟件:
 
1.
GNU Automake
2.
GNU Autoconf
3.
GNU m4
4.
perl
5.
GNU Libtool (如果你需要產生 shared library)
建議最好也使用 GNU C/C++ 編譯器 、GNU Make 以及其它 GNU 的工具程序來作為開發的環境,這些工具都是屬于 Open Source Software 不但免費而且功能強大。如果你是使用 Red Hat Linux 可以找到所有上述軟件的 rpm 文件,FreeBSD 也有現成的 package 可以直接安裝,或也可以自行下載這些軟件的源代碼回來安裝。下面的示例是在Red Hat Linux 5.2 + CLE2 的環境下所完成的。
3. 一個簡單的例子
Automake 所產生的 Makefile 除了可以做到程式的編譯和連接,也已經把如何產生程序文件 (如 manual page, info 文件及 dvi 文件) 的動作,還有把源碼文件包裝起來以供發布都考慮進去了,所以程序源代碼所存放的目錄結構最好符合GNU 的標準慣例,接下來就用一個hello.c 來做為例子。
在工作目錄下建立一個新的子目錄"devel"',再在 devel 下建立一個"hello"' 的子目錄,這個目錄將作為存放 hello這個程序及其相關文件的地方:
% mkdir devel
% cd devel
% mkdir hello
% cd hello
用編輯器寫一個hello.c文件,
#include
int main(int argc, char** argv) {
printf(``Hello, GNU!\n'');
return 0;
}
接下來就要用 Autoconf 及 Automake 來產生 Makefile 文件了,
1.
用 autoscan 產生一個 configure.in 的原型,執行autoscan 后會產生一個configure.scan 的文件,可以用它作為 configure.in文件的藍本。
 
% 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.
執行 aclocal 和 autoconf ,分別會產生 aclocal.m4 及 configure 兩個文件
% aclocal
% autoconf
% ls
aclocal.m4 configure configure.in hello.c
4.
編輯 Makefile.am 文件,內容如下
AUTOMAKE_OPTIONS= foreign
bin_PROGRAMS= hello
hello_SOURCES= hello.c
5.
執行 automake --add-missing ,Automake 會根據Makefile.am 文件產生一些文件,包含最重要的 Makefile.in
% automake --add-missing automake: configure.in: installing `./install-sh' automake: configure.in: installing `./mkinstalldirs' automake: configure.in: installing `./missing'
6.
最后執行 ./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
現在你的目錄下已經產生了一個 Makefile 檔,下個 ``make'' 指令就可以開始編譯 hello.c 成執行檔,執行 ./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'' 看看會有什麼結果。你也可以把產生出來的 Makefile 秀給你的老闆,讓他從此對你刮目相看 :-)
4. 追根問底
上述產生Makefile 的過程和以往自行編寫的方式非常不一樣,舍棄傳統自定義make 的規則,使用 Automake 只需用到一些已經定義好的宏就可以了。我們把宏及目標 (target)寫在Makefile.am 文件內,Automake 讀入 Makefile.am 文件后會把這一串已經定義好的宏展開并產生相對應的 Makefile.in 文件,然后再由 configure這個 shell script 根據 Makefile.in 產生合適的Makefile。

利用 autoconf 及 automake產生Makefile 的流程

上圖表示在上一范例中要使用的文件檔案及產生出來的文件,有星號 (*) 者代表可執行文件。在此示例中可由 Autoconf 及 Automake 工具所產生的額外文件有 configure.scan、aclocal.m4、configure、Makefile.in,需要自行加入設置的有configure.in 及 Makefile.am。
4.1 編輯 configure.in 文件
Autoconf 是用來產生 'configure'文件的工具。'configure' 是一個 shell script,它可以自動設定原始程序以符合各種不同平臺上Unix 系統的特性,并且根據系統參數及環境產生合適的Makefile文件或C 的頭文件(header file),讓原始程式可以很方便地在不同的平臺上進行編譯。Autoconf會讀取 configure.in 文件然后產生'configure' 這個 shell script。
configure.in 文件內容是一系列GNU m4 的宏,這些宏經autoconf處理后會變成檢查系統特性的shell scripts。 configure.in 內宏的順序并沒有特別的規定,但是每一個configure.in 文件必須在所有宏前加入 AC_INIT 宏,然后在所有宏的最后加上 AC_OUTPUT宏。可先用 autoscan 掃描原始文件以產生一個 configure.scan 文件,再對 configure.scan 做些修改成 configure.in 文件。在范例中所用到的宏如下:
dnl
這個宏后面的字不會被處理,可以視為注釋
AC_INIT(FILE)
該宏用來檢查源代碼所在路徑,autoscan 會自動產生,一般無須修改它。
AM_INIT_AUTOMAKE(PACKAGE,VERSION)
這個是使用 Automake 所必備的宏,PACKAGE 是所要產生軟件套件的名稱,VERSION 是版本編號。
AC_PROG_CC
檢查系統可用的C編譯器,若源代碼是用C寫的就需要這個宏。
AC_OUTPUT(FILE)
設置 configure 所要產生的文件,若是Makefile ,configure 便會把它檢查出來的結果帶入 Makefile.in 文件后產生合適的 Makefile。
實際上,這里使用 Automake 時,還需要一些其他的宏,這些額外的宏我們用 aclocal來幫助產生。執行 aclocal會產生aclocal.m4 文件,如果無特別的用途,可以不需要修改它,用 aclocal 所產生的宏會告訴 Automake如何動作。
有了 configure.in 及 aclocal.m4兩個文件以后,便可以執行 autoconf來產生 configure 文件了。
4.2 編輯Makefile.am 文件
接下來要編輯Makefile.am 文件,Automake 會根據 configure.in 中的宏把Makefile.am 轉成 Makefile.in 文件。 Makefile.am 文件定義所要產生的目標:
AUTOMAKE_OPTIONS
設置 automake 的選項。Automake 主要是幫助開發 GNU 軟件的人員來維護軟件,所以在執行 automake 時,會檢查目錄下是否存在標準 GNU 軟件中應具備的文件,例如 'NEWS'、'AUTHOR'、'ChangeLog' 等文件。設置 foreign 時,automake 會改用一般軟件的標準來檢查。
bin_PROGRAMS
定義要產生的執行文件名。如果要產生多個執行文件,每個文件名用空白符隔開。
hello_SOURCES
定義 'hello' 這個執行程序所需要的原始文件。如果 'hello'這個程序是由多個原始文件所產生,必須把它所用到的所有原始文件都列出來,以空白符隔開。假設 'hello' 還需要 'hello.c'、'main.c'、'hello.h' 三個文件的話,則定義
hello_SOURCES= hello.c main.c hello.h
如果定義多個執行文件,則對每個執行程序都要定義相對的filename_SOURCES。
編輯好 Makefile.am 文件,就可以用 automake --add-missing來產生 Makefile.in。加上 --add-missing 選項來告訴 automake順便假如包裝一個軟件所必須的文件。Automake產生生出來的 Makefile.in 文件是完全符合 GNU Makefile 的慣例,只要執行 configure這個shell script 便可以產生合適的 Makefile 文件了。
4.3 使用 Makefile
利用 configure 所產生的 Makefile文件有幾個預先設定的目標可供使用,這里只用幾個簡述如下:
make all
產生設定的目標,既次范例中的執行文件。只敲入make 也可以,此時會開始編譯源代碼,然后連接并產生執行文件。
make clean
清除之前所編譯的執行文件及目標文件(object file, *.o)。
make distclean
除了清除執行文件和目的文件以外,也把 configure 所產生的 Makefile 清除掉。
make install
將程序安裝到系統中,若源碼編譯成功,且執行結果正確,便可以把程序安裝到系統預先設定的執行文件存放路徑中,若用 bin_PROGRAMS 宏的話,程序會被安裝到 /usr/local/bin下。
make dist
將程序和相關的文檔包裝為一個壓縮文檔以供發布 (distribution) 。執行完在目錄下會產生一個以PACKAGE-VERSION.tar.gz 為名稱的文件。PACKAGE 和 VERSION 這兩個參數是根據 configure.in 文件中 AM_INIT_AUTOMAKE(PACKAGE, VERSION) 的定義。在此范例中會產生 'hello-1.0.tar.gz' 的文件。
make distcheck
和 make dist 類似,但是加入檢查包裝以后的壓縮文件是否正常,這個目標除了把程序和相關文檔包裝成 tar.gz 文件外,還會自動把這個壓縮文件解開,執行 configure,并執行 make all ,確認編譯無錯誤以后,戶顯示這個 tar.gz 文件已經準備好可以發布了。這個檢查非常有用,檢查過關的套件,基本上可以給任何具備 GNU 開發環境的人去重新編譯成功。就 hello-1.tar.gz 這個范例而言,除了在Red Hat Linux 上,在 FreeBSD 2.2.x 也可以正確編譯。
要注意的是,利用 Autoconf 及 Automake 所產生出來的軟件套件是可以在沒有安裝 Autoconf 及 Automake 的環境使用的,因為 configure 是一個 shell script,它己被設計為可以在一般 Unix 的 sh 這個 shell 下執行。但是如果要修改 configure.in 及 Makefile.am 文件再產生新的 configure 及 Makefile.in 文件時就一定要有 Autoconf 及 Automake 了。
5. 相關資料
Autoconf 和 Automake 功能十分強大,可以從它們附帶的 info 穩當4中找到詳細的使用方法說明。你也可以從許多現有的GNU 軟件或 Open Source 軟件中找到相關的 configure.in 或 Makefile.am 文件,他們是學習 Autoconf 及 Automake 更多技巧的最佳范例。
這個簡介只用到了 Autoconf 及 Automake 的皮毛罷了,如果你有心加入 Open Source 軟件開發的行列,希望這篇文章可以幫助你對產生 Makefile 有個簡單的了解。其它有關開發 GNU 程式或 C 程序設計及 Makefile 的詳細運用及技巧,建議從 GNU Coding Standards (GNU 編碼規定) 讀起,里面包含了 GNU Makefile 慣例,及開發 GNU 軟件的標準程序和慣例。這些 GNU 軟件的在線說明文件可以在 http://www.gnu.org/ 上找到。
6. 結束語
利用 Autoconf 及 Automake,產生一個 Makefile 似乎不再象以前那么困難了,而使用 Autoconf 也使得我們在不同平臺上或各家 Unix 之間發布及便宜程序變的簡單,這對于在Unix 系統上程序開發員來說減輕了許多負擔。妥善運用這些 GNU 的工具軟件,可以幫助我們更容易的去開發程序,而且更容易維護源代碼。


T.S Liu 2008-06-25 11:18 發表評論
]]>
vim參考手冊!http://www.shnenglu.com/liu1061/articles/54535.htmlT.S LiuT.S LiuWed, 25 Jun 2008 01:57:00 GMThttp://www.shnenglu.com/liu1061/articles/54535.htmlhttp://www.shnenglu.com/liu1061/comments/54535.htmlhttp://www.shnenglu.com/liu1061/articles/54535.html#Feedback0http://www.shnenglu.com/liu1061/comments/commentRss/54535.htmlhttp://www.shnenglu.com/liu1061/services/trackbacks/54535.htmlvim參考手冊

T.S Liu 2008-06-25 09:57 發表評論
]]>
Linux平臺可以用gdb進行反匯編和調試。http://www.shnenglu.com/liu1061/articles/53762.htmlT.S LiuT.S LiuTue, 17 Jun 2008 13:16:00 GMThttp://www.shnenglu.com/liu1061/articles/53762.htmlhttp://www.shnenglu.com/liu1061/comments/53762.htmlhttp://www.shnenglu.com/liu1061/articles/53762.html#Feedback0http://www.shnenglu.com/liu1061/comments/commentRss/53762.htmlhttp://www.shnenglu.com/liu1061/services/trackbacks/53762.html
2. 最簡C代碼分析

    為簡化問題,來分析一下最簡的c代碼生成的匯編代碼:
    # vi test1.c
     
    int main()
    {
        return 0;
    }  
   
    編譯該程序,產生二進制文件:
    # gcc test1.c -o test1
    # file test1  
    test1: ELF 32-bit LSB executable 80386 Version 1, dynamically linked, not stripped

    test1是一個ELF格式32位小端(Little Endian)的可執行文件,動態鏈接并且符號表沒有去除。
    這正是Unix/Linux平臺典型的可執行文件格式。
    用mdb反匯編可以觀察生成的匯編代碼:

    # mdb test1
    Loading modules: [ libc.so.1 ]
    > main::dis                       ; 反匯編main函數,mdb的命令一般格式為  <地址>::dis
    main:          pushl   %ebp       ; ebp寄存器內容壓棧,即保存main函數的上級調用函數的棧基地址
    main+1:        movl    %esp,%ebp  ; esp值賦給ebp,設置main函數的棧基址
    main+3:          subl    $8,%esp
    main+6:          andl    $0xf0,%esp
    main+9:          movl    $0,%eax
    main+0xe:        subl    %eax,%esp
    main+0x10:     movl    $0,%eax    ; 設置函數返回值0
    main+0x15:     leave              ; 將ebp值賦給esp,pop先前棧內的上級函數棧的基地址給ebp,恢復原棧基址
    main+0x16:     ret                ; main函數返回,回到上級調用
    >

    注:這里得到的匯編語言語法格式與Intel的手冊有很大不同,Unix/Linux采用AT&T匯編格式作為匯編語言的語法格式
         如果想了解AT&T匯編可以參考文章:Linux AT&T 匯編語言開發指南

    問題:誰調用了 main函數?
    
     在C語言的層面來看,main函數是一個程序的起始入口點,而實際上,ELF可執行文件的入口點并不是main而是_start。
     mdb也可以反匯編_start:
      
    > _start::dis                       ;從_start 的地址開始反匯編
    _start:              pushl   $0
    _start+2:            pushl   $0
    _start+4:            movl    %esp,%ebp
    _start+6:            pushl   %edx
    _start+7:            movl    $0x80504b0,%eax
    _start+0xc:          testl   %eax,%eax
    _start+0xe:          je      +0xf            <_start+0x1d>
    _start+0x10:         pushl   $0x80504b0
    _start+0x15:         call    -0x75           <atexit>
    _start+0x1a:         addl    $4,%esp
    _start+0x1d:         movl    $0x8060710,%eax
    _start+0x22:         testl   %eax,%eax
    _start+0x24:         je      +7              <_start+0x2b>
    _start+0x26:         call    -0x86           <atexit>
    _start+0x2b:         pushl   $0x80506cd
    _start+0x30:         call    -0x90           <atexit>
    _start+0x35:         movl    +8(%ebp),%eax
    _start+0x38:         leal    +0x10(%ebp,%eax,4),%edx
    _start+0x3c:         movl    %edx,0x8060804
    _start+0x42:         andl    $0xf0,%esp
    _start+0x45:         subl    $4,%esp
    _start+0x48:         pushl   %edx
    _start+0x49:         leal    +0xc(%ebp),%edx
    _start+0x4c:         pushl   %edx
    _start+0x4d:         pushl   %eax
    _start+0x4e:         call    +0x152          <_init>
    _start+0x53:         call    -0xa3           <__fpstart>
    _start+0x58:        call    +0xfb        <main>              ;在這里調用了main函數
    _start+0x5d:         addl    $0xc,%esp
    _start+0x60:         pushl   %eax
    _start+0x61:         call    -0xa1           <exit>
    _start+0x66:         pushl   $0
    _start+0x68:         movl    $1,%eax
    _start+0x6d:         lcall   $7,$0
    _start+0x74:         hlt
    >

    問題:為什么用EAX寄存器保存函數返回值?
    實際上IA32并沒有規定用哪個寄存器來保存返回值。但如果反匯編Solaris/Linux的二進制文件,就會發現,都用EAX保存函數返回值。
    這不是偶然現象,是操作系統的ABI(Application Binary Interface)來決定的。
    Solaris/Linux操作系統的ABI就是Sytem V ABI。


    概念:SFP (Stack Frame Pointer) 棧框架指針 

    正確理解SFP必須了解:
        IA32 的棧的概念
        CPU 中32位寄存器ESP/EBP的作用
        PUSH/POP 指令是如何影響棧的
        CALL/RET/LEAVE 等指令是如何影響棧的

    如我們所知:
    1)IA32的棧是用來存放臨時數據,而且是LIFO,即后進先出的。棧的增長方向是從高地址向低地址增長,按字節為單位編址。
    2) EBP是棧基址的指針,永遠指向棧底(高地址),ESP是棧指針,永遠指向棧頂(低地址)。
    3) PUSH一個long型數據時,以字節為單位將數據壓入棧,從高到低按字節依次將數據存入ESP-1、ESP-2、ESP-3、ESP-4的地址單元。
    4) POP一個long型數據,過程與PUSH相反,依次將ESP-4、ESP-3、ESP-2、ESP-1從棧內彈出,放入一個32位寄存器。
    5) CALL指令用來調用一個函數或過程,此時,下一條指令地址會被壓入堆棧,以備返回時能恢復執行下條指令。
    6) RET指令用來從一個函數或過程返回,之前CALL保存的下條指令地址會從棧內彈出到EIP寄存器中,程序轉到CALL之前下條指令處執行
    7) ENTER是建立當前函數的棧框架,即相當于以下兩條指令:
        pushl   %ebp
        movl    %esp,%ebp
    8) LEAVE是釋放當前函數或者過程的棧框架,即相當于以下兩條指令:
        movl ebp esp
        popl  ebp

    如果反匯編一個函數,很多時候會在函數進入和返回處,發現有類似如下形式的匯編語句:
       
        pushl   %ebp            ; ebp寄存器內容壓棧,即保存main函數的上級調用函數的棧基地址
        movl    %esp,%ebp       ; esp值賦給ebp,設置 main函數的棧基址
        ...........             ; 以上兩條指令相當于 enter 0,0
        ...........
        leave                   ; 將ebp值賦給esp,pop先前棧內的上級函數棧的基地址給ebp,恢復原棧基址
        ret                     ; main函數返回,回到上級調用

    這些語句就是用來創建和釋放一個函數或者過程的棧框架的。
    原來編譯器會自動在函數入口和出口處插入創建和釋放棧框架的語句。
    函數被調用時:
    1) EIP/EBP成為新函數棧的邊界
    函數被調用時,返回時的EIP首先被壓入堆棧;創建棧框架時,上級函數棧的EBP被壓入堆棧,與EIP一道行成新函數棧框架的邊界
    2) EBP成為棧框架指針SFP,用來指示新函數棧的邊界
    棧框架建立后,EBP指向的棧的內容就是上一級函數棧的EBP,可以想象,通過EBP就可以把層層調用函數的棧都回朔遍歷一遍,調試器就是利用這個特性實現 backtrace功能的
    3) ESP總是作為棧指針指向棧頂,用來分配棧空間
    棧分配空間給函數局部變量時的語句通常就是給ESP減去一個常數值,例如,分配一個整型數據就是 ESP-4
    4) 函數的參數傳遞和局部變量訪問可以通過SFP即EBP來實現
    由于棧框架指針永遠指向當前函數的棧基地址,參數和局部變量訪問通常為如下形式:
        +8+xx(%ebp)         ; 函數入口參數的的訪問
        -xx(%ebp)           ; 函數局部變量訪問
           
    假如函數A調用函數B,函數B調用函數C ,則函數棧框架及調用關系如下圖所示:
   	+-------------------------+----> 高地址
| EIP (上級函數返回地址) |
+-------------------------+
+--> | EBP (上級函數的EBP) | --+ <------當前函數A的EBP (即SFP框架指針)
| +-------------------------+ +-->偏移量A
| | Local Variables | |
| | .......... | --+ <------ESP指向函數A新分配的局部變量,局部變量可以通過A的ebp-偏移量A訪問
| f +-------------------------+
| r | Arg n(函數B的第n個參數) |
| a +-------------------------+
| m | Arg .(函數B的第.個參數) |
| e +-------------------------+
| | Arg 1(函數B的第1個參數) |
| o +-------------------------+
| f | Arg 0(函數B的第0個參數) | --+ <------ B函數的參數可以由B的ebp+偏移量B訪問
| +-------------------------+ +--> 偏移量B
| A | EIP (A函數的返回地址) | |
| +-------------------------+ --+
+--- | EBP (A函數的EBP) |<--+ <------ 當前函數B的EBP (即SFP框架指針)
+-------------------------+ |
| Local Variables | |
| .......... | | <------ ESP指向函數B新分配的局部變量
+-------------------------+ |
| Arg n(函數C的第n個參數) | |
+-------------------------+ |
| Arg .(函數C的第.個參數) | |
+-------------------------+ +--> frame of B
| Arg 1(函數C的第1個參數) | |
+-------------------------+ |
| Arg 0(函數C的第0個參數) | |
+-------------------------+ |
| EIP (B函數的返回地址) | |
+-------------------------+ |
+--> | EBP (B函數的EBP) | --+ <------ 當前函數C的EBP (即SFP框架指針)
| +-------------------------+
| | Local Variables |
| | .......... | <------ ESP指向函數C新分配的局部變量
| +-------------------------+----> 低地址
frame of C

圖 1-1
      
    再分析test1反匯編結果中剩余部分語句的含義:
       
    # mdb test1
    Loading modules: [ libc.so.1 ]
    > main::dis                        ; 反匯編main函數
    main:          pushl   %ebp                           
    main+1:        movl    %esp,%ebp        ; 創建Stack Frame(棧框架)
    main+3:       subl    $8,%esp       ; 通過ESP-8來分配8字節堆棧空間
    main+6:       andl    $0xf0,%esp    ; 使棧地址16字節對齊
    main+9:       movl    $0,%eax       ; 無意義
    main+0xe:     subl    %eax,%esp     ; 無意義
    main+0x10:     movl    $0,%eax          ; 設置main函數返回值
    main+0x15:     leave                    ; 撤銷Stack Frame(棧框架)
    main+0x16:     ret                      ; main 函數返回
    >

    以下兩句似乎是沒有意義的,果真是這樣嗎?
        movl    $0,%eax
        subl     %eax,%esp
      
    用gcc的O2級優化來重新編譯test1.c:
    # gcc -O2 test1.c -o test1
    # mdb test1
    > main::dis
    main:         pushl   %ebp
    main+1:       movl    %esp,%ebp
    main+3:       subl    $8,%esp
    main+6:       andl    $0xf0,%esp
    main+9:       xorl    %eax,%eax      ; 設置main返回值,使用xorl異或指令來使eax為0
    main+0xb:     leave
    main+0xc:     ret
    >
    新的反匯編結果比最初的結果要簡潔一些,果然之前被認為無用的語句被優化掉了,進一步驗證了之前的猜測。
    提示:編譯器產生的某些語句可能在程序實際語義上沒有用處,可以用優化選項去掉這些語句。

    問題:為什么用xorl來設置eax的值?
    注意到優化后的代碼中,eax返回值的設置由 movl $0,%eax 變為 xorl %eax,%eax ,這是因為IA32指令中,xorl比movl有更高的運行速度。

    概念:Stack aligned 棧對齊
    那么,以下語句到底是和作用呢?
        subl    $8,%esp
       andl    $0xf0,%esp     ; 通過andl使低4位為0,保證棧地址16字節對齊
      
    表面來看,這條語句最直接的后果是使ESP的地址后4位為0,即16字節對齊,那么為什么這么做呢?
    原來,IA32 系列CPU的一些指令分別在4、8、16字節對齊時會有更快的運行速度,因此gcc編譯器為提高生成代碼在IA32上的運行速度,默認對產生的代碼進行16字節對齊

        andl $0xf0,%esp 的意義很明顯,那么 subl $8,%esp 呢,是必須的嗎?
    這里假設在進入main函數之前,棧是16字節對齊的話,那么,進入main函數后,EIP和EBP被壓入堆棧后,棧地址最末4位二進制位必定是1000,esp -8則恰好使后4位地址二進制位為0000。看來,這也是為保證棧16字節對齊的。

    如果查一下gcc的手冊,就會發現關于棧對齊的參數設置:
    -mpreferred-stack-boundary=n    ; 希望棧按照2的n次的字節邊界對齊, n的取值范圍是2-12

    默認情況下,n是等于4的,也就是說,默認情況下,gcc是16字節對齊,以適應IA32大多數指令的要求。

    讓我們利用-mpreferred-stack-boundary=2來去除棧對齊指令:
     
    # gcc -mpreferred-stack-boundary=2 test1.c -o test1
      
    > main::dis
    main:       pushl   %ebp
    main+1:     movl    %esp,%ebp
    main+3:     movl    $0,%eax
    main+8:     leave
    main+9:     ret
    >

    可以看到,棧對齊指令沒有了,因為,IA32的棧本身就是4字節對齊的,不需要用額外指令進行對齊。
    那么,棧框架指針SFP是不是必須的呢?
    # gcc -mpreferred-stack-boundary=2 -fomit-frame-pointer test1.c -o test
    > main::dis
    main:       movl    $0,%eax
    main+5:     ret
    >

    由此可知,-fomit-frame-pointer 可以去除SFP。
      
    問題:去除SFP后有什么缺點呢?
      
    1)增加調式難度
        由于SFP在調試器backtrace的指令中被使用到,因此沒有SFP該調試指令就無法使用。
    2)降低匯編代碼可讀性
        函數參數和局部變量的訪問,在沒有ebp的情況下,都只能通過+xx(esp)的方式訪問,而很難區分兩種方式,降低了程序的可讀性。
      
    問題:去除SFP有什么優點呢?
      
    1)節省棧空間
    2)減少建立和撤銷棧框架的指令后,簡化了代碼
    3)使ebp空閑出來,使之作為通用寄存器使用,增加通用寄存器的數量
    4)以上3點使得程序運行速度更快

    概念:Calling Convention  調用約定和 ABI (Application Binary Interface) 應用程序二進制接口
        
        函數如何找到它的參數?
        函數如何返回結果?
        函數在哪里存放局部變量?
        那一個硬件寄存器是起始空間?
        那一個硬件寄存器必須預先保留?

    Calling Convention  調用約定對以上問題作出了規定。Calling Convention也是ABI的一部分。
    因此,遵守相同ABI規范的操作系統,使其相互間實現二進制代碼的互操作成為了可能。
    例如:由于Solaris、Linux都遵守System V的ABI,Solaris 10就提供了直接運行Linux二進制程序的功能。
    詳見文章:
關注: Solaris 10的10大新變化
            
3. 小結
    本文通過最簡的C程序,引入以下概念:
        SFP 棧框架指針
        Stack aligned 棧對齊
        Calling Convention  調用約定 和 ABI (Application Binary Interface) 應用程序二進制接口
    今后,將通過進一步的實驗,來深入了解這些概念。通過掌握這些概念,使在匯編級調試程序產生的core dump、掌握C語言高級調試技巧成為了可能。


T.S Liu 2008-06-17 21:16 發表評論
]]>
Linux 匯編語言開發指南http://www.shnenglu.com/liu1061/articles/53761.htmlT.S LiuT.S LiuTue, 17 Jun 2008 13:11:00 GMThttp://www.shnenglu.com/liu1061/articles/53761.htmlhttp://www.shnenglu.com/liu1061/comments/53761.htmlhttp://www.shnenglu.com/liu1061/articles/53761.html#Feedback0http://www.shnenglu.com/liu1061/comments/commentRss/53761.htmlhttp://www.shnenglu.com/liu1061/services/trackbacks/53761.html閱讀全文

T.S Liu 2008-06-17 21:11 發表評論
]]>
gdb 方法 說明 (轉)http://www.shnenglu.com/liu1061/articles/53249.htmlT.S LiuT.S LiuSat, 14 Jun 2008 08:02:00 GMThttp://www.shnenglu.com/liu1061/articles/53249.htmlhttp://www.shnenglu.com/liu1061/comments/53249.htmlhttp://www.shnenglu.com/liu1061/articles/53249.html#Feedback0http://www.shnenglu.com/liu1061/comments/commentRss/53249.htmlhttp://www.shnenglu.com/liu1061/services/trackbacks/53249.html* list:顯示程序中的代碼,常用使用格式有:

    list

      輸出從上次調用list命令開始往后的10行程序代碼。

    list -

      輸出從上次調用list命令開始往前的10行程序代碼。

    list n

      輸出第n行附近的10行程序代碼。

    list function

      輸出函數function前后的10行程序代碼。

 * forward/search:從當前行向后查找匹配某個字符串的程序行。使用格式:

    forward/search 字符串

  查找到的行號將保存在$_變量中,可以用print $_命令來查看。

 * reverse-search:和forward/search相反,向前查找字符串。使用格式同上。

 * break:在程序中設置斷點,當程序運行到指定行上時,會暫停執行。使用格式:

    break 要設置斷點的行號

 * tbreak:設置臨時斷點,在設置之后只起作用一次。使用格式:

    tbreak 要設置臨時斷點的行號

 * clear:和break相反,clear用于清除斷點。使用格式:

    clear 要清除的斷點所在的行號

 * run:啟動程序,在run后面帶上參數可以傳遞給正在調試的程序。

 * awatch:用來增加一個觀察點(add watch),使用格式:

    awatch 變量或表達式

  當表達式的值發生改變或表達式的值被讀取時,程序就會停止運行。

 * watch:與awatch類似用來設置觀察點,但程序只有當表達式的值發生改變時才會停止運行。使用格 式:

    watch 變量或表達式

  需要注意的是,awatch和watch都必須在程序運行的過程中設置觀察點,即可運行run之后才能設置。

 * commands:設置在遇到斷點后執行特定的指令。使用格式有:

    commands

      設置遇到最后一個遇到的斷點時要執行的命令

    commands n

      設置遇到斷點號n時要執行的命令

  注意,commands后面跟的是斷點號,而不是斷點所在的行號。

  在輸入命令后,就可以輸入遇到斷點后要執行的命令,每行一條命令,在輸入最后一條命令后輸入end就可以結束輸入。

 * delete:清除斷點或自動顯示的表達式。使用格式:

    delete 斷點號

 * disable:讓指定斷點失效。使用格式:

    disable 斷點號列表

  斷點號之間用空格間隔開。

 * enable:和disable相反,恢復失效的斷點。使用格式:

    enable 斷點編號列表

 * ignore:忽略斷點。使用格式:

    ignore 斷點號 忽略次數

 * condition:設置斷點在一定條件下才能生效。使用格式:

    condition 斷點號 條件表達式

 * cont/continue:使程序在暫停在斷點之后繼續運行。使用格式:

    cont

      跳過當前斷點繼續運行。

    cont n

      跳過n次斷點,繼續運行。

  當n為1時,cont 1即為cont。

 * jump:讓程序跳到指定行開始調試。使用格式:

    jump 行號

 * next:繼續執行語句,但是跳過子程序的調用。使用格式:

    next

      執行一條語句

    next n

      執行n條語句

 * nexti:單步執行語句,但和next不同的是,它會跟蹤到子程序的內部,但不打印出子程序內部的語句。使用格式同上。

 * step:與next類似,但是它會跟蹤到子程序的內部,而且會顯示子程序內部的執行情況。使用格式同上。

 * stepi:與step類似,但是比step更詳細,是nexti和step的結合。使用格式同上。

 * whatis:顯示某個變量或表達式的數據類型。使用格式:

    whatis 變量或表達式

 * ptype:和whatis類似,用于顯示數據類型,但是它還可以顯示typedef定義的類型等。使用格式:

    ptype 變量或表達式

 * set:設置程序中變量的值。使用格式:

    set 變量=表達式

    set 變量:=表達式

 * display:增加要顯示值的表達式。使用格式:

    display 表達式

 * info display:顯示當前所有的要顯示值的表達式。

 * delete display/undisplay:刪除要顯示值的表達式。使用格式:

    delete display/undisplay 表達式編號

 * disable display:暫時不顯示一個要表達式的值。使用格式:

    disable display 表達式編號

 * enable display:與disable display相反,使用表達式恢復顯示。使用格式:

    enable display 表達式編號

 * print:打印變量或表達式的值。使用格式:

    print 變量或表達式

  表達式中有兩個符號有特殊含義:$和$$。

  $表示給定序號的前一個序號,$$表示給定序號的前兩個序號。

  如果$和$$后面不帶數字,則給定序號為當前序號。

 * backtrace:打印指定個數的棧幀(stack frame)。使用格式:

    backtrace 棧幀個數

 * frame:打印棧幀。使用格式:

    frame 棧幀號

 * info frame:顯示當前棧幀的詳細信息。

 * select-frame:選擇棧幀,選擇后可以用info frame來顯示棧幀信息。使用格式:

    select-frame 棧幀號

 * kill:結束當前程序的調試。

 * quit:退出gdb。



T.S Liu 2008-06-14 16:02 發表評論
]]>
gdb command! (轉)http://www.shnenglu.com/liu1061/articles/53232.htmlT.S LiuT.S LiuSat, 14 Jun 2008 05:37:00 GMThttp://www.shnenglu.com/liu1061/articles/53232.htmlhttp://www.shnenglu.com/liu1061/comments/53232.htmlhttp://www.shnenglu.com/liu1061/articles/53232.html#Feedback0http://www.shnenglu.com/liu1061/comments/commentRss/53232.htmlhttp://www.shnenglu.com/liu1061/services/trackbacks/53232.html一個調試器,能讓你觀察到正在運行的程序的某個變量的值,和gcc, emacs組成構建起整個gnu system的3劍客。

2.How it work?
首先要安裝,然后就可以 gdb application,進入gdb模式,執行(run)啟動例程。(list-顯示源碼)

3.一個優點
GDB的函數調用是緩式的,也就是說只有當變量真正需要時才會被計算。
int c = add(1,1)
printf("%d",c);

gdb-->run-->print c -1222342. c的值直到打印的時候才會被計算。(這里可能有個開關來控制緩式計算)

4.一個前提
gcc 的時候加上 -g 或者 -ggdb,主要是生成供調試使用的某些信息。(emacs好像默認是關閉這個選項)

5.存在圖形調試界面

6.輸入help可以查看幫助
help,會顯示命令的分類,help 類名

7.how use?
debug 3 program yourself.

8.常用命令(From:http://my.donews.com/tangfl/2006/10/23/gdb-debug-example/)
  break NUM 在指定的行上設置斷點。
  bt 顯示所有的調用棧幀。該命令可用來顯示函數的調用順序。
  clear 刪除設置在特定源文件、特定行上的斷點。其用法為clear FILENAME:NUM
  continue 繼續執行正在調試的程序。該命令用在程序由于處理信號或斷點而 導致停止運行時。
  display EXPR 每次程序停止后顯示表達式的值。表達式由程序定義的變量組成。
  file FILE 裝載指定的可執行文件進行調試。
  help NAME 顯示指定命令的幫助信息。
  info break 顯示當前斷點清單,包括到達斷點處的次數等。
  info files 顯示被調試文件的詳細信息。
  info func 顯示所有的函數名稱。
  info local 顯示當函數中的局部變量信息。
  info prog 顯示被調試程序的執行狀態。
  info var 顯示所有的全局和靜態變量名稱。
  kill 終止正被調試的程序。
  list 顯示源代碼段。
  make 在不退出 gdb 的情況下運行 make 工具。
  next 在不單步執行進入其他函數的情況下,向前執行一行源代碼。
  print EXPR 顯示表達式 EXPR 的值。
backtrace 顯示程序中的當前位置和表示如何到達當前位置的棧跟蹤(同義詞:where)
breakpoint 在程序中設置一個斷點
cd 改變當前工作目錄
clear 刪除剛才停止處的斷點
commands 命中斷點時,列出將要執行的命令
continue 從斷點開始繼續執行
delete 刪除一個斷點或監測點;也可與其他命令一起使用
display 程序停止時顯示變量和表達時
down 下移棧幀,使得另一個函數成為當前函數
frame 選擇下一條continue命令的幀
info 顯示與該程序有關的各種信息
jump 在源程序中的另一點開始運行
kill 異常終止在gdb 控制下運行的程序
list 列出相應于正在執行的程序的原文件內容
next 執行下一個源程序行,從而執行其整體中的一個函數
print 顯示變量或表達式的值
pwd 顯示當前工作目錄
pype 顯示一個數據結構(如一個結構或C++類)的內容
quit 退出gdb
reverse-search 在源文件中反向搜索正規表達式
run 執行該程序
search 在源文件中搜索正規表達式
set variable 給變量賦值
signal 將一個信號發送到正在運行的進程
step 執行下一個源程序行,必要時進入下一個函數
undisplay display命令的反命令,不要顯示表達式
until 結束當前循環
up 上移棧幀,使另一函數成為當前函數
watch 在程序中設置一個監測點(即數據斷點)
whatis 顯示變量或函數類型

T.S Liu 2008-06-14 13:37 發表評論
]]>
ubuntu linux base comandhttp://www.shnenglu.com/liu1061/articles/52223.htmlT.S LiuT.S LiuThu, 05 Jun 2008 02:14:00 GMThttp://www.shnenglu.com/liu1061/articles/52223.htmlhttp://www.shnenglu.com/liu1061/comments/52223.htmlhttp://www.shnenglu.com/liu1061/articles/52223.html#Feedback0http://www.shnenglu.com/liu1061/comments/commentRss/52223.htmlhttp://www.shnenglu.com/liu1061/services/trackbacks/52223.htmlNO   分類   PS1   命令名   用法及參數   功能注解         
1  文件管理   #   ls   ls -a   列出當前目錄下的所有文件,包括以.頭的隱含文件          
   文件管理   #   ls   ls -l或ll   列出當前目錄下文件的詳細信息          
   文件管理   #   pwd   pwd   查看當前所在目錄的絕對路經          
   文件管理   #   cd   cd ..   回當前目錄的上一級目錄          
   文件管理   #   cd   cd -   回上一次所在的目錄          
   文件管理   #   cd   cd ~ 或 cd   回當前用戶的宿主目錄          
   文件管理   #   cd   cd ~用戶名   回指定用戶的宿主目錄         
2  文件管理   #   mkdir   mkdir 目錄名   創建一個目錄          
   文件管理   #   mkdir   mkdir –p   遞歸式去創建一些嵌套目錄          
   文件管理   #   rmdir   Rmdir 空目錄名   刪除一個空目錄         
3  文件管理   #   rm   rm 文件名 文件名   刪除一個文件或多個文件          
   文件管理   #   rm   rm -rf 非空目錄名   遞歸刪除一個非空目錄下的一切,不讓提式-f         
4  文件管理   #   cat   cat文件名   一屏查看文件內容         
5  文件管理   #   more   more文件名   分頁查看文件內容         
6  文件管理   #   less   less 文件名   可控分頁查看文件內容         
7  文件管理   #   grep   grep字符 文件名   根據字符匹配來查看文件部分內容         
8  文件管理   #   mv   mv 路經/文件  /經/文件   移動相對路經下的文件到絕對路經下          
   文件管理   #   mv   mv 文件名 新名稱   在當前目錄下改名         
9  文件管理   #   cp   cp /路經/文件  ./   移動絕對路經下的文件到當前目錄下         
10 文件管理   #   find   find 路經 -name “字符串”   查找路經所在范圍內滿足字符串匹配的文件和目錄         
11 文件管理   #   ln   ln 源文件 鏈接名   創建當前目錄源文件的硬鏈接         
                  ln /home/test /usr/test1   在/usr下建立/home/test的硬鏈接         
12 文件管理   #   ln   Ln -s a b   創建當前目錄下a的符號鏈接b      
13 文件管理   #   touch   touch file1 file2   創建兩個空文件         
14 磁盤管理   #   df   df   用于報告文件系統的總容量,使用量,剩余容量。         
15 磁盤管理   #   du   du -b /home   查看目前/HOME目錄的容量(k)及子目錄的容量(k)。         
16 磁盤管理   #   fdisk   fdisk -l   查看系統分區信息      
17 磁盤管理   #   fdisk   fdisk /dev/sdb   為一塊新的SCSI硬盤進行分區      
18 磁盤管理   #   mkfs.ext3   Mkfs.ext3 /dev/sdb1
                  為第一塊SCSI硬盤的第一主分區格式化成ext3的文件系統      
                  mkfs.ext2   Mkfs.ext2/dev/sdb2    格式化成ext2文件系統      
19 磁盤管理   #   mount   mount -t 文件系統類型 設備路經  訪問路經         
   磁盤管理   #   文件系統類型            
                  Iso9660   光驅文件系統         
                  vfat   Fat文件系統(windows)         
   掛載光驅   #   mount –t iso9660 /dev/cdrom /mnt/cdrom           
   掛載FAT    #   mount –t vfat /dev/hda5 /mnt/cdrom    掛第一個ide的第五個邏輯分區      
17 磁盤管理   #   Umount /mnt/cdrom     卸載/mnt/cdrom為空      
18 文件權限   #   chmod   chmod u+s file   為file的屬主加上特殊權限         
                  chmod g+r file   為file的屬組加上讀權限         
                  chmod o+w file   為file的其它用戶加上寫權限         
                  chmod a-x file   為file的所有用戶減去執行權限      
                  chmod 765 file  為file的屬主設為完全權限,屬組設成讀寫權,其它用戶具有讀和執心權限      
19   文件權限   #   chown   chown root /home   把/home的屬主改成root用戶      
20   文件權限   #   chgrp   chgrp root /home   把/home的屬組改成root組      
21   打印管理   #   redhat-config-printer-tui   進入安裝打印機界面         
22   打印管理   #   lp   lp –d hptr file   打印file到hptr的打印機上         
23   打印管理   #   lpq   Lpq –P 打印機名   查看打印機的狀態         
24   打印管理   #   lprm   Lprm –P 打印機名 a   刪除打印機內的打印作業         
25   打印管理   #   disable   Disable –r “changing paper” HPtr    禁用打印機并提示原因      
26   打印管理   #   enable   Enable HPtr   重新啟用被禁用的         
27   用戶管理   #   useradd   Useradd   創建一個新的用戶         
28   用戶管理   #   groupadd   Groupadd 組名   創建一個新的組         
29   用戶管理   #   passwd   Passwd 用戶名   為用戶創建密碼         
30   用戶管理   #   Passwd -d   Passwd -d用戶名   刪除用戶密碼也能登陸         
31   用戶管理   #   Passwd -l   Passwd -l用戶名   鎖定賬號密碼         
32   用戶管理   #   Passwd -u   Passwd -u用戶名   解鎖賬號密碼         
33   用戶管理   #   Passwd -S   Passwd -S用戶名   查詢賬號密碼         
34   用戶管理   #   Usermod -l   Usermod -l 新用戶名 老用戶名   為用戶改名         
35   用戶管理   #   Usermod -L   Usermod -L 要鎖定用戶名   鎖定用戶登陸         
36   用戶管理   #   Usermod -U   Usermod –U解鎖用戶名   解鎖用戶登陸         
37   用戶管理   #   Usermod -u   Usermod –u 501用戶名   改變用戶UID         
38   用戶管理   #   Userdel   Userdel–r 用戶名   刪除用戶一切         
39   用戶管理   #   Groupmod -n   Groupmod –n新用戶名 老用戶名   為組改名         
40   用戶管理   #   Groupmod -g   Groupmod –g 501 組名   改變組GID         
41   用戶管理   #   groupdel   Groupdel組名    先應刪它的用戶   刪除組         
42   用戶管理   #   gpasswd -a   gpasswd -a 用戶名 組名   增加用戶到組         
43   用戶管理   #   Id    id   用戶名   查用戶信息         
44   軟件管理   #   rpm -qa   rpm –qa | less   查詢已安裝RPM         
45   軟件管理   #   rpm –qa | grep ftp   查詢指定RPM         
46   軟件管理   #   rpm -q   rpm -q 已安裝的RPM包   查是否安裝         
47   軟件管理   #   rpm -q telnet-server   查看telnet服務器包      
48   軟件管理   #   rpm -qi   rpm –qi 軟件包名稱   查看軟件的描述信息      
49   軟件管理   #   rpm -ql   rpm –ql軟件包名稱   查詢軟件包的文件列表      
50   軟件管理   #   rpm -qf   rpm –qf軟件包名稱   查詢某個文件所屬的軟件包      
51   軟件管理   #   rpm -qp   rpm –qp軟件包全名   查詢未安裝的軟件包信息      
52   軟件管理   #   rpm -e   rpm –e 軟件包名稱   刪除具體的軟件包      
53   軟件管理   #   rpm -U   rpm –Uvh軟件包全名   升級軟件包并顯示過程      
54   軟件管理   #   rpm -ivh   rpm –ivh 軟件包全名   安裝軟件包并顯示過程      
55   軟件管理   #   rpm -V   rpm –V軟件包名稱   驗證軟件包的大小,類型等      
56   軟件管理   #   tar    -c 創建包 –x 釋放包  -v 顯示命令過程 –z 代表壓縮包      
57   軟件管理   #   tar -cf   tar –cvf benet.tar /home/benet   把/home/benet目錄打包      
58   軟件管理   #   tar -czf   tar –zcvf benet.tar.gz /mnt   把目錄打包并壓縮      
59   軟件管理   #   tar –tf   tar –tf benet.tar   看非壓縮包的文件列表      
60   軟件管理   #   tar –tzf   tar –tf benet.tar.gz   看壓縮包的文件列表      
61   軟件管理   #   tar –xf   tar –xf benet.tar   非壓縮包的文件恢復      
62   軟件管理   #   tar –zxvf   tar –zxvf benet.tar.gz   壓縮包的文件解壓恢復      
63   軟件管理   #   tar -jxvf   tar –jxvf benet.tar.bz2         
64   軟件管理   #   diff   diff file1 file2 > 補丁名.patch   為新舊文件生成補丁文件      
65   軟件管理   #   diff   diff file1 file2   比較兩個文件的區別      
66   軟件管理   #   Patch    Patch file補丁名.patch   打補丁      
67   軟件管理   #   ./configure  --prefix=/usr/local/   編譯前配置      
68   軟件管理   #   make   編譯      
69   軟件管理   #   make install   安裝編譯好的源碼包      
70   啟動管理   #   reboot   Init 6   重啟LINUX系統      
71   啟動管理   #   Halt   Init 0   Shutdown –h now   關閉LINUX系統      
72   啟動管理   #   runlevel      顯示系統運行級      
73   啟動管理   #   Init [0123456]       改變系統運行級,7種      
74   啟動管理   #   Chkconfig –-list [服務名稱]   查看服務的狀態      
75   啟動管理   #   Chkconfig –-level <運行級> <服務名> on|off|set    設置服務的啟動狀態      
76   啟動管理   #   Chkconfig <服務名> on|off|set   設置非獨立服務啟狀態      
77   進程管理   #   Top動態   Ps-aux靜態   進程樹pstree    查看系統進程      
78   進程管理   #   程序名 &   后臺運行程序         
79   進程管理   #   fg   把后臺運行的進程調回前臺         
80   進程管理   #   bg   把前臺運行進程調到后臺         
81   進程管理   #   renice   Renice +1 180    把180號進程的優先級加1      
82   進程管理   #   kill   Kill PID    終止某個PID進程      
83   進程管理   #   at   at 5pm + 3 days
                    /bin/ls   指定三天后下午5:00執行/bin/ls      
84   進程管理   #   crontab   Crontab -e   用VI的形式來編輯自動周期性任務      
85   進程管理   #   crontab   Crontab -l   查看自動周期性任務      
86   進程管理   #   crontab   Crontab -r   刪除自動周期性任務      
87   進程管理   #   crond   Service crond <start|stop|restart|status>      
   馬上啟動自動周期性服務   Service crond <啟動|停止|重啟|狀態>      
            
   實現磁盤配額   (注安裝LINUX時建立/home分區)
目標:對用戶zhao在/home目錄上實現soft limit為5k,hard limit 為10k的磁盤配額
實現步驟:
1. 修改包含/home的行,  #vi /etc/fstab, 改為:defaults,usrquota。也就是增加usrquota項。然后保存退出。
2、卸載/home目錄                           #umount /home
3. 掛接/home目錄                           #mount /home
4、增加用戶zhao                            #useradd zhao 
5、修改密碼                                #passwd zhao 
6、生成關于/home目錄的quota信息              #quotacheck -cmug /home 
                                         #quotacheck -vu /home 
7、查看所有用戶的信息                        #repquota -au
8、設置配額                                #edquota -u zhao
將soft 和hard 分別改為5和10
9、保存并退出                               #wq! 
10、修改時間                                #edquota -t 
11、                                      #wq!
12.開啟/home上的磁盤配額功能                 #quotaon /home
13.查詢配額                                #quota -u zhao
14.驗證配額                                #su - zhao 
                                          $touch myfile

T.S Liu 2008-06-05 10:14 發表評論
]]>
ubuntu一些基本操作用法!(轉)http://www.shnenglu.com/liu1061/articles/52174.htmlT.S LiuT.S LiuWed, 04 Jun 2008 08:44:00 GMThttp://www.shnenglu.com/liu1061/articles/52174.htmlhttp://www.shnenglu.com/liu1061/comments/52174.htmlhttp://www.shnenglu.com/liu1061/articles/52174.html#Feedback0http://www.shnenglu.com/liu1061/comments/commentRss/52174.htmlhttp://www.shnenglu.com/liu1061/services/trackbacks/52174.html如何列出硬盤分割表?
sudo fdisk -l
  • 您可以使用 系統 -> 管理 -> Disks

[編輯] 如何列出硬盤檔案系統使用狀況?

df -T -h
  • 您可以使用 系統 -> 管理 -> Disks

[編輯] 如何列出掛載的設備?

mount

[編輯] 如何列出 PCI 設備?

lspci

[編輯] 如何列出 USB 設備?

lsusb

[編輯] 如何提高 CD/DVD-ROM 速度?

e.g. 假設 CD/DVD-ROM設備 位置是 /dev/cdrom
sudo hdparm -d1 /dev/cdrom
sudo cp /etc/hdparm.conf /etc/hdparm.conf_backup
sudo gedit /etc/hdparm.conf
  • 檔案后面增加此行敘述
/dev/cdrom {
dma = on
}
  • 儲存編輯過的檔案

[編輯] 如何手動 掛載/卸載 CD/DVD-ROM , 并且顯示所有隱藏以及關聯的 檔案/資料夾?

e.g. 假設 CD/DVD-ROM 位置是 /media/cdrom0/
  • 掛載 CD/DVD-ROM
sudo mount /media/cdrom0/ -o unhide
  • 卸載 CD/DVD-ROM
sudo umount /media/cdrom0/

[編輯] 如何手動強制卸載 CD/DVD-ROM ?

e.g. 假設 CD/DVD-ROM 位置是 /media/cdrom0/
sudo umount /media/cdrom0/ -l

[編輯] 如何不用重開機下掛載 /etc/fstab ?

sudo mount -a

[編輯] CD/DVD 燒錄

[編輯] 如何清除 CD-RW/DVD-RW?

e.g. 假設 CD/DVD-ROM 位置為 /dev/cdrom
sudo umount /dev/cdrom
cdrecord dev=/dev/cdrom blank=fast

[編輯] 如何燒錄 檔案/資料夾 至 CD/DVD?

nautilus burn:///
  • CD/DVD 光盤制作程序 : 檔案瀏覽器
  • 拖曳 檔案/資料夾 至窗口內
檔案選單 -> 燒錄光盤... -> 燒錄

[編輯] 如何燒錄影像檔 (ISO) 至 CD/DVD?

點選影像檔(ISO)右鍵 -> 燒錄光盤... -> 燒錄

[編輯] 如何復制 CD/DVD?

[編輯] 如何從 CD/DVD 建立影像檔 (ISO)?

e.g. 假設 CD/DVD-ROM 位置為 /dev/cdrom
sudo umount /dev/cdrom
dd if=/dev/cdrom of=file.iso bs=1024

[編輯] 如何將資料夾資料建立成影像檔(ISO)?

mkisofs -o file.iso /location_of_folder/

[編輯] 如何產生 MD5 檢查碼檔案?

md5sum file.iso > file.iso.md5

[編輯] 如何檢查檔案的 MD5 碼?

e.g. 假設 file.iso 以及 file.iso.md5 位于相同的目錄
md5sum -c file.iso.md5

[編輯] 如何不透過燒錄而 掛載/卸載 影像檔 (ISO) ?

sudo mkdir /media/iso
sudo modprobe loop
sudo mount file.iso /media/iso/ -t iso9660 -o loop
  • 卸載影像檔 (ISO)
sudo umount /media/iso/

[編輯] 如何 設定/改變 CD/DVD 燒錄速度?

  • 請參閱 #基本備注
  • 應用程序 -> 系統工具 -> 組態編輯器
  • 組態編輯器
/ -> apps -> nautilus-cd-burner -> default_speed (設定/改變 燒錄速度)

[編輯] 如何啟動 CD/DVD 燒錄 burnproof?

  • 請參閱 #基本備注
  • 應用程序 -> 系統工具 -> 組態編輯器
  • 組態編輯器
/ -> apps -> nautilus-cd-burner -> burnproof (勾選)

[編輯] 如何啟動 CD/DVD 超燒?

  • 請參閱 #基本備注
  • 應用程序 -> 系統工具 -> 組態編輯器
  • 組態編輯器
/ -> apps -> nautilus-cd-burner -> overburn (勾選)

[編輯] 網絡

[編輯] 如何設定 Google Talk?

[編輯] 如何 啟動/關閉 網絡連線?

  • 請參閱 #基本備注
  • 系統 -> 管理 -> 網絡
  • 網絡連線
連線 -> 選擇 "以太網連線" -> 啟動/停止使用

[編輯] 如何設定網絡連線?

  • 請參閱 #基本備注
  • 系統 -> 管理 -> 網絡
  • 網絡連線
連線 -> 選擇 "以太網連線" -> 屬性
連線 -> 啟動這個連線 (勾選)
連線設定 -> 組態: 選擇 "DHCP/固定 IP 位址"
DNS -> DNS 服務器 -> 新增/刪除

[編輯] 如何設定撥號連線?

sudo pppconfig
  • 開始連線
sudo pon provider_name
  • 結束連線
sudo poff

[編輯] 如何設定寬帶連線?

sudo pppoeconf

[編輯] 如何修改主機名稱?

  • 請參閱 #基本備注
  • 系統 -> 管理 -> 網絡
  • 網絡設定
一般 -> 主機設定 -> 主機名稱: 指定計算機名稱
  • 儲存并且關閉所有已開啟的應用程序,并重開機。

[編輯] 如何修改主機敘述?

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

[編輯] 如何用免費 DynDNS 服務指定使用動態IP本機的名稱?

e.g. 假設因特網連線組態已經完成
注冊免費動態 DNS 服務 https://www.dyndns.org
每一小時自動更新 IP 至 DynDNS Database/DNS
* * * * * 代表 分 時 日 月 星期
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"
共享內容 -> 名稱: 指定共享名稱

[編輯] 如何瀏覽網絡上計算機?

e.g. 假設局域網路已經設定好了
如果計算機或者網絡資料夾無法找到,試著接存取他們。
請參閱 #如何不先掛載就讀取網絡分享檔案夾?
  • 位置 -> 網絡服務器

[編輯] 如何不先掛載就讀取網絡分享檔案夾?

例如:假設你已正確設定好網絡連線
網絡上分享出資料夾的計算機IP位址是: 192.168.0.1
分享出來的資料夾名稱是: linux
  • 應用程序 -> 執行命令...
  • 輸入并執行以下指令
smb://192.168.0.1/linux

[編輯] 如何手動 掛載/卸載 網絡分享的資料夾,并予許所有使用者讀取?

e.g. 假設網絡連線已經設定完成
網絡計算機 IP: 192.168.0.1
網絡計算機帳號: myusername
網絡計算機密碼: mypassword
分享資料夾名稱: linux
本機掛載資料夾: /media/sharename
  • 掛載網絡資料夾
sudo mkdir /media/sharename
sudo mount //192.168.0.1/linux /media/sharename/ -o username=myusername,password=mypassword
  • 卸載網絡資料夾
sudo umount /media/sharename/

[編輯] 如何手動掛載/卸除網絡共享檔案夾, 并允許所有使用者都可讀取和寫入?

e.g. 假設網絡連線已經設定完成
網絡計算機 IP: 192.168.0.1
網絡計算機帳號: myusername
網絡計算機密碼: mypassword
分享資料夾名稱: linux
本機掛載資料夾: /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/

[編輯] 如何在系統啟動時, 自動掛載網絡分享檔案夾, 并允許所有使用者都可讀取 ?

e.g. 假設網絡連線已經設定完成
網絡計算機 IP: 192.168.0.1
網絡計算機帳號: myusername
網絡計算機密碼: mypassword
分享資料夾名稱: linux
本機掛載資料夾: /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

[編輯] 如何在系統啟動時, 自動掛載網絡分享檔案夾, 并允許所有使用者都可讀取 ?

e.g. 假設網絡連線已經設定完成
網絡計算機 IP: 192.168.0.1
網絡計算機帳號: myusername
網絡計算機密碼: mypassword
分享資料夾名稱: linux
本機掛載資料夾: /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,dmask=777,fmask=777  0    0

[編輯] 如何取得無線網絡模組(ipw2200)并且使用無線資料傳輸協定(WAP)?

[編輯] 遠端桌面

[編輯] 如何設定遠端桌面 (沒有安全性)?

警告! 遠端桌面只在 GNOME 登入 session 運作
離開計算機而未注意 GNOME 登入 session 是不安全
使用 (系統 -> 鎖定劃面) 并且離開計算機時關掉螢幕
  • 系統 -> 偏好管理 -> 遠端桌面
  • 遠端桌面偏好設定
共享 ->
允許其他使用者觀看您的桌面 (勾選)
允許其他使用者控制您的桌面 (勾選)
安全性 ->
詢問您已確認 (不勾選)
使用者需要輸入密碼: (勾選)
密碼: 指定密碼

[編輯] 如何連結遠端 Ubuntu 桌面?

e.g. Assumed that remote Ubuntu machine have configured Remote Desktop
Read #如何設定遠端桌面 (沒有安全性)?
Remote Ubuntu machine: 192.168.0.1
vncviewer -fullscreen 192.168.0.1:0
  • To quit vncviewer
Press 'F8' -> Quit viewer

[編輯] 如何從 Windows 機器上連結遠端 Ubuntu 桌面?

e.g. Assumed that remote Ubuntu machine have configured Remote Desktop
Read #如何設定遠端桌面 (沒有安全性)?
Remote Ubuntu machine: 192.168.0.1
  • Download VNC Viewer: Here

[編輯] Windows

[編輯] 如何手動 掛載/卸載 Windows 分割區 (NTFS) , 并且允許所有使用者只能讀取?


e.g. 假設 Windows 分割區 (NTFS) 位置是 /dev/hda1
本地掛載資料夾: /media/windows
  • 掛載 Windows 分割區
sudo mkdir /media/windows
sudo mount /dev/hda1 /media/windows/ -t ntfs -o nls=utf8,umask=0222
  • 卸載 Windows 分割區
sudo umount /media/windows/

[編輯] 如何手動 掛載/卸載 Windows 分割區 (FAT) , 并且允許所有使用者能讀取以及寫入?

e.g. 假設 Windows 分割區 (FAT) 位置為 /dev/hda1
本地掛載資料夾: /media/windows
  • 掛載 Windows 分割區
sudo mkdir /media/windows
sudo mount /dev/hda1 /media/windows/ -t vfat -o iocharset=utf8,umask=000
  • 卸載 Windows 分割區
sudo umount /media/windows/

[編輯] 如何開機時掛載 Windows 分割區 (NTFS) , 并且允許所有使用者讀取?

e.g. 假設 Windows 分割區 (NTFS) 位置為 /dev/hda1
本地掛載資料夾: /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

[編輯] 如何開機時掛載 Windows 分割區 (FAT), 并且允許所有使用者讀取/寫入?

e.g. 假定 Windows 分割區 (FAT) 位置為 /dev/hda1
本地掛載資料夾: /media/windows
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


T.S Liu 2008-06-04 16:44 發表評論
]]>
用GDB調試程序http://www.shnenglu.com/liu1061/articles/51895.htmlT.S LiuT.S LiuMon, 02 Jun 2008 09:09:00 GMThttp://www.shnenglu.com/liu1061/articles/51895.htmlhttp://www.shnenglu.com/liu1061/comments/51895.htmlhttp://www.shnenglu.com/liu1061/articles/51895.html#Feedback0http://www.shnenglu.com/liu1061/comments/commentRss/51895.htmlhttp://www.shnenglu.com/liu1061/services/trackbacks/51895.html閱讀全文

T.S Liu 2008-06-02 17:09 發表評論
]]>
gcc和g++的區別http://www.shnenglu.com/liu1061/articles/51872.htmlT.S LiuT.S LiuMon, 02 Jun 2008 04:37:00 GMThttp://www.shnenglu.com/liu1061/articles/51872.htmlhttp://www.shnenglu.com/liu1061/comments/51872.htmlhttp://www.shnenglu.com/liu1061/articles/51872.html#Feedback0http://www.shnenglu.com/liu1061/comments/commentRss/51872.htmlhttp://www.shnenglu.com/liu1061/services/trackbacks/51872.html
2008-03-18 00:32
http://www.yuanma.org/data/2007/0406/article_2498.htm
gcc和g++的區別
我們在編譯c/c++代碼的時候,有人用gcc,有人用g++,于是各種說法都來了,譬如c代碼用gcc,而c++代碼用g++,或者說編譯用 gcc,鏈接用g++,一時也不知哪個說法正確,如果再遇上個extern "C",分歧就更多了,這里我想作個了結,畢竟知識的目的是令人更清醒,而不是更糊涂。
誤區一:gcc只能編譯c代碼,g++只能編譯c++代碼

兩者都可以,但是請注意:
1.后綴為.c的,gcc把它當作是C程序,而g++當作是c++程序;后綴為.cpp的,兩者都會認為是c++程序,注意,雖然c++是c的超集,但是兩者對語法的要求是有區別的,例如:
#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的語法規則,OK,沒問題,但是,一旦把后綴改為cpp,立刻報三個錯:“printString未定義”;
“cannot convert `char**' to `char*”;
”return-statement with no value“;
分別對應前面紅色標注的部分。可見C++的語法規則更加嚴謹一些。
2.編譯階段,g++會調用gcc,對于c++代碼,兩者是等價的,但是因為gcc命令不能自動和C++程序使用的庫聯接,所以通常用g++來完成鏈接,為了統一起見,干脆編譯/鏈接統統用g++了,這就給人一種錯覺,好像cpp程序只能用g++似的。
誤區二:gcc不會定義__cplusplus宏,而g++會

實際上,這個宏只是標志著編譯器將會把代碼按C還是C++語法來解釋,如上所述,如果后綴為.c,并且采用gcc編譯器,則該宏就是未定義的,否則,就是已定義。
誤區三:編譯只能用gcc,鏈接只能用g++

嚴格來說,這句話不算錯誤,但是它混淆了概念,應該這樣說:編譯可以用gcc/g++,而鏈接可以用g++或者gcc -lstdc++。因為gcc命令不能自動和C++程序使用的庫聯接,所以通常使用g++來完成聯接。但在編譯階段,g++會自動調用gcc,二者等價。
誤區四:extern "C"與gcc/g++有關系

實際上并無關系,無論是gcc還是g++,用extern "c"時,都是以C的命名方式來為symbol命名,否則,都以c++方式命名。試驗如下:
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        //注意此函數的命名
        .type   CppPrintf, @function
[root@root GCC]# gcc -S me.cpp
[root@root GCC]# less me.s
.globl _Z9CppPrintfv        //注意此函數的命名
        .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        //注意此函數的命名
        .type   _Z9CppPrintfv, @function
[root@root G++]# g++ -S me.cpp
[root@root G++]# less me.s
.globl _Z9CppPrintfv        //注意此函數的命名
        .type   _Z9CppPrintfv, @function
完全相同!
【結論】完全相同,可見extern "C"與采用gcc/g++并無關系,以上的試驗還間接的印證了前面的說法:在編譯階段,g++是調用gcc的。


T.S Liu 2008-06-02 12:37 發表評論
]]>
gcc/g++ 常用選項http://www.shnenglu.com/liu1061/articles/51870.htmlT.S LiuT.S LiuMon, 02 Jun 2008 04:32:00 GMThttp://www.shnenglu.com/liu1061/articles/51870.htmlhttp://www.shnenglu.com/liu1061/comments/51870.htmlhttp://www.shnenglu.com/liu1061/articles/51870.html#Feedback0http://www.shnenglu.com/liu1061/comments/commentRss/51870.htmlhttp://www.shnenglu.com/liu1061/services/trackbacks/51870.html
http://blog.csdn.net/blade2001/archive/2007/06/10/1646530.aspx

gcc and g++分別是gnu的c & c++編譯器 gcc/g++在執行編譯工作的時候,總共需要4步

1.預處理,生成.i的文件[預處理器cpp]
2.將預處理后的文件不轉換成匯編語言,生成文件.s[編譯器egcs]
3.有匯編變為目標代碼(機器代碼)生成.o的文件[匯編器as]
4.連接目標代碼,生成可執行程序[鏈接器ld]
[參數詳解]
-x language filename
設定文件所使用的語言,使后綴名無效,對以后的多個有效.也就是根據約定C語言的后
綴名稱是.c的,而C++的后綴名是.C或者.cpp,如果你很個性,決定你的C代碼文件的后綴
名是.pig 哈哈,那你就要用這個參數,這個參數對他后面的文件名都起作用,除非到了
下一個參數的使用。
可以使用的參數嗎有下面的這些
`c', `objective-c', `c-header', `c++', `cpp-output', `assembler', and `a
ssembler-with-cpp'.
看到英文,應該可以理解的。
例子用法:
gcc -x c hello.pig

-x none filename
關掉上一個選項,也就是讓gcc根據文件名后綴,自動識別文件類型
例子用法:
gcc -x c hello.pig -x none hello2.c

-c
只激活預處理,編譯,和匯編,也就是他只把程序做成obj文件
例子用法:
gcc -c hello.c
他將生成.o的obj文件
-S
只激活預處理和編譯,就是指把文件編譯成為匯編代碼。
例子用法
gcc -S hello.c
他將生成.s的匯編代碼,你可以用文本編輯器察看
-E
只激活預處理,這個不生成文件,你需要把它重定向到一個輸出文件里面.
例子用法:
gcc -E hello.c > pianoapan.txt
gcc -E hello.c | more
慢慢看吧,一個hello word 也要與處理成800行的代碼
-o
制定目標名稱,缺省的時候,gcc 編譯出來的文件是a.out,很難聽,如果你和我有同感
,改掉它,哈哈
例子用法
gcc -o hello.exe hello.c (哦,windows用習慣了)
gcc -o hello.asm -S hello.c
-pipe
使用管道代替編譯中臨時文件,在使用非gnu匯編工具的時候,可能有些問題
gcc -pipe -o hello.exe hello.c
-ansi
關閉gnu c中與ansi c不兼容的特性,激活ansi c的專有特性(包括禁止一些asm inl
ine typeof關鍵字,以及UNIX,vax等預處理宏,
-fno-asm
此選項實現ansi選項的功能的一部分,它禁止將asm,inline和typeof用作關鍵字。

-fno-strict-prototype
只對g++起作用,使用這個選項,g++將對不帶參數的函數,都認為是沒有顯式的對參數
的個數和類型說明,而不是沒有參數.
而gcc無論是否使用這個參數,都將對沒有帶參數的函數,認為城沒有顯式說明的類型


-fthis-is-varialble
就是向傳統c++看齊,可以使用this當一般變量使用.

-fcond-mismatch
允許條件表達式的第二和第三參數類型不匹配,表達式的值將為void類型

-funsigned-char
-fno-signed-char
-fsigned-char
-fno-unsigned-char
這四個參數是對char類型進行設置,決定將char類型設置成unsigned char(前兩個參
數)或者 signed char(后兩個參數)

-include file
包含某個代碼,簡單來說,就是便以某個文件,需要另一個文件的時候,就可以用它設
定,功能就相當于在代碼中使用#i nclude<filename>
例子用法:
gcc hello.c -include /root/pianopan.h

-imacros file
將file文件的宏,擴展到gcc/g++的輸入文件,宏定義本身并不出現在輸入文件中

-Dmacro
相當于C語言中的#define macro

-Dmacro=defn
相當于C語言中的#define macro=defn

-Umacro
相當于C語言中的#undef macro
-undef
取消對任何非標準宏的定義

-Idir
在你是用#i nclude"file"的時候,gcc/g++會先在當前目錄查找你所制定的頭文件,如
果沒有找到,他回到缺省的頭文件目錄找,如果使用-I制定了目錄,他
回先在你所制定的目錄查找,然后再按常規的順序去找.
對于#i nclude<file>,gcc/g++會到-I制定的目錄查找,查找不到,然后將到系統的缺
省的頭文件目錄查找

-I-
就是取消前一個參數的功能,所以一般在-Idir之后使用

-idirafter dir
在-I的目錄里面查找失敗,講到這個目錄里面查找.

-iprefix prefix
-iwithprefix dir
一般一起使用,當-I的目錄查找失敗,會到prefix+dir下查找

-nostdinc
使編譯器不再系統缺省的頭文件目錄里面找頭文件,一般和-I聯合使用,明確限定頭
文件的位置

-nostdin C++
規定不在g++指定的標準路經中搜索,但仍在其他路徑中搜索,.此選項在創libg++庫
使用

-C
在預處理的時候,不刪除注釋信息,一般和-E使用,有時候分析程序,用這個很方便的


-M
生成文件關聯的信息。包含目標文件所依賴的所有源代碼你可以用gcc -M hello.c
來測試一下,很簡單。

-MM
和上面的那個一樣,但是它將忽略由#i nclude<file>造成的依賴關系。

-MD
和-M相同,但是輸出將導入到.d的文件里面

-MMD
和-MM相同,但是輸出將導入到.d的文件里面

-Wa,option
此選項傳遞option給匯編程序;如果option中間有逗號,就將option分成多個選項,然
后傳遞給會匯編程序

-Wl.option
此選項傳遞option給連接程序;如果option中間有逗號,就將option分成多個選項,然
后傳遞給會連接程序.

-llibrary
制定編譯的時候使用的庫
例子用法
gcc -lcurses hello.c
使用ncurses庫編譯程序

-Ldir
制定編譯的時候,搜索庫的路徑。比如你自己的庫,可以用它制定目錄,不然
編譯器將只在標準庫的目錄找。這個dir就是目錄的名稱。

-O0
-O1
-O2
-O3
編譯器的優化選項的4個級別,-O0表示沒有優化,-O1為缺省值,-O3優化級別最高 
  
-g
只是編譯器,在編譯的時候,產生調試信息。

-gstabs
此選項以stabs格式聲稱調試信息,但是不包括gdb調試信息.

-gstabs+
此選項以stabs格式聲稱調試信息,并且包含僅供gdb使用的額外調試信息.

-ggdb
此選項將盡可能的生成gdb的可以使用的調試信息.
-static
此選項將禁止使用動態庫,所以,編譯出來的東西,一般都很大,也不需要什么
動態連接庫,就可以運行.
-share
此選項將盡量使用動態庫,所以生成文件比較小,但是需要系統由動態庫.
-traditional
試圖讓編譯器支持傳統的C語言特性


T.S Liu 2008-06-02 12:32 發表評論
]]>
天堂久久天堂AV色综合| 亚洲国产精品成人久久| 久久国产免费| 亚洲中文字幕无码久久2020| 久久精品国产久精国产思思| 国产高潮国产高潮久久久91 | 国产免费久久精品丫丫| 日本欧美国产精品第一页久久| 日产精品久久久久久久| 精品久久久噜噜噜久久久| 久久精品国产72国产精福利| 久久久久亚洲AV成人网人人网站| 色综合色天天久久婷婷基地 | 色偷偷久久一区二区三区| 99久久国产免费福利| 久久影院综合精品| 久久香蕉国产线看观看猫咪?v| 精品无码久久久久久午夜| 香蕉aa三级久久毛片| 亚洲国产精品久久久久| 亚洲国产精品久久电影欧美| 久久久久一本毛久久久| 色噜噜狠狠先锋影音久久| 久久AV高清无码| 欧洲成人午夜精品无码区久久 | 久久se精品一区精品二区国产| 久久久无码精品亚洲日韩按摩| 伊人久久五月天| 久久夜色精品国产亚洲av| 狠狠色噜噜狠狠狠狠狠色综合久久| 国产成人久久精品一区二区三区| 久久久免费观成人影院| 国产高潮久久免费观看| 99久久免费国产精品| 亚洲国产二区三区久久| 99久久精品免费观看国产| 久久99国产亚洲高清观看首页| 国产精品久久自在自线观看| 91精品国产色综合久久| 久久久久四虎国产精品| 精品久久久久久无码人妻蜜桃|