ldd可以用來顯示每個程式所使用到的shared library。ldd其實是一個shell script而不是執行檔。
在linux,我們可以將程式編譯成靜態連結或是動態連結,在這以hello.c來解釋。#include
int main(void) {
printf("Hello world!\n");
return 0;
}
用gcc編譯
# gcc hello.c -o hello
則會產生hello的執行檔,而其預設是使用動態連結的方式:
用file指令來檢視其屬性
# file hello
hello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.8, not stripped
用ldd來檢視共用了哪些shared library
# ldd hello
linux-gate.so.1 => (0xb7f6a000)
libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb7dfd000)
/lib/ld-linux.so.2 (0xb7f6b000)
此外,此檔案的大小為
# ls -l hello
-rwxr-xr-x 1 howard howard 6256 2008-09-30 00:00 hello
上述為程式使用動態連結,我們也可以將程式編譯成靜態連結:
# gcc -static hello.c -o hello
用file來檢視,可以看到顯示為靜態連結
# file hello
hello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), statically linked, for GNU/Linux 2.6.8, not stripped
用ldd來檢視,自然沒使用到任何shared library
# ldd hello
not a dynamic executable
再來檢視檔案的大小
# ls -l hello
-rwxr-xr-x 1 howard howard 564881 2008-09-30 00:07 hello
我們可以看到檔案大小為564881 Bytes,相對於之前用動態連結只用了6256 Bytes,足足大上快一百倍。可見使用動態連結能大大節省空間。
2008年9月29日 星期一
ldd
2008年9月28日 星期日
Linux Library
Program library指的就是包含已編譯好的程式碼和資料,可以拿來被其它程式來運作。可以依程式與library結合的時間將library分成三類:
- static library:
- shared library:
- dynamically loaded library:
2008年9月2日 星期二
firefox 3.0.1異常
自從Debian(Lenny)的firefox升級到3.0.1後,開啟firefox時,系統就會出現回報錯誤的視窗。造成這個問題的原因主要是在gcin和firefox相容的問題。目前Lenny的gcin版本停留在1.4.0,只要升級到1.4.2以上的版本便可解決此問題。
2008年7月29日 星期二
通用的編核心方式
之前介紹過如何用Debian的方式來編譯核心,將它變成deb檔。現在要介紹的是用傳統的方法來編譯,適用於各個不同版本的linux下。
下載所需的核心並解壓縮在/usr/src裡
# cd /usr/src
# wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.25.tar.bz2
# tar jxvf linux-2.6.25.tar.bz2
# cd /usr/src linux-2.6.25
# make clean
編輯所要編譯核心,設定是靜態還是動態連結到核心裡。最後會產生一個.config檔
# make menuconfig
開始編譯核心,產生一個壓縮的boot image,如果是x86的電腦,會產生在arch/x86/boot/bzImage
# make bzImage
編譯及安核心模組。模組會被放置在/lib/modules/`uname -r`/這個目錄裡
# make modules
# make modules_install
將產生的boot image複製到/boot,並改名成vmlinuz-2.6.25
# cp arch/x86/boot/bzImage /boot/vmlinuz-2.6.25
更新bootloader,在這,我們是使用grub。
# update-grub
重開機即可。
若在開機的過程發生問題時,可能核心還需要initrd的幫助。
所以,可以利用工具(mkinitramfs來建立initrd檔案
# cd /boot
# mkinitramfs -o 2.6.25-initrd 2.6.25
# update-grub
即完成。
2008年7月24日 星期四
xargs
xargs:將標準輸入之分行字串轉換成指令參數,也就是用來將某個輸出的結果當作另一個輸入的參數。以下面例子來解釋:
例:刪除檔名包含.bak的所有檔案
# find / -name "*.bak" | xargs rm -rf
2008年5月17日 星期六
apt-file
常常用tarball安裝軟體,常會發生少了某些library或套件,在Debian可以利用apt-file來搜尋到需要再安裝哪一個套件。安裝如下:
# apt-get install apt-file
# apt-file update
假如在make出現以下的錯誤訊息
error: gtk/gtk.h: No such file or directory
則可以利用apt-file來找尋套件
# apt-file gtk/gtk.h
如此便可找到所欠缺的套件
2008年5月13日 星期二
mplayer設定
播放avi檔時,發現中文字幕變成亂碼,解決方法如下:
在preferences->font中,選擇一中文字型,如:
/usr/share/fonts/truetype/arphic/uming.ttf
同時encoding選unicode
在preferences->Subtitles & OSD中,encoding設成Big5,即可。
讓畫面能隨視窗大小縮放:
修改~/.mplayer/config檔,在裡面加入下面這一行:
zoom="yes"
2008年5月7日 星期三
背景執行
因為前景只有有一個工作,其它的工作必須於背景執行。主要有兩種方式&以及nohup:
最簡單的方式就是在命令的後面加上&,如:
# command &
此時會回此程序的PID。
另一個方式則是當登出shell時,也能讓程序繼續進行:
# nohup command &
2008年5月5日 星期一
iwlwifi
之前筆電內建的無線網卡 Intel Corporation PRO/Wireless 3945ABG,由於kernel並不支援,所以還要必須額外去編譯模組。在kernel 2.6.23後已經有支援了,所以要啟動無線網卡就更加容易了。當然首先要確定有將此模組編入核心。# apt-get install firmware-iwlwifi
# modprobe iwl3945
可以用iwconfig來看是否成功啟動無線網卡wlan0_rename IEEE 802.11g ESSID: "CS-WLAN"
...
2008年3月11日 星期二
連線服務
觀察目前系統所以啟的連線服務可以用netstat或是nmap軟體來達成。
列出正在Listen的服務
# netstat -utnl
以連線的狀態
# netstat -utn
nmap使用方法
只列出所開啟的TCP port
# nmap localhost
列出TCP/UDP的port
# nmap -sTU localhost
像系統內mysql的服務是開啟的,若要只限於本機可連,可以設於防火牆內
# iptables -A INPUT -i eth0 -p tcp --dport 3306 -j DROP
2008年3月9日 星期日
架設Postfix
# cd /usr/local/src
下載postfix-2.3.3.tar.gz
# tar zxvf postfix-2.3.3.tar.gz
# cd postfix-2.3.3# make
編譯完成之後,先新增postfix所需使用的帳號及群組
# useradd -M -s /sbin/nologin postfix# groupadd postdrop
安裝postfix
# make install
若無意外的話,接下來一直按enter就可以順利安裝完成
啟動Postfix
# postfix start
##ReadMore##
測試是否成功啟動
# telnet localhost 25
Trying 127.0.0.1...Connected to localhost.Escape character is '^]'.220 mail.maruko.cs.nchu.edu.tw ESMTP Postfix
看到以上畫面表示成功啟動
設定postfix
主要設定檔在/etc/postfix/main.cf
若要改成接受所有連線
inet_interfaces = all
設定主機名稱
myhostname = mail.maruko.cs.nchu.edu.tw
而mydomain為依myhosname設定自動設為maruko.cs.nchu.edu.tw
postfix預設只會接收與本機的主機名稱相同的郵件,但因為主機名稱只能設一個,所以可以如下設定
mydestination = $myhostname, localhost.$mydomain, localhost, 其它要收信的郵件位址
設定可轉遞的郵件位址預設只允許本機與同一subnet的IP寄送信件,設定方法如下:設定可轉遞的網段 - mynetworks_style,此參數只能使用三個設定值
subnet:允許同一子網段
class:允許屬於同一個class
host:只允許本機
另一種方法是指定可以用來指定某一小段IP的轉遞郵件 - mynetworks,而mynetworks的優先權大於mynetworks_style
更改重送佇列郵件的間隔時間與佇列郵件的保留時間
queue_run_delay
maximal_queue_lifetime
檢視還未寄出的郵件
# postqueue -p
若要備份postfix,則需備份以下目錄
/etc/postfix
/etc/passwd、/etc/shadow、/etc/group、/etc/gshadow
/var/spool/mail
2008年2月21日 星期四
回復grub
當重灌Windows時,會發現grub不見了,以下為回復的方法。
首先先拿一片Live CD。進入後,開啟終端機執行下列指令:# sudo grub update
接著提示符號會變成grub>
grub> root (hd0,2)
輸入含有/boot目錄的硬碟分割區代號
grub> setup (hd0)
安裝到MBR
2008年2月2日 星期六
update-alternatives
Debian提供了update-alternatives的工具,可以用來管理套件的版本。例如:系統有三套Java的套件GIJ、GCJ和Sun Java,如何能自由且快速的切換不同版本。
首先,先看一下java指令的路徑# which java
/usr/bin/java
# ls -l /usr/bin/java
/usr/bin/java -> /etc/alternatives/java
# ls -l /etc/alternatives/java
/etc/alternatives/java -> /usr/lib/jvm/java-gcj/jre/bin/java
我們可以看到java的指令用一個symbolic link連到/etc/alternatives/java,而/etc/alternatives/java又是一個symbolic link連到/usr/lib/jvm/java-gcj/jre/bin/java。
所以update-alternatives就是將/etc/alternatives/java改掉。# update-alternatives--display java
java - status is auto.
link currently points to /usr/lib/jvm/java-gcj/jre/bin/java
/usr/bin/gij-4.2 - priority 42
slave java.1.gz: /usr/share/man/man1/gij-4.2.1.gz
/usr/lib/jvm/java-gcj/jre/bin/java - priority 1042
/usr/lib/jvm/java-6-sun/jre/bin/java - priority 63
slave java.1.gz: /usr/lib/jvm/java-6-sun-1.6.0.00/jre/man/man1/java.1.gz
Current `best' version is /usr/lib/jvm/java-gcj/jre/bin/java.
可以看到目前系統有gcj和Sun Java,而=由於status是auto,而gcj的優先權最高,所以可以最下面顯示目前最佳的版本是gcj。若要改變成java-6-sun:update-alternatives --config java
即可選擇java-6-sun。
2008年1月28日 星期一
使用Bluetooth
介紹如何用gnome-bluetooth套件,透過bluetooth來傳送檔案。
首先,假設系統已安裝了bluez utilities,且藍芽已經啟動。
安裝gnome-bluetooth套件
# apt-get install gnome-bluetooth
在桌面按右鍵選擇新增啟動圖示
名稱隨便填,如Bluetooth傳送檔案
Command填入gnome-obex-send
圖示隨便選一個喜歡的
之後,若要傳送檔案,則將檔案拖曳至此,即會跳出視窗,來選擇要傳送至哪個裝置。
2008年1月25日 星期五
vi/vim設定Tab鍵空格數
寫程式常用Tab鍵來縮排,讓程式更具可讀性。
然而vi/vim的Tab預設為8個空格,若要改變Tab的空格數,有兩種方法。
第一種:
進入vi/vim後,在Last Line Mode中輸入set tapstop=4
Tab空格數就會變成4,然而只套用於目前設定。
第二種:
將set tapstop=4寫進~/.vimrc裡,則每次開啟vi/vim就會套用這個值。
2008年1月20日 星期日
手動新增使用者
在新增使用者部份,我們可以使用useradd指令來建立,非常方便,但也可以用手動的方式來建立:
假設要建立一個新的使用者,帳號為newuser,群組為newgroup,uid為600,gid為800
1. 先建立newgroup這個群組,所以我們就去修改/etc/group的檔案,在最後一行加上
newgroup:x:800
2. 執行grpconv,這個指令能比對/etc/group和/etc/gshadowt檔案,將/etc/group出現的group卻沒在/etc/gshadow出現的群組對應過去
# grpconv
3. 修改/etc/passwd,來建立新的使用者名稱,在最後一行加上 (家目錄設為/home/newuser shell為bash)
newuser:x:600:800::/home/newuser:/bin/bash
4. 執行pwconv,這個指令用來比對/etc/group和/etc/shadow檔案,將/etc/passwd出現的帳號名稱卻沒在/etc/shadow出現的帳號對應過去
# pwconv
5. 為newuser設定密碼,在此使用passwd指令
# passwd newuser
6. 建立家目錄,將/etc/skel/*複製到我們家目錄裡,/etc/skel/裡包含環境設定檔等,如.bashrc
# cp -a /etc/skel /home/newuser
7. 更改剛才複製過來檔案的擁有者和群組擁有者
# chown -R newuser:newgroup /home/newuser
如此便大功告成!
2008年1月19日 星期六
vi/vim編輯時回到Shell
當我們在用vi/vim編輯檔案時,若暫時需要回到外面的Shell執行一些工作,可以在Last Line Mode下輸入以下指令
:sh
如此,便暫時跳回Shell的畫面,若要返回vi/vim,則執行exit即可。
# exit
簡易的Samba架設
Samba可以讓Windows主機可以用網路芳鄰來存取我們要分享的資料,以下就以Debian為例,快速架設一個Samba server:
先安裝samba
# apt-get install samba
編輯設定檔(/etc/samba/smb.conf)
# vim /etc/samba/smb.conf
任何人都可以存取
workgroup = WORKGROUP # 視Windows群組為何
security = share # 任何人都可以直接存取
guest account = nobody # 使用nobody的帳號
接著設定欲分享的資料夾
[share]
comment = Share # 共享資料的文字說明
path = /home/howard/share # 共享資料的路徑
guest ok = yes # 無需認證(須security = share)
writable = no
share modes = yes
接著,重新執行
# /etc/init.d/samba reload
除了純分享外,也可以設定認證機制
security = user
但要先建立samba的使用者帳號及密碼, 例:
# smbpasswd -a howard
如此便需擁有帳號及密碼才能存取分享的資料。
2008年1月7日 星期一
編譯多個source code
將函式的prototype的宣告以及一些constant的定義寫在另一個header檔是程式常用的技巧。自行定義的header必須以雙引號include進來,如:
#include "selfdefined.h"
至於如何編譯多個source code,以下以GNU C compiler gcc作說明:
假設有以下檔案:main.c selfdefined.c selfdefined.h
# gcc -c main.c selfdefined.c
會產生兩個object file
# gcc -o main main.o selfdefined.o
連結兩個object file產生main的執行檔
如果後來main.c做了更改,我們只須重新編譯main.c即可
# gcc -o main main.c selfdefined.o