這些命令基于Ubuntu16.04系統,其他版本或系統可能微有不同
1.Shell
1.1Shell家族
Shell:命令解析器,根據輸入的命令執行相應命令。
查看當前系統下有哪些shell:
cat /etc/shells
查看當前系統正在使用的shell
echo $SHELL
常見shell:
/bin/sh (已經被bin/bash所取代)
/bin/bash (Linux默認的shell)
/bin/ksh (kornshell這個 shell 可交互式的從終端鍵盤或從一個文件中執行命令)
/bin/tcsh (整合 C Shell ,提供更多的功能)
/bin/csh (已經被tcsh所取代)
/bin/zsh (基于 ksh 發展出來的,功能更強大的shell)
1.2Bash
bash是一個為GNU計劃編寫的Unix shell。它的名字是一系列縮寫:Bourne-Again Shell這是關于Bourne shell(sh)的一個雙關語(Bourne again/born again)
bash是許多Linux平臺的內定shell,事實上還有許多傳統Unix上用的shell,像tcsh、csh、ash、bsh、ksh等等,shell script大致都類同,當您學會一種shell以后,其他的shell會很快就上手,大多數的時候,一個shell script通常可以在很多種shell上使用。
bash是大多數Linux系統以及mac OS 默認的shell,它能運行于大多數Unix風格的操作系統之上,甚至被移植到了Microsoft Windows上的Cygwin系統中,以實現windows的POSIX虛擬借口。此外,它也被DJGPP項目移植到了MS-DOS上。
1.3命令和路徑補齊
在bash下敲命令時,tab鍵可以補全已經敲了一部分的文件名和目錄名。如果是Ubuntu系統,系統默認啟用了bash completion,還可以補全命令的某些參數、Makefile目標等等。如果是Debian系統,可以用以下命令啟用bash completion:
$source /etc/bash_completion
建議將這一行加入~/.bashrc啟動腳本中。比如使用sudo后面接命令,如果沒有bash completion則只有sudo可以補全,后面的命令不能補全。如果啟動了bash completion,則后面的命令,包括命令的某些參數(比如aptitude命令的install)都可以補全了。
比如在主目錄下要列出桌面目錄的內容,輸入(不回車)
$ls De
然后敲tab鍵,如果以De開頭的文件或文件夾只有Desktop一個,就自動補全為
$ls Desktop
否則,再敲一次tab鍵,將會把所有以De開頭的文件或文件夾列在下面供你選擇(在這里我們手動創建另外一個以De開頭的文件)
$touch Death
$ls De
Death Desktop/
你可以再補敲一個s再tab,這次Desktop就會補全到命令后面了。
有的人是DOS時代過來的,留下一個很不好的習慣就是在找一個文件時反復的cd、ls、cd、ls…等找到了要找的文件時再想回到先前的目錄,已經不記得先前是從哪個目錄轉到這里來的了。
我們從上面可以看出,tab補全本身就具備了ls的功能,上面的tab補全相當于ls –Fd De*命令。所以我們完全不必反復的cd到別的目錄然后ls去找文件,多按幾次tab就可以一條命令完成了,這樣的好處是我們的當前目錄不用變,不需要找完了文件再cd回來,同時省去了大量的按鍵次數。更重要的是,自動補全同時兼具了檢查拼寫錯誤的功能,如果前面幾個字母拼寫錯了,就補全不出東西來,用戶就知道拼寫錯了,如果前面幾個字母沒有品寫錯,那么由系統補全出來的文件名肯定也不會有拼寫錯誤,避免了用戶在敲很長的文件名時易犯的拼寫錯誤。
1.4歷史記錄
歷史記錄是另外一個非常方便的功能。按上下移動光標鍵(或者ctrl-p、ctrl-n)可以一條一條瀏覽以前輸過的命令。如果有需要重復輸入的命令就不用輸第二次了。如果你能記住以前輸過的某條命令中的某個關鍵字,可以按ctrl–r,然后輸入關鍵字,隨著你每輸入一個字母,bash會做增量式(increasingly)查找,也可以反復按ctrl-r或ctrl-s向前向后查找。如果找到了,按左右移動光標鍵或home鍵(ctrl-a)或end鍵(ctrl-e)將該命令帶回提示符下進一步修改,或者直接按enter鍵原封不動的執行該命令
1.5主鍵盤快捷鍵
bash的快捷鍵和emacs保持一致,用慣其中之一再用另一個程序會很順手的。請記住一條原則:盡量使用主鍵盤快捷鍵而不使用移動光標鍵和編輯鍵。因為手不必離開主鍵盤是效率最高的,這樣在你一生之中所節省的來回移動手的時間絕對可以用星期來計算,是絕對值得你花十分鐘的時間記住這些快捷鍵的。
功能 | 快捷鍵 | 助記 |
---|---|---|
上 | Ctrl-p | previous |
下 | Ctrl-n | next |
左 | Ctrl-b | backward |
右 | Ctrl-f | forward |
Del | Ctrl-d | delete光標后面 |
Home | Ctrl-a | the first letter |
End | Ctrl-e | end |
Backspace | Backspace | delete光標前面 |
2.目錄和文件
2.1類Unix系統目錄結構
Linux系統,不像現在Windows版本這樣,硬盤存在各個盤符的情況,沒有盤符的這個概念,只有一個根目錄/,所有文件都在它下面
/ 根目錄
|--- bin //系統可執行程序,如命令
|--- boot //內核和啟動程序,所有和啟動相關的文件都保存在這里
|--- grub //引導器相關文件
|--- dev //設備文件
|--- etc //系統軟件的啟動和配置文件,系統在啟動過程中需要讀取的文件都在這個目錄。如LILO參數、用戶賬戶和密碼。
|--- media //掛載媒體設備,如光驅、U盤等
|--- mnt //目錄是讓用戶臨時掛載別的文件系統,如掛載windows下的某個分區,ubuntu默認還是掛載在/media目錄
|--- opt //可選的應用軟件包(很少使用)
|--- proc //這個目錄是系統內存的映射,我們可以直接訪問這個目錄來獲取系統信息。也就是說,這個目錄的內容不在硬盤上而是在內存里。
|--- sbin //管理員系統程序
|--- selinux
|--- srv
|--- sys //udev用到的設備目錄樹,/sys反映你機器當前所接的設備
|--- tmp //臨時文件夾
|--- usr //這是個最龐大的目錄,我們要用到的很多應用程序和文件幾乎都存放在這個目錄下。
|--- bin //應用程序
|--- game //游戲程序
|--- include
|--- lib //應用程序的庫文件
|--- lib64
|--- local //包含用戶程序等
|--- sbin //管理員應用程序
2.2用戶目錄
位于/home/user,稱之為用戶工作目錄或家目錄,表示方式:
/home/user
~
2.3相對路徑與絕對路徑
絕對路徑
從/(根目錄)開始描述的路徑為絕對路徑,如:
cd /home
ls /usr
相對路徑
從當前位置開始描述的路徑為相對路徑,如:
cd ../../
ls abc/def
.
和..
:
每個目錄下都有.和.
.表示當前目錄
..表示上一級目錄,即父目錄
根目錄下的.和..都表示當前目錄
Linux
的.和..和Windows
系統的文件目錄大體相同的意思.
2.4目錄內容
ls
ls [OPTION]...[FILE]…
ls是英文單詞list的簡寫,其功能為列出目錄的內容。這是用戶最常用的一個命令,因為用戶需要不時的查看某個目錄的內容。該命令類似于DOS下的dir命令。對于每個目錄,該命令將列出其中的所有子目錄與文件。對于每個文件,ls將輸出其文件名以及所要求的其他信息。默認情況下,輸出條目按字母順序排序。當未給出目錄名或是文件名時,就顯示當前目錄的信息。
主要的OPTION有:
-a 列出隱藏文件,文件中以”.”開頭的均為隱藏文件,如:~/.bashrc
-l 列出文件的詳細信息
-R 連同子目錄中的內容一起列出
用ls –l命令顯示的信息中,開頭是由10個字符構成的字符串,其中第一個字符表示文件類型,它可以是下述類型之一:
- 普通文件
d 目錄
l 符號鏈接
b 塊設備文件
c 字符設備文件
s socket文件,網絡套接字
p 管道
后面的9個字符表示文件的訪問權限,分為3組,每組3位。第一組表示文件屬主的權限,第二組表示同組用戶的權限,第三組表示其他用戶的權限。每一組的三個字符分別表示對文件的讀、寫和執行權限。各權限如下所示:
r 讀
w 寫
x 可執行。對于目錄,表示進入權限。
s 當文件被執行時,把該文件的UID或6ID賦予執行進程的UID(用戶ID)或6ID(組ID)。
t 設置標志位(sticky bit)。如果擁有者或文件屬主刪除。如果是由sticky bit的可執行文件,在該文件執行后,指向其正文段的指針仍留在內存。這樣再次執行它時,系統就能更快的裝入該文件。
- 沒有相應位置的權限
訪問權限后面的數字表示與該文件共享inode的文件總數,即便鏈接數(參見下面ln命令)。
2.5切換目錄
cd
change dir 改變當前所在路徑
cd ~
cd dir1/dir2
cd ..
2.6查看命令路徑
which
查看指定命令所在路徑
which ls
2.7查看路徑
pwd
Linux中用 pwd命令來查看"當前工作目錄"的完整路徑。簡單得說,每當你在終端進行操作時,你都會有一個當前工作目錄。在不確定當前位置時,就會使用pwd來判定當前目錄在文件系統內的確切位置
pwd
2.8創建目錄
mkdir [OPTION] DIRECTORY ....
創建目錄DIRECTORY,可以一次創建多個。
要創建文件夾或目錄的用戶必須對所創建的文件夾的父文件夾具有寫權限。并且,所創建的文件夾(目錄)不能與其父目錄(即父文件夾)中的文件夾重名,即同一個目錄下不能有同名的(區分大小寫)。
-m, --mode=模式,設定權限<模式> (類似 chmod),而不是 rwxrwxrwx 減 umask
-p, --parents 可以是一個路徑名稱。此時若路徑中的某些目錄尚不存在,加上此選項后,系統將自動建立好那些尚不存在的目錄,即一次可以建立多個目錄;
-v, --verbose 每次創建新目錄都顯示信息
例
mkdir test
mkdir –p test1/test2
2.9刪除空目錄
rmdir [OPTION]... directory
刪除空目錄,可以一次刪除多個。
OPTION如果是-p,表示可以連同空的父目錄一起刪除。
mkdir和rmdir的用法舉例:
$ mkdir a
$ mkdir a/b
$ ls a
b
$ rmdir a/b
$ ls a
$ rmdir a
$ mkdir a/b
mkdir:cannot create directory ‘a/b’:No such file or directory
$ mkdir –p a/b
$ rmdir –p a/b
2.10修改文件時間
touch [OPTION] ..... FILE.....
將每個文件的訪問及修改時間都更新為目前的時間。
如果文件不存在,則創建一個字節數為0的文件。
2.11刪除文件/目錄
rm
刪除文件:
rm file
刪除目錄:
rm dir -rf
2.12重命名/移動文件
mv
重命名:
mv file1 file2
移動文件:
mv file ~/
2.13拷貝文件/目錄
cp
拷貝文件:
Cp file1 file2
Cp file1 dir/
Cp file1 ../
拷貝目錄:
Cp dir1 dir2 –r
Cp dir1 ~/ -r
2.14查看文件內容
cat
查看文件里內容,輸出到終端,如果cat時沒跟文件名,則讀標準輸入,遇到\n后,輸出到標準輸出,終端下輸入ctrl -d表示結束。
2.15查看文本文件內容
more [OPTION] FILE ....
查看文本文件內容,屏幕顯示完一屏就等待用戶按下任意鍵再滾動到下一屏,如果中途不想繼續看下去了,可以按ctrl c或q終止顯示。
less [OPTION] FILE ....
查看文本文件內容,屏幕顯示完一屏就等待用戶按鍵,用戶可以向上或向下查看,如果中途不想繼續看下去,可以按ctrl c或q終止顯示。
2.16顯示文件的前面/最后幾行
head [OPTION] ..... FILE....
顯示指定文件的前面幾行。如果沒有指定文件,將從標準輸入(鍵盤)上讀取。如果沒有指定要顯示的行數,則默認顯示前10行。如果要顯示文件的前5行。
head -5 file1
tail [OPTION].... FILE ....
顯示文件的最后幾行。若沒有指定顯示的行或字符數,則默認顯示末尾10行。如果要顯示文件末5行。
tail -5 file1
2.17鏈接
ln
鏈接有兩種,一種被成為硬鏈接(Hard Link),另一種被稱為符號鏈接(Symbolic Link),建立硬鏈接時,鏈接文件和鏈接文件必須位于同一文件系統中,并且不能建立指向目錄的硬鏈接。而對符號鏈接,則不存在這個問題。默認情況下,ln產生硬鏈接。如果給ln命令加上-s選項,則建立符號鏈接,則建立符號鏈接。
例:
//硬鏈接:
touch hello
ln hello word_h
//軟鏈接:
Ln –s hello word_s
2.18樹形顯示目錄文件
tree
這個命令需要下載安裝,ubuntu下
//安裝命令
sudo apt-get install tree
按結構樹的形狀顯示目錄和文件。
2.19計算文件
wc
利用wc指令我們可以計算文件的byte數,字數,或是列數,若不指定文件名稱,或是所給予的文件名為"-",則wc指令會從標準輸入設備讀取數據。
-c 或 –bytes 或 –chars 只顯示bytes數。
-l 或 –lines 只顯示列數。
-w 或 –words 只顯示字數。
例:
wc -l ./*
2.20數據顯示格式
od
od -tcx file1
-t 指定數據的顯示格式,主要參數有:
c ASCII字符或反斜杠序列
d [SIZE] 有符號十進制數,每個整數SIZE字節。
f [SIZE] 浮點數,每個整數SIZE字節。
o [SIZE] 八進制(系統默認值為02),每個整數SIZE字節。
u [SIZE] 無符號十進制數,每個整數SIZE字節。
x [SIZE] 十六進制數,每個整數SIZE字節。
2.21查看目錄大小
du
查看某個目錄的大小:
例:
//Juinjonn為用戶目錄
以M(兆)為單位。
du -hm /home/Juinjonn/test
-----------------------------
以B為單位
du –hb ./home/Juinjonn/test
-----------------------------
以K為單位,4K的整數倍
du –hk ./home/Juinjonn/test
-----------------------------
2.22查看磁盤使用情況
df
df –block-size=GB
df –block-size=MB
3.文件屬性和用戶用戶組
3.1查看當前登錄用戶
whoami
3.2更改文件目錄訪問權限
chmod
文字設定法
chmod [who] [+|-|=] [mode]文件名
操作對象who可是下述子母鐘的任一個或者他們的組合:
u 表示”用戶(user)”,即文件或目錄的所有者。
g 表示”同組(group)用戶”,即與文件屬主有相同組ID的所有用戶。
o 表示”其他(others)用戶”。
a 表示”所有(all)用戶”。它時系統默認值。
操作符號可以是:
+ 添加某個權限。
- 取消某個權限。
= 賦予給定權限并取消其他所有權限(如果有的話)。
設置mode所表示的權限可以用下述字母的任意組合:
r 可讀。
w 可寫。
x 可執行
數字設定法
chmod [mode] 文件名
我們必須首先了解用數字表示的屬性的含義:
0表示沒有權限,
1表示可執行權限,
2表示可寫權限,
4 表示可讀權限,
然后將其相加。所以數字屬性的格式應為3個從0到7的八進制,其順序是(u)(g)(o)。
例如,如果想讓某個文件的屬性有"讀/寫"兩種權限,需要把4(可讀)+2(可寫)=6(讀/寫)。
比如設置一個文件允許所有用戶可寫
chmod a+w file1
設置一個文件允許所有用戶可讀,可寫,不可執行
chmod 666 file1
user group other
r w x r w x r w x
4 2 1 4 2 1 4 2 1
5 6 3
3.3更改文件目錄的用戶或組
chown
chown [OPTION]… [OWNER:GROUP] FILE…
chown [OPTION]… -reference=RFILE FILE…
更改某個文件或目錄的屬主和屬組。這個命令也很常用。例如root用戶把自己的一個文件拷貝給用戶A,為了讓用戶A能夠存取這個文件,root用戶應該把這個文件的屬主設為A,否則,用戶A無法存取這個文件。
OPTION的主要參數:
-R 遞歸式的改變指定目錄及其下的所有子目錄和文件的擁有者。
-v 顯示chown命令所做的工作。
比如把一個文件改為Juinjonn用戶和nogroup用戶組所有:
sudo chown Juinjonn:nogroup file1
注意:
chown 需要特權用戶才能執行
一個文件的owner和owning group 是沒有關聯的。一個文件屬于用戶A,也屬于用戶組B,并不表示用戶A屬于用戶組B。
3.4改變文件的用戶組
chgrp
chgrp [OPTION]… GROUP FILE …
chgrp [OPTION]… -reference = RFILE FILE…
該命令改變(指定)指定文件所屬的用戶組。其中group可以是用戶組ID,也可以是/etc/group文件中用戶組的組名。文件名是以空格分開的要改變屬組的文件列表,支持通賠符。如果用戶不是該文件的屬主或超級用戶,則不能改變該文件的組。
OPTION的主要參數:
-R 遞歸式的改變指定目錄及其下的所有子目錄和文件的屬組
4.查找與檢索
4.1文件名查找
find
根據文件名查找
find [OPTION] path… [expression]
在目錄中搜索文件,path指定目錄路徑,系統從這里開始沿著目錄樹向下查找文件。它是一個路徑列表,相互用空格分離,如果不寫path,那么默認為當前目錄。Expression是find命令接受的表達式,find命令的所有操作都是針對表達式的。
一條最常用的find命令------在當前目錄及子目錄下查找所有以file開頭的文件名。
find .-name ‘file*’
find /-name ‘vimrc’
find ~-name ‘*.c’
4.2內容檢索
grep
grep [options] PATTERM [FILE…]
在指定文件中搜索特定的內容,并將含有這些內容的行輸出到標準輸出。若不指定文件名,則從標準輸入讀取。
[options]部分包含的主要參數:
-c : 只輸出匹配行的計數。
-i: 不區分大小寫(只適用于單字符)。
-h : 查詢多文件時不顯示文件名。
-l : 查詢多文件時只輸出包含匹配字符的文件名。
-n: 顯示匹配行及行號。
-s: 不顯示不存在或無匹配文本的錯誤信息。
-v:顯示不包含匹配文本的所有行。
-R:連同子目錄中所有文件一起查找。
比如到系統文件目錄下查找所有包含printf的文件
grep ‘printf’ /usr/include -R
5.安裝卸載文件
5.1apt - get
更新源服務器列表
sudo vi /etc/apt/sources.list
更新完服務器列表后需要更新下源:
sudo apt-get update 更新源
sudo apt-get install package 安裝包
sudo apt-get remove package 刪除包
sudo apt-cache search package 搜索軟件包
sudo apt-cache show package 獲取包的相關信息,如說明、大小、版本等。
sudo apt-get install package ---reinstall 重新安裝包
sudo apt-get –f install 修復安裝
sudo apt-get remove package –purge 刪除包,包括配置文件等
sudo apt-get build-dep package 安裝相關的編譯環境。
sudo apt-get upgrade 更新已安裝的包
sudo apt-get dist-upgrade 升級系統
sudo apt-cache depends package 了解使用該包依賴哪些包
sudo apt-cache rdepends package 查看該包被哪些包依賴
sudo apt-get source package 下載該包的源代碼
sudo apt-get clean && sudo apt-get autoclean 清理無用的包
sudo apt-get check 檢查是否有損壞的依賴
5.2deb包安裝
安裝deb軟件包命令: sudo dpkg –I XXX.deb
刪除軟件包命令: sudo dpkg –r XXX.deb
連同配置文件一起刪除命令: sudo dpkg –r –purge XXX.deb
查看軟件包信息命令: sudo dpkg –info XXX.deb
查看文件拷貝詳情命令: sudo dpkg –L xxx.deb
查看系統中已安裝軟件包信息命令: sudo dpkg -l
重新配置軟件包命令: sudo dpkg –reconfigure xxx
5.3源碼安裝
解壓縮源代碼包
cd dir
./configure
檢測文件是否確實,創建Makefile,檢測編譯環境make
編譯源碼,生成庫和可執行程序sudo make install
把庫和可執行程序,安裝到系統路徑下
6.磁盤管理
6.1mount
命令格式:
mount [-t vfstype] –o options device dir
其中:
-t vfstype 指定文件系統的類型,通常不必指定。mount會自動選擇正確的類型。常用類型有:
光盤或光盤鏡像:iso9660
DOS fat16文件系統:msdos
Windows 9x fat32文件系統:vfat
Windows NT ntfs文件系統:ntfs
mount windows文件網絡共享:smbfs
UNIX(LINUX) 文件網絡共享:nfs
-o options 主要用來描述設備或檔案的掛接方式。常用的參數有:
loop:用來把一個文件當成硬盤分區掛接上系統
ro:采用只讀方式掛接設備
rw:采用讀寫方式掛接設備
iocharset:指定訪問文件系統所用字符集
device:要掛接(mount)的設備
dir設備在系統上的掛接點(mount point)。
6.2卸載
卸載命令umount
sudo umount 掛載點
6.3拷貝
dd
例:拷貝光碟(注意,你的光碟是標準的iso9660格式才可以這么做)
dd if=/dev/cdrom of=cdrom.iso
例2:將文件sfile拷貝到文件dfile中。
dd if=sfile of=dfile
例3:創建一個100M的空文件
dd if=/dev/zero of=hello.txt bs=100M count =1
/dev/null,外號叫無底洞,你可以向它輸出任何數據,它通吃,并且不會撐著!
/dev/zero,是一個輸入設備,你可你用它來初始化文件,從里面獨處來的數據都是0.
7.壓縮包管理
7.1tar
tar [主選項+輔選項] 文件或者目錄
tar可以為文件和目錄創建檔案。利用tar命令用戶可以為某一特定文件創建檔案(備份文件),也可以在檔案中改變文件,或者向檔案中加入新的文件。使用該命令時,主選項是必須要有的,輔選項是輔助使用的,可以選用。
主選項包括:
c 創建新的檔案文件。如果用戶想備份一個目錄或是一些文件,就要選擇這個選項。
r 把要存檔的文件追加到檔案文件的末尾。
t 列出檔案文件的內容,查看已經備份了哪些文件。
u 更新文件。用新增的文件取代原備份文件,如果在備份文件中找不到要更新的文件,則把它追加到備份文件的最后。
x 從檔案文件中釋放文件。(常用)
輔選項包括:
f 使用檔案文件或設備,這個選項通常是必選的。(常用)
k 保存已經存在的文件。
m 在還原文件時,把所有文件的修改時間設定為現在。
M 創建多卷的檔案文件,以便在幾個磁盤中存放。
v 詳細報告tar處理的文件信息。如無此選項,tar不報告文件信息。(信息)
w 每一步都要求確認。
z 用gzip來壓縮/解壓縮文件,加上該選項后可以將檔案文件進行壓縮,但還原時也一定要使用該選項進行解壓縮。(常用)
j 用bzip2來壓縮/解壓縮文件,加上該選項后可以將檔案文件進行壓縮,但還原時也一定要使用該選項進行解壓縮。(常用)
要將文件備份到一個特定的設備,只需要把設備名作為備份文件名。
打包:
tar cvf dir.tar dir
tar xvf dir.tar dir
打gz壓縮包:
tar zcvf dir.tar.gz dir
tar zxvf dir.tar.gz
打bz2壓縮包:
tar jcvf dir.tar.bz2 dir
tar jxvf dir.tar.bz2
指定目錄解壓縮:
tar zxvf dir.tar.gz –C ~/test
7.2rar
打包:把dir壓縮成newdir.rar
rar a –r newdir dir
解包:把newdir.rar解壓縮到當前目錄
unrar x newdir.rar
7.3zip
打包:
zip –r dir.zip dir
解包:
unzip dir.zip
8.進程管理
8.1查看當前在線用戶
**who **
查看當前在線上的用戶情況。所有的選項都是可選的,不使用任何選項時,who命令將顯示以下三項內容:
login name:登錄用戶名;
terminal line:使用終端設備;
login time:登錄到系統時間;
Juinjonn@ubuntu:~/demo$ who –uH
名稱 線路 時間 空閑 進程號 備注
Juinjonn tty2 2016-05-12 09:35 . 6798
8.2監控后臺進程
ps [選項]
ps命令用于監控后臺進程的工作情況,因為后臺進程是不和屏幕鍵盤這些標準輸入/輸出設備進行通信的,所以如果需要檢測其情況,便可以使用ps命令了。選項部分如下:
-e 顯示所有進程
-f 全格式
-h 不顯示標題
-l 長格式
-w 寬輸出。
a 顯示終端上的所有進程,包括其他用戶的進程。
r 只顯示正在運行的進程。
x 顯示沒有控制終端的進程。
這個命令參數有很多,但一般的用戶只需掌握一些最常用的命令參數就可以了。最常用的三個參數是u、a、x,我們首先以root身份登錄系統,查看當前進程狀況。
Juinjonn@ubuntu:~$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 3672 2008 ? Ss 08:46 0:01 /sbin/init
Juinjonn@ubuntu:~$ ps ajx
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
4592 6948 6948 4592 pts/3 6948 R+ 1000 0:00 ps ajx
Juinjonn@ubuntu:~$ ps –Lf 2423
UID PID PPID LWP C NLMP STIME TTY STAT TIME CMD
1000 2423 2282 2423 0 4 08:46 ? Ssl 0:00 gnome-session—session=ubuntu
1000 2423 2282 2465 0 4 08:46 ? Ssl 0:00 gnome-session—session=ubuntu
1000 2423 2282 2466 0 4 08:46 ? Ssl 0:00 gnome-session—session=ubuntu
1000 2423 2282 2468 0 4 08:46 ? Ssl 0:00 gnome-session—session=ubuntu
Head 標頭:
USER 用戶名
UID 用戶ID(User ID)
PID 進程ID(Process ID)
PPID 父進程的進程ID(Parent Process ID)
SID 會話ID(Session ID)
%CPU 進程的CPU占用率
%MEM 進程的內存占用率
VSZ 進程所使用的虛存的大小(Virtual Size)
RSS 進程使用的駐留集大小或者是實際內存的大小,kbytes字節
TTY 與進程關聯的終端(tty)
STAT 進程的狀態:進程狀態使用字符表示的(STAT的狀態碼)
R 運行 Runnable(on run queue) 正在運行或在運行隊列中等待.
S 睡眠 Sleeping 休眠中,受阻,在等待某個條件的形成或接受到信號
I 空閑 Idle
Z 僵死 Zombie(a defunct process) 進程已終止,但進程描述符存在,直到父進程調用wait4()系統調用后釋放。
D 不可中斷 Uninterruptible sleep (ususally IO) 收到信號不喚醒和不可運行,進程必須等待直到有中斷發生。
T 停止 Terminate 進程收到SIGSTOP ,SIGSTP,SIGTIN,SIGTOU信號后停止運行。
P 等待交換頁
W 無駐留頁 has no resident pages 沒有足夠的記憶體分頁可分配
X 死掉的進程
< 高優先級進程 高優先序的進程
N 低優先級進程 低優先序的進程
L 內存鎖頁 Lock 有記憶體分頁分配并縮在記憶體內
s 進程的領導者(在它之下有子進程)
l 多進程的(使用 CLONE_THREAD,類似 NPTL pthreads)
+ 位于后臺的進程組
START 進程啟動時間和日期
TIME 進程使用的總CPU時間
COMMAND 正在執行的命令行命令
NI 優先級(Nice)
PRI 進程優先級編號(Priority)
WCHAN 進程正在睡眠的內核函數名稱;該函數的名稱是從/root/system.map文件中獲得的。
FLAGS 與進程相關的數字標識。
8.3顯示后臺作業
jobs
用來顯示當前shell下正在運行哪些作業(即后臺作業)。
cat
(按下ctrl – z 掛起當前進程)
[1]+ Stopped cat
cat
(按下ctrl – z 掛起當前進程)
[1]+ Stopped cat
$ jobs
[1]- Stopped cat
[2]+ Stopped cat
第一列方括號中的數字表示作業序號,它是由當前運行的shell分配的,而不是由操作系統統一分配的。在當前shell環境下,第一后臺作業的作業號為1,第二作業的作業號為2,等等。第二列中的“+”號表示相應作業的優先級比“-”號對應作業的優先級高。第三列表明作業狀態,是否為運行、中斷、等待輸入或停止等。最后列出的是創建當前這個作業所對應的命令行。
8.4后臺/掛起作業移到前臺運作
fg [job...]
把指定的后臺作業或掛起作業移到前臺運行。參數job是一個或多個進程的PID,或者是命名名稱,或者是作業號(作業號前面要帶一個%號)。
通常在shell中輸入命令啟動進程后,如果該進程需要與用戶交互,那么此后用戶的鍵盤輸入都被該進程讀取,直到該進程退出后才出現shell提示符$,這種進程為前臺進程。
如果在命令行的末尾加上&字符,則shell為這個命令創建一個后臺進程,它雖然也可以輸出到屏幕,但是不能讀取鍵盤輸入,不管執行命令的進程有沒有退出都立刻回到shell提示符接受下一條命令的輸入。如果該進程也需要讀取鍵盤輸入,則被掛起等待直到用戶用fg命令把它變成前臺進程。如果一個命令需要較長的處理時間并且不需要與用戶交互,就適合把它放在后臺執行。
8.5掛起進程后臺執行
把被掛起的進程提到后臺執行。其中,job是一個或多個進程的PID、命令名稱或者作業號,在參數前要帶%號。
cat
(按下ctrl-z掛起當前進程)
[1]+ Stopped cat
bg %1
[1]+ cat &
(再回車一次)
[1]+ Stopped cat
fg %1
cat
(按ctrl-d輸入文件結束符)
8.6進程發送信號
kill
向指定進程發送信號
Kill [-signal | -s signal ] pid…
查看信號編號
kill –l [signal]
給一個進程發信號,或終止一個進程的運行。
cat
(按ctrl-z掛起當前進程)
[1]+ Stopped cat
ps
PID TTY TIME CMD
5819 pts/1 00:00:00 bash
5893 pts/1 00:00:00 cat
5894 pts/1 00:00:00 ps
$kill -SIGKILL 5893
$(再次按回車鍵)
[1]+ killed cat
Kill命令如果不帶參數而直接跟pid,就是發給該進程SIGTERM信號,大部分進程收到該信號就會終止。但是被掛起的進程不能處理信號,所以必須發SIGKILL信號,由系統強制終止進程。
8.7查看當前進程環境變量
env
env
vim ~/.bashrc
配置當前用戶環境變量
vim /etc/profile
配置系統環境變量,配置時需要有root權限。
export PATH=$PATH:新路徑
9.用戶管理
9.1創建用戶
sudo useradd –s /bin/bash –g Juinjonn –d /home/Juinjonn –m Juinjonn
sudo useradd –s /bin/sh –g group –G adm,root pzh
此命令新建了一個用戶pzh,該用戶的登錄shell是/bin/sh,他屬于group用戶組,同時又屬于adm和root用戶組,其中group用戶組是其主組。
-s 指定新用戶登錄時shell類型
-g 指定所屬組,改組必須已經存在
-G 指定附屬組,改組必須已經存在
-g 用戶家目錄
-m 用戶家目錄不存在時,自動創建該目錄
9.2設置用戶組
sudo groupadd Juinjonn
9.3設置密碼
sudo passwd Juinjonn
9.4切換用戶
su 用戶名
//Juinjonn是用戶名
su Juinjonn
9.5root用戶
變成root用戶
sudo su
設置root密碼
passwd
9.6刪除用戶
userdel [選項] [用戶名]
常用的選項是-r,他的作用是把用戶的主目錄一起刪除。例如:
sudo userdel –r Juinjonn
此命令刪除用戶Juinjonn在系統文件(主要是/etc/passwd,/etc/shadow,/etc/group等)中的記錄,同時刪除用戶的主目錄。
10.網絡管理
10.1ifconfig
1. 查看網卡信息 ifconfig
2. 關閉網卡 sudo ifconfig ens33 down
3. 開啟網卡ens33 sudo ifconfig ens33 up
4. 給網卡ens33配置臨時IP sudo ifconfig ens33 IP
10.2ping
ping [選項] 主機名/IP地址
查看網絡上的主機是否在工作。它向該主機發送ICMP ECHO_REQUEST包。有時我們想從網絡上的某臺主機上下載文件,可是又不知道那臺主機是否開著,就需要使用ping命令查看。
命令中個選項的含義如下:
-c 數目,在發送指定數目的包后停止。
-d 設定SO_DEBUG的選項
-f 大量且快速的送網絡封包給一臺機器,看它的回應。
-I 秒數 設定間隔幾秒送一個網絡封包給一臺機器,預設值是一秒送一次。
-l 次數 在指定次數內,以最快的方式送封包數據到指定機器(只有超級用戶可以使用此選項)。
-q 不顯示任何傳送封包的信息,只顯示最后的結果。
-r 不經由網關而直接發送封包到一臺機器,通常是查看本機的網絡接口是否有問題。
-s 字節數 指定發送的數據字節數,預設值是56,加上8字節的ICMP頭,一共是64ICMP數據字節。
10.3netstat
netstat [選項]
顯示網絡連接、路由表和網絡接口信息,可以讓用戶得知目前都有哪些網絡連接正在運作。命令中各選項的含義如下:
-a 顯示所有socket,包括正在監聽的。
-c 每隔1秒就重新顯示一遍,直到用戶中斷它。
-i 顯示所有網絡接口的信息,格式同“ifconfig -e”。
-n 以網絡IP地址代替名稱,顯示出網絡連接情形。
-r 顯示核心路由表,格式同“route -e”。
-t 顯示TCP協議的連接情況。
-u 顯示UDP協議的連接情況。
-v 顯示正在進行的工作
10.4nslookup
nslookup name
查詢一臺機器的IP地址和其對應的域名。它通常需要一臺域名服務器來提供域名服務。
如果用戶已經設置好域名服務器,就可以用這個命令查看不同主機的IP地址對應的域名。
不帶參數使用nslookup命令時,出現提示符“>”,在后面輸入要查詢的IP地址或域名并回車即可。如果要退出該命令,輸入exit并回車即可。
//例如:
Juinjonn@Juinjonn-virtual-machine:~$ nslookup
> www.Juinjonnsot.cn
Server: 127.0.1.1
Address: 127.0.1.1#53
Non-authoritative answer:
Name: www.Juinjonnsot.cn
Address: 202.111.54.183
10.5finger
finger [-lmsp] user [user@host…]
查詢用戶的信息,通常會顯示系統中某個用戶的用戶名、主目錄、停滯時間、登錄時間、登錄shell等信息。如果要查詢遠程機上的用戶信息,需要在用戶名后面接“@主機名”,采用[用戶名@主機名]的格式,不過要查詢的網絡主機需要運行finger守護進程。命令中各選項的含義如下:
-s 顯示用戶的注冊名、實際姓名、終端名稱、寫燭臺、停滯時間、登錄時間等信息。
-l 除了用-s選項顯示的信息外,還顯示用戶主目錄、登錄shell、郵件狀態等信息,以及用戶主目錄下的.plan、.project和.forward文件的內容。
-p 除了不顯示.plan文件和.project文件以外,與-1選項相同。
Juinjonn@Juinjonn-virtual-machine:~$ finger Juinjonn
Login: Juinjonn Name: Juinjonn
Directory: /home/Juinjonn Shell: /bin/bash
On since Thu Jun 2 10:28 (CST) on tty7 from :0
6 minutes 56 seconds idle
No mail.
No Plan.
11.常用服務器構建
11.1ftp
11.1.1ftp服務器
- 安裝vsftpd服務器
sudo apt-get install vsftpd
- 配置vsftpd.conf文件
sudo vi /etc/vsftpd.conf
添加下面設置
anonymous_enable=YES
anon_root=/home/colin/ftp
no_anon_password=YES
write_enable=YES
anon_upload_enable=YES
anon_mkdir_write_enable=YES
- 重啟服務器,重新加載.etc.vsftpd.conf配置文件
sudo /etc/init.d/vsftpd restart
- 進入你的/home/colin/ftp目錄下創建一個空目錄,供用戶上傳
cd !/ftp
mkdir anonymous
chmod 777 anonymous
- 測試上傳功能,登錄ftp服務器,進入到anonymous目錄
ftp IP
cd anonymous
- 上傳命令,可以把你當前目錄下的文件上傳到ftp服務器的anonymous目錄
put somefile
11.1.2ftp客戶端
ubuntu 默認已經安裝ftp客戶端
11.1.3lftp客戶端
lftp也是一種ftp客戶程序。它是以文本方式操作的,但是比起圖形界面更為方便。Lftp幾乎具有bash的所有方便功能,tab補全,bookmark,queue,后臺下載等可以得到支持。用法與ftp類似,主要的指令如下:
put 上傳文件
mput 上傳多個文件
get 下載文件
mget 下載多個文件
mirror 下載整個目錄及其子目錄
mirror –R 上傳整個目錄及其子目錄
lcommand 調用本地shell執行命令command
注意,有的發行版可能缺省沒有安裝lftp工具,需要用戶自己安裝。如果是Debian或Ubuntu系統,則安裝lftp軟件包。
sudo apt-get install lftp
11.2nfs
- 安裝nfs服務器
sudo apt-get install nfs-kernel-server
- 設置/etc/exports配置文件
sudo vi /etc/exports
添加這行配置
/home/用戶名/nfs *(rw,sync,no_root_squash)
- 在用戶目錄下創建nfs目錄
mkdir /home/用戶名/nfs
- 重啟服務器,重新加載配置文件
sudo /etc/init.d/nfs-kernel-server restart
- 在/home/用戶名/nfs目錄下創建測試文件hello
cd /home/用戶名/nfs
touch hello
- 測試服務器,把服務器共享目錄nfs掛在到/mnt節點
sudo mount –t nfs –o nolock –o tcp IP:/home/用戶名/nfs /mnt
進入/mnt目錄可以看到hello文件,表示構建成功
卸載網絡共享目錄
sudo umount /mnt
11.3ssh
- 安裝ssh服務器
sudo apt-get install openssh-server
- 遠程登錄
ssh 用戶名@IP
12其他命令
12.1終端翻頁
shift-pageup
shift-pagedown
12.2看手冊
man
看手冊(叫做manual或man page)。每一個命令和系統函數都有自己的man page。\
man man
man read 查看read命令的man page
man 2 read 查看read系統函數的man page(在第二個section中,表示為read(2))
man –k read 以read為關鍵字查找相關的man page
12.3清屏
clear
清屏。使光標和提示符回到屏幕的第一行。
快捷鍵:ctrl-l
12.4設置指令別名
alias
alias [-p] name = value...
將value字符串起個別名叫name,以后再命令行輸入name,shell自動將其解釋為value,如果不帶參數執行本命令,或以參數-p執行,則顯示當前定義的別名列表。
$ alias
alias ls = ‘ls --color=auto’
alias rm=’rm -i’
12.5顯示文字
echo [-n] 字符串
在顯示器上顯示一段文字,一般起到一個提示的作用。其中選項n表示輸出文字后不換行;字符串可以加引號,也可以不加引號。用echo命令輸入加引號的字符串時,將字符串原樣輸出;用echo命令輸出不加引號的字符串時,將字符串中的各個單詞作為字符串輸出,各字符串之間用一個空格分隔。
查看上一個程序退出數值,正常情況程序退出值是0
echo $?
12.6查看當前時間
date
12.7權限掩碼
umask
umask [-p] -$ [mode]
umask指定用戶創建文件時的掩碼,其中的mode和chmod的命令中的格式一樣。如果不用mode參數,則顯示當前的umask設置。如果用-S參數,則以符號形式顯示設置。
$umask
0022
$umask –S
u=rmx,g=rx,o=rx
比如該用戶touch或gedit創建一個文件,則其默認權限為-rm-r-r,如果該用戶創建一個可執行文件(比如編譯生成的程序),則其默認權限為-rwxr-xr-x。也就是說,由于umask的設定,創建的文件默認是不具有g的w權限和o的w權限,除非用chmod更改權限。
12.8創建終端
創建終端標簽:Ctrl+Shift+t
切換標簽 Alt+n (n=1)
新開終端 ctrl+shift+n
13關機重啟
關機重啟都需要有root權限
13.1poweroff
13.2 shutdown
shutdown –t 秒數 [-rkncfF] 時間 [警告訊息]
-t 秒數:設定在切換至不同的runlevel之前,警告和刪除二訊號之間的延遲時間(秒)。
-k :僅送出警告訊息文字,但不是真的要shutdown。
-r :shutdown之后重新開機。
-h:shutdown 之后關機。
-n:不經過init,由shutdown指令本身來做關機動作。(不建議用)
-f:重新開機時,跳過fsck指令,不檢查檔案系統。
-F:重新開機時,強迫做fsck檢查。
-c:將已經正在 shutdown的動作取消。
例如:
shutdown –r now 立刻重新開機
shutdown –h now 立刻關機
shutdown –k now ‘Hey| Go away| now ….’ 發出警告訊息,但沒有真的關機
shutdown –t3 –r now 立刻重新開機,但在警告和刪除processes之間,延遲3秒鐘。
shutdown –h 10:42 ‘Hey|Go away|’ 10:42分關機.
shutdown –r 10 ‘Hey|Go away |’ 10分鐘后關機
shutdown –c 將剛才下的 shutdown指令取消,必須切換至其他tty,登入之后,才能下次一指令。
shutdown now 切換至單人操作模式(不加任何選項時)
注意事項:
時間參數務必要加:不是用now,便是用 hh:mm或mm
now 其實就是0的意思
13.3reboot
13.4查看內核版本信息
uname -a
13.5查看發行版信息
lsb_release -a
13.6查看空閑內存
free -m
14需要安裝的組件
sudo apt-get install openssh-server
sudo apt-get install nfs-kernel-server
sudo apt-get install vsftpd
15gcc
-v / –v / –version 查看gcc版本號
-I 指定頭文件目錄,注意-I和之間沒有空格
-c 只編譯,生成.o文件,不進行鏈接
-g 包含調試信息 -On n=0~3 編譯優化,n越大優化得越多
-Wall 提示更多警告信息
-D 編譯時定義宏,注意-D和之間沒有空格
-E 生成預處理文件
-M 生成.c文件與頭文件依賴關系以用于Makefile,包括系統庫的頭文件
-MM 生成.c文件與頭文件依賴關系以用于Makefile,不包括系統庫的頭文件
16Vim
16.1簡介
Vi是“visual interface”的簡稱,它在linux上的地位就仿佛edit程序在DOS上一樣。它可以執行輸出、刪除、查找、替換、塊操作等眾多文本操作,而且用戶可以根據自己的需要對其進行定制。Vi不是一個排版程序,它不像word或wps那樣可以對字體、格式、段落等其他屬性進行編排,它只是一個文本編輯程序。Vi沒有菜單,只有命令,且命令繁多。
Vi有三種基本工作模式
+ 命令模式
+ 文本輸入模式
+ 末行模式

16.2命令行模式
任何時候,不管用戶處于何種模式,只要按一下ESC鍵,即可使vi進入命令模式;我們在shell環境(提示符為$)下輸入啟動vi命令,進入編輯器時,也是處于該模式下。在該模式下,用戶可以輸入各種合法的vi命令,用戶管理自己的文檔。此時從鍵盤上輸入的任何字符都被當做編輯命令來解釋,若輸入的字符是合法的vi命令,則vi在接受用戶命令之后完成相應的動作。但需注意的是,所輸入的命令并不在屏幕上顯示出來。若輸入的字符不是vi的合法命令,vi會響鈴報警。
16.3末行模式
末行模式也稱ex轉義模式。在命令模式下,用戶按“:”鍵即可進入末行模式下,此時vi會在顯示窗口的最后一行(通常也是屏幕的最后一行)顯示一個“:”作為末行模式的提示符,等待用戶輸入命令。多數文件管理命令都是在此模式下執行的(如把編輯緩沖區的內容寫到文件中等)。末行命令執行完后,vi自動回到命令模式。例如:
:sp newfile
列分出一個窗口編輯newfile文件。如果要從命令模式轉換到編輯模式,可以鍵入命令a或者i;如果需要從文本模式返回,則按ESC鍵即可。在命令模式下輸入“:”即可切換到末行模式,然后輸入命令。
16.4Vim基礎操作
進入插入模式:
i: 插入光標前一個字符
I: 插入行首
a: 插入光標后一個字符
A: 插入行未
o: 向下新開一行,插入行首
O: 向上新開一行,插入行首
進入命令模式:
ESC:從插入模式或末行模式進入命令模式
移動光標:
h: 左移
j: 下移
k: 上移
l: 右移
M: 光標移動到中間行
L: 光標移動到屏幕最后一行行首
G: 移動到指定行,行號 -G
w: 向后一次移動一個字
b: 向前一次移動一個字
{: 按段移動,上移
}: 按段移動,下移
Ctr-d: 向下翻半屏
Ctr-u: 向上翻半屏
Ctr-f: 向下翻一屏
Ctr-b: 向上翻一屏
gg: 光標移動文件開頭
G: 光標移動到文件末尾
刪除命令:
x: 刪除光標后一個字符,相當于 Del
X: 刪除光標前一個字符,相當于 Backspace
dd: 刪除光標所在行,n dd 刪除指定的行數
D: 刪除光標后本行所有內容,包含光標所在字符
d0: 刪除光標前本行所有內容,不包含光標所在字符
dw: 刪除光標開始位置的字,包含光標所在字符
撤銷命令:
u: 一步一步撤銷
U: 一次性撤銷當前行所作的所有操作
Ctr-r: 反撤銷
重復命令:
. : 重復上一次操作的命令
文本行移動:
>>: 文本行右移
<<: 文本行左移
復制粘貼:
yy: 復制當前行,n yy 復制 n 行
p: 在光標所在位置向下新開辟一行,粘貼
可視模式:
v: 按字符移動,選中文本
V: 按行移動,選中文本可視模式可以配合 d, y, >>, << 實現對文本塊的刪除,復制,左右移動
替換操作:
r: 替換當前字符
R: 替換當前行光標后的字符
查找命令:
/: str查找
n: 下一個
N:上一個
替換命令: 把abc全部替換成123
:%s/abc/123/g
同上,但要用戶一個個確認是否替換
:%s/abc/123/gc
查看 Man Page:
光標移動到函數上,Shift+k
光標移動到函數上,3 Shift+k,查看第三章的 ManPage
查看宏定義:
[-d: 可以查看宏定義,必須先包含此宏所在的頭文件
代碼排版:
gg=G: 代碼自動縮進排版
vim里執行 shell 下命令:
末行模式里輸入!,后面跟命令
16.5 vim分屏操作
分屏操作:
sp: 上下分屏,后可跟文件名
vsp: 左右分屏,后可跟文件名
Ctr+w+w: 在多個窗口切換
啟動分屏:
1.使用大寫O參數進行垂直分屏
$ vim -On file1 file2 ...
2.使用小寫o參數進行水平分屏
$ vim -on file1 file2 ...
注: n是數字,表示分屏的數量,n要大于等于文件個數
關閉分屏
1.關閉當前窗口
ctrl+w c
2.關閉當前窗口,如果只剩最后一個,則退出vim
ctrl+w q
編輯中分屏
1.上下分割當前打開的文件
ctrl+w s
2.上下分割,并打開一個新的文件
:sp filename
3.左右分割當前打開的文件
ctrl+w v
4.左右分割,并打開一個新的文件
:vsp filename
分屏編輯中光標的移動
vi中的光標鍵是h,j,k,l,要在各個屏之間切換,只需要先按一下ctrl+w
1.把光標移動到上邊的屏
ctrl+w k
2.把光標移動到下邊的屏
ctrl+w j
3.把光標移動到右邊的屏
ctrl+w l
4.把光標移動到左邊的屏
ctrl+w h
5.把光標移動到下一個的屏
ctrl+w w
移動分屏
1.向上移動
ctrl+w K
2.向下移動
ctrl+w J
3.向右移動
ctrl+w L
4.向左移動
ctrl+w H
屏幕尺寸
1.增加高度
ctrl+w +
2.減少高度
ctrl+w
3.讓所有屏的高度一致
ctrl+w =
4.左加寬度
ctrl+w >
5.右加寬度
ctrl+w <
6.右增加n寬 (如:n=30)
ctrl+w n <
16.6vim打造IDE
vimrc是vim的配置文件,可以修改兩個位置
1. /etc/vim/vimrc
2.~/.vimrc
~/.vimrc優先級高
1.拷貝我提供的
vim.tar.gz,
2.解包到當前用戶目錄下
tar zxvf vim.tar.gz -C ~/
3.查看編輯.vimrc文件
vim .vimrc
4.vim常用操作,備注:這些操作可以通過修改.vimrc文件進行設置
17toolchain
binutils 一組用于編譯、鏈接、匯編和其它調試目的的程序,包括ar、as、ld、nm、objcopy、objdump、ranlib、readelf、size、strings、strip等
* gcc 編譯器
* glibc 該庫實現Linux系統函數,例如open、read等,也實現標準C語言庫,如printf 等。幾乎所有應用程序都需要與glibc鏈接
本節主要介紹binutils中的幾種主要工具的作用。
* ar 打包生成靜態庫
* as 匯編器
* ld 鏈接器。本節前面介紹用gcc完成鏈接步驟,其實是gcc調用鏈接器ld,將用戶編譯 生成的目標文件連同系統的libc啟動代碼鏈接在一起形成最終的可執行文件
* nm 查看目標文件中的符號(全局變量、全局函數等)
* objcopy 將原目標文件中的內容復制到新的目標文件中,可以通過不同的命令選項調 整目標文件的格式,比如去除某些ELF文件頭
* objdump 用于生成反匯編文件,主要依賴objcopy實現,a.out編譯時需要-g, objdump -dSsx a.out > file
* ranlib 為靜態庫文件創建索引,相當于ar命令的s選項
* readelf 解讀ELF文件頭
18靜態庫和共享庫
*本節就如何創建和使用程序庫進行論述。所謂“程序庫”,簡單說,就是包含了數據和執行碼的文件。其不能單獨執行,可以作為其它執行程序的一部分來完成某些功能。庫的 存在,可以使得程序模塊化,可以加快程序的再編譯,可以實現代碼重用,可以使得程序便于升級。程序庫可分靜態庫(static library)和共享庫(shared object)。
18.1
是在可執行程序運行前就已經加入到執行碼中,成為執行程序的一部分;共享庫,是在 執行程序啟動時加載到執行程序中,可以被多個執行程序共享使用。
建議庫開發人員創建共享庫,比較明顯的優勢在于庫是獨立的,便于維護和更新;而靜 態庫的更新比較麻煩,一般不做推薦。然而,它們又各有優點,后面會講到。
本節所講述的執行程序和庫都采用ELF(Executable and Linking Format)格式,盡管GNU GCC工具可以處理其它格式,但不在本節的討論范圍。
靜態庫可以認為是一些目標代碼的集合。按照習慣,一般以“.a”做為文件后綴名。使 用ar(archiver)命令可以創建靜態庫。因為共享庫有著更大的優勢,靜態庫已經不經常使用。但靜態庫使用簡單,仍有使用的余地,并會一直存在。有些Unix系統,如Solaris 10, 已經基本廢棄了靜態庫。
靜態庫在應用程序生成時,可以不必再編譯,節省再編譯時間。但在編譯器越來越快的 今天,這一點似乎已不重要。如果其他開發人員要使用你的程序,而你又不想給其源碼,提供靜態庫是一種選擇。從理論上講,應用程序使用了靜態庫,要比使用動態加載庫速度快 1-5%,但實際上可能并非如此。由此看來,除了使用方便外,靜態庫可能并非一種好的選擇。
要創建一個靜態庫,或要將目標代碼加入到已經存在的靜態庫中,可以使用以下命令:
ar rcs libmylib.a file1.o
file2.o以上表示要把目標碼file1.o和file2.o加入到靜態庫libmylib.a中(ar的參數 r)。若libmylib.a不存在,會自動創建(ar的參數c)。然后更新.a文件的索引,使之包含新 加入的.o文件的內容(ar的參數s)。
靜態庫創建成功后,需要鏈接到應用程序中使用。使用gcc的-l選項來指定靜態庫,使 用-L參數來指定庫文件的搜索路徑。比如上述例子應指定-lmylib,所有庫文件名都以lib開 頭,開頭的lib在指定參數時應省略。-l和-L之后都直接帶參數而不跟空格。
在使用gcc時,要注意其參數的順序。-l是鏈接器選項,一定要放在被編譯的文件名稱 之后;若放在文件名稱之前則會連接失敗,并會出現莫名其妙的錯誤。這一點切記。
18.2共享庫
共享庫的創建比較簡單,基本有兩步。首先使用-fPIC或-fpic創建目標文件,PIC或 pic表示位置無關代碼,然后就可以使用以下格式創建共享庫了: gcc -share -Wl,soname,your_soname -o library_name file_list library_list 下面是使用a.c和b.c創建庫的示例:
gcc -fPIC -c a.c
gcc -fPIC -c b.c
gcc -shared -Wl -o libmyab.so a.o b.o
gcc -shared -Wl,-soname,libmyab.so.1 -o libmyab.so.1.0.1 a.o b.o
按照共享庫的命名慣例,每個共享庫有三個文件名:real name、soname和linker name。真正的庫文件(而不是符號鏈接)的名字是real name,包含完整的共享庫版本號。
soname是一個符號鏈接的名字,只包含共享庫的主版本號,主版本號一致即可保證庫函數的接口一致,因此應用程序的.dynamic段只記錄共享庫的soname,只要soname一致,這個 共享庫就可以用。如libmyab.so.1和libmyab.so.2是兩個主版本號不同的libmyab,有些應 用程序依賴于libmyab.so.1,有些應用程序依賴于libmyab.so.2,但對于依賴libmyab.so.1 的應用程序來說,真正的庫文件不管是libmyab.so.1.10還是libmyab.so.1.11都可以用,所 以使用共享庫可以很方便地升級庫文件而不需要重新編譯應用程序,這是靜態庫所沒有的優點。注意libc的版本編號有一點特殊,libc-2.8.90.so的主版本號是6而不是2或2.8。
linker name僅在編譯鏈接時使用,gcc的-L選項應該指定linker name所在的目錄。有 的linker name是庫文件的一個符號鏈接,有的linker name是一段鏈接腳本。例如上面的 libc.so就是一個linker name,它是一段鏈接腳本:
18.3 共享庫加載
在所有基于GNUglibc的系統中,在啟動一個ELF二進制執行程序時,一個特殊的 程序“程序裝載器”會被自動裝載并運行。在linux中,這個程序裝載器就是/lib/ldlinux.so.X(X是版本號)。它會查找并裝載應用程序所依賴的所有共享庫。被搜索的目錄保
存在/etc/ld.so.conf文件中。當然,如果程序的每次啟動,都要去搜索一番,勢必效率不 堪忍受。Linux系統已經考慮這一點,對共享庫采用了緩存管理。ldconfig就是實現這一功能的工具,其缺省讀取/etc/ld.so.conf文件,對所有共享庫按照一定規范建立符號連接, 然后將信息寫入/etc/ld.so.cache。 /etc/ld.so.cache的存在大大加快了程序的啟動速度。
1. 修改/etc/ld.so.conf
sudo vi /etc/ld.so.conf
添加你的共享庫路徑
2. 更新查找共享庫的路徑
sudo ldconfig -v
3.測試你的程序可否找到共享庫
ldd a.out