極迅云課(服務(wù)端教案)

一、Python簡介和環(huán)境搭建以及pip的安裝

4課時

實驗課

主要內(nèi)容

【Python簡介】:

Python 是一個高層次的結(jié)合了解釋性、編譯性、互動性和面向?qū)ο蟮哪_本語言。

Python 的設(shè)計具有很強的可讀性谴供,相比其他語言經(jīng)常使用英文關(guān)鍵字,其他語言的一些標(biāo)點符號筷笨,它具有比其他語言更有特色語法結(jié)構(gòu)憔鬼。

Python 是一種解釋型語言:?這意味著開發(fā)過程中沒有了編譯這個環(huán)節(jié)龟劲。類似于PHP和Perl語言。

Python 是交互式語言:?這意味著轴或,您可以在一個Python提示符昌跌,直接互動執(zhí)行寫你的程序。

Python 是面向?qū)ο笳Z言:?這意味著Python支持面向?qū)ο蟮娘L(fēng)格或代碼封裝在對象的編程技術(shù)照雁。

Python 是初學(xué)者的語言:Python 對初級程序員而言蚕愤,是一種偉大的語言,它支持廣泛的應(yīng)用程序開發(fā)饺蚊,從簡單的文字處理到 WWW 瀏覽器再到游戲萍诱。

Python 是由 Guido van Rossum 在八十年代末和九十年代初,在荷蘭國家數(shù)學(xué)和計算機科學(xué)研究所設(shè)計出來的污呼。

Python 本身也是由諸多其他語言發(fā)展而來的,這包括 ABC裕坊、Modula-3、C燕酷、C++籍凝、Algol-68、SmallTalk苗缩、Unix shell 和其他的腳本語言等等饵蒂。

像 Perl 語言一樣,Python 源代碼同樣遵循 GPL(GNU General Public License)協(xié)議酱讶。

現(xiàn)在 Python 是由一個核心開發(fā)團隊在維護(hù)退盯,Guido van Rossum 仍然占據(jù)著至關(guān)重要的作用,指導(dǎo)其進(jìn)展泻肯。

Python 特點

1.易于學(xué)習(xí):Python有相對較少的關(guān)鍵字渊迁,結(jié)構(gòu)簡單,和一個明確定義的語法软免,學(xué)習(xí)起來更加簡單宫纬。

2.易于閱讀:Python代碼定義的更清晰。

3.易于維護(hù):Python的成功在于它的源代碼是相當(dāng)容易維護(hù)的膏萧。

4.一個廣泛的標(biāo)準(zhǔn)庫:Python的最大的優(yōu)勢之一是豐富的庫漓骚,跨平臺的,在UNIX榛泛,Windows和Macintosh兼容很好蝌蹂。

5.互動模式:互動模式的支持,您可以從終端輸入執(zhí)行代碼并獲得結(jié)果的語言曹锨,互動的測試和調(diào)試代碼片斷孤个。

6.可移植:基于其開放源代碼的特性,Python已經(jīng)被移植(也就是使其工作)到許多平臺沛简。

7.可擴展:如果你需要一段運行很快的關(guān)鍵代碼齐鲤,或者是想要編寫一些不愿開放的算法斥废,你可以使用C或C++完成那部分程序,然后從你的Python程序中調(diào)用给郊。

8.數(shù)據(jù)庫:Python提供所有主要的商業(yè)數(shù)據(jù)庫的接口牡肉。

9.GUI編程:Python支持GUI可以創(chuàng)建和移植到許多系統(tǒng)調(diào)用。

10.可嵌入:?你可以將Python嵌入到C/C++程序淆九,讓你的程序的用戶獲得"腳本化"的能力统锤。

【所需環(huán)境】:

Ubuntu操作系統(tǒng) | Centos操作系統(tǒng) | Mac OS操作系統(tǒng)

(目前不介紹Windows是因為Windows安裝相對于簡單一些)

【Ubuntu操作系統(tǒng)下安裝Python和Pip】:

python:

第一步,輸入 apt-cache search python 檢索我們需要的python包

檢索我們需要的python包


第二步炭庙,安裝Python包

apt-get?install?python2.7? 安裝2.7版本的Python

安裝Python2.7

之后進(jìn)入Python的安裝時間饲窿,安裝成功之后輸入:

which python命令進(jìn)行查看python路徑

并且輸入 python --version 查看python的版本信息是否正確。


另外一種方式焕蹄,從源代碼編譯安裝python:

$?wget?-c?https://www.python.org/ftp/python/2.7.9/Python-2.7.9.tgz??

$?tar?-xzvf?Python-2.7.9.tgz??

$?cd?Python-2.7.9/??

$?LDFLAGS="-L/usr/lib/x86_64-linux-gnu"?./configure??

$?make??

$?sudo?make?install??

這種方式是使用編譯的形勢安裝python程序逾雄。


pip:

pip 是一個安裝和管理 Python 包的工具,python安裝包的工具有easy_install, setuptools, pip腻脏,distribute嘲驾。使用這些工具都能下載并安裝django。迹卢,而pip是easy_install的替代品。在CPython解釋器徒仓,pypy解釋器腐碱,可以很好地工作。

步驟一: 在終端上使用以下命令掉弛,來保證你系統(tǒng)上所有的包都是最新的症见。

更新你的包

sudo apt-get update

升級你的包

sudo apt-get upgrade

步驟二: 安裝Pip

安裝python-pip和你所需要的包:

apt-get install python-pip

檢查你所安裝Pip的版本:

pip -V

步驟三: 如何使用Pip命令。

在安裝python-pip之后殃饿,你可以使用pip命令谋作。這里有很多的pip命令是可以使用:?

安裝新的python包:

pip install packageName

卸載python包:

pip uninstall packageName

尋找python包:

pip search packageName


【Centos操作系統(tǒng)下安裝Python和Pip】:

python & pip:

從pip官網(wǎng)https://pypi.python.org/pypi/pip下載pip的源代碼

#解壓

tar -zxvf pip-1.5.5.tar.gz

cd pip-1.5.5

安裝

python setup.py install

從setuptools官網(wǎng)https://pypi.python.org/pypi/setuptools下載setuptools

#解壓

tar -zxvf setuptools-3.6.tar.gz

cd setuptools-3.6

#安裝

python setup.py install

再次安裝pip就OK了。

加載到python時乎芳,在編譯時帶入zlib選項可以有遵蚜。如下:

./configure --prefix=/usr/local --with -zlib

sudo make

sudo make install

pip類似RedHat里面的yum逻翁,安裝軟件非常方便蹋肮。本節(jié)詳細(xì)介紹pip的安裝、以及使用方法理郑。

1肴甸、pip下載安裝

1.1 pip下載

# wget "https://pypi.python.org/packages/source/p/pip/pip-1.5.4.tar.gz#md5=834b2904f92d46aaa333267fb1c922bb" --no-check-certificate

1.2 pip安裝

# pip install SomePackage

? [...]

? Successfully installed SomePackage

2. pip使用詳解

2.1 pip安裝軟件

# pip install SomePackage

? [...]

? Successfully installed SomePackage

2.2 pip查看已安裝的軟件

# pip show --files SomePackage

? Name: SomePackage

? Version: 1.0

? Location: /my/env/lib/pythonx.x/site-packages

? Files:

?? ../somepackage/__init__.py

?? [...]

2.3 pip檢查哪些軟件需要更新

# pip list --outdated

? SomePackage (Current: 1.0 Latest: 2.0)

2.4 pip升級軟件

# pip install --upgrade SomePackage

? [...]

? Found existing installation: SomePackage 1.0

? Uninstalling SomePackage:

??? Successfully uninstalled SomePackage

? Running setup.py install for SomePackage

? Successfully installed SomePackage

2.5 pip卸載軟件

$ pip uninstall SomePackage

? Uninstalling SomePackage:

??? /my/env/lib/pythonx.x/site-packages/somepackage

? Proceed (y/n)? y

? Successfully uninstalled SomePackage

3. pip使用實例

#3.1 安裝redis

# pip install redis

#3.2 卸載redis

# pip uninstall redis

Uninstalling redis:

? /usr/lib/python2.6/site-packages/redis-2.9.1-py2.6.egg-info

.....省略一些內(nèi)容....

Proceed (y/n)? y

? Successfully uninstalled redis

#3.3 查看待更新軟件

pip list --outdate

pygpgme (Current: 0.1 Latest: 0.3)

pycurl (Current: 7.19.0 Latest: 7.19.3.1)

iniparse (Current: 0.3.1 Latest: 0.4)


【Centos操作系統(tǒng)下安裝Python和Pip】:

python & pip:

Mac OS上可以使用brew一鍵安裝:

brew install python2.7

brew install pip2





二寂殉、Python基礎(chǔ)語法

4課時

實驗課

主要內(nèi)容

Python?基礎(chǔ)語法

Python 語言與 Perl,C 和 Java 等語言有許多相似之處原在。但是友扰,也存在一些差異彤叉。

第一個 Python 程序

交互式編程

交互式編程不需要創(chuàng)建腳本文件,是通過 Python 解釋器的交互模式進(jìn)來編寫代碼村怪。

linux上你只需要在命令行中輸入 Python 命令即可啟動交互式編程,提示窗口如下:

$ pythonPython 2.7.6 (default, Sep? 9 2014, 15:04:36) [GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.39)] on darwinType "help", "copyright", "credits" or "license" for more information.>>>

Window 上在安裝 Python 時已經(jīng)已經(jīng)安裝了默認(rèn)的交互式編程客戶端秽浇,提示窗口如下:

在 python 提示符中輸入以下文本信息,然后按 Enter 鍵查看運行效果:

>>> print "Hello, Python!";

在 Python 2.7.6 版本中,以上實例輸出結(jié)果如下:

Hello, Python!

腳本式編程

通過腳本參數(shù)調(diào)用解釋器開始執(zhí)行腳本实愚,直到腳本執(zhí)行完畢兼呵。當(dāng)腳本執(zhí)行完成后,解釋器不再有效腊敲。

讓我們寫一個簡單的 Python 腳本程序击喂。所有 Python 文件將以?.py?為擴展名。將以下的源代碼拷貝至 test.py 文件中碰辅。

print "Hello, Python!";

這里懂昂,假設(shè)你已經(jīng)設(shè)置了 Python 解釋器 PATH 變量。使用以下命令運行程序:

$ python test.py

輸出結(jié)果:

Hello, Python!

讓我們嘗試另一種方式來執(zhí)行 Python 腳本没宾。修改 test.py 文件凌彬,如下所示:

#!/usr/bin/pythonprint "Hello, Python!";

這里,假定您的Python解釋器在/usr/bin目錄中循衰,使用以下命令執(zhí)行腳本:

$ chmod +x test.py? ? # 腳本文件添加可執(zhí)行權(quán)限$ ./test.py

輸出結(jié)果:

Hello, Python!

Python 標(biāo)識符

在 Python 里铲敛,標(biāo)識符由字母、數(shù)字会钝、下劃線組成伐蒋。

在 Python 中,所有標(biāo)識符可以包括英文迁酸、數(shù)字以及下劃線(_)先鱼,但不能以數(shù)字開頭。

Python 中的標(biāo)識符是區(qū)分大小寫的奸鬓。

以下劃線開頭的標(biāo)識符是有特殊意義的焙畔。以單下劃線開頭?_foo?的代表不能直接訪問的類屬性,需通過類提供的接口進(jìn)行訪問串远,不能用?from xxx import *?而導(dǎo)入宏多;

以雙下劃線開頭的?__foo?代表類的私有成員;以雙下劃線開頭和結(jié)尾的?__foo__?代表 Python 里特殊方法專用的標(biāo)識抑淫,如?__init__()?代表類的構(gòu)造函數(shù)绷落。

Python 可以同一行顯示多條語句,方法是用分號?;?分開始苇,如:

>>> print 'hello';print 'runoob';hello

runoob

Python 保留字符

下面的列表顯示了在Python中的保留字砌烁。這些保留字不能用作常數(shù)或變數(shù),或任何其他標(biāo)識符名稱。

所有 Python 的關(guān)鍵字只包含小寫字母函喉。

andexecnot

assertfinallyor

breakforpass

classfromprint

continueglobalraise

defifreturn

delimporttry

elifinwhile

elseiswith

exceptlambdayield

行和縮進(jìn)

學(xué)習(xí) Python 與其他語言最大的區(qū)別就是避归,Python 的代碼塊不使用大括號?{}?來控制類,函數(shù)以及其他邏輯判斷管呵。python 最具特色的就是用縮進(jìn)來寫模塊梳毙。

縮進(jìn)的空白數(shù)量是可變的,但是所有代碼塊語句必須包含相同的縮進(jìn)空白數(shù)量捐下,這個必須嚴(yán)格執(zhí)行账锹。如下所示:

if True:? ? print "True"else:? print "False"

以下代碼將會執(zhí)行錯誤:

#!/usr/bin/python# -*- coding: UTF-8 -*-# 文件名:test.pyif True:? ? print "Answer"? ? print "True"else:? ? print "Answer"? ? # 沒有嚴(yán)格縮進(jìn),在執(zhí)行時會報錯? print "False"

執(zhí)行以上代碼坷襟,會出現(xiàn)如下錯誤提醒:

$ python test.py?

? File "test.py", line 10? ? print "False"? ? ? ? ? ? ? ? ^IndentationError: unindent does not match any outer indentation level

IndentationError: unindent does not match any outer indentation level錯誤表明奸柬,你使用的縮進(jìn)方式不一致,有的是 tab 鍵縮進(jìn)婴程,有的是空格縮進(jìn)廓奕,改為一致即可。

如果是?IndentationError: unexpected indent?錯誤, 則 python 編譯器是在告訴你"Hi档叔,老兄桌粉,你的文件里格式不對了,可能是tab和空格沒對齊的問題"衙四,所有 python 對格式要求非常嚴(yán)格铃肯。

因此,在 Python 的代碼塊中必須使用相同數(shù)目的行首縮進(jìn)空格數(shù)传蹈。

建議你在每個縮進(jìn)層次使用?單個制表符?或?兩個空格?或?四個空格?, 切記不能混用

多行語句

Python語句中一般以新行作為語句的結(jié)束符缘薛。

但是我們可以使用斜杠( \)將一行的語句分為多行顯示,如下所示:

total = item_one + \

? ? ? ? item_two + \

? ? ? ? item_three

語句中包含 [], {} 或 () 括號就不需要使用多行連接符卡睦。如下實例:

days = ['Monday', 'Tuesday', 'Wednesday',? ? ? ? 'Thursday', 'Friday']

Python 引號

Python 可以使用引號(?'?)、雙引號(?"?)漱抓、三引號(?'''?或?"""?) 來表示字符串表锻,引號的開始與結(jié)束必須的相同類型的。

其中三引號可以由多行組成乞娄,編寫多行文本的快捷語法瞬逊,常用于文檔字符串,在文件的特定地點仪或,被當(dāng)做注釋确镊。

word = 'word'sentence = "這是一個句子。"paragraph = """這是一個段落范删。

包含了多個語句"""

Python注釋

python中單行注釋采用 # 開頭蕾域。

#!/usr/bin/python# -*- coding: UTF-8 -*-# 文件名:test.py# 第一個注釋print "Hello, Python!";? # 第二個注釋

輸出結(jié)果:

Hello, Python!

注釋可以在語句或表達(dá)式行末:

name = "Madisetti" # 這是一個注釋

python 中多行注釋使用三個單引號(''')或三個雙引號(""")。

#!/usr/bin/python# -*- coding: UTF-8 -*-# 文件名:test.py'''

這是多行注釋,使用單引號旨巷。

這是多行注釋巨缘,使用單引號。

這是多行注釋采呐,使用單引號若锁。

'''"""

這是多行注釋,使用雙引號斧吐。

這是多行注釋又固,使用雙引號。

這是多行注釋煤率,使用雙引號仰冠。

"""

Python空行

函數(shù)之間或類的方法之間用空行分隔,表示一段新的代碼的開始涕侈。類和函數(shù)入口之間也用一行空行分隔沪停,以突出函數(shù)入口的開始。

空行與代碼縮進(jìn)不同裳涛,空行并不是Python語法的一部分木张。書寫時不插入空行,Python解釋器運行也不會出錯端三。但是空行的作用在于分隔兩段不同功能或含義的代碼舷礼,便于日后代碼的維護(hù)或重構(gòu)。

記捉即场:空行也是程序代碼的一部分妻献。

等待用戶輸入

下面的程序執(zhí)行后就會等待用戶輸入,按回車鍵后就會退出:

#!/usr/bin/python# -*- coding: UTF-8 -*-raw_input("按下 enter 鍵退出团赁,其他任意鍵顯示...\n")

以上代碼中 栗柒,\n?實現(xiàn)換行。一旦用戶按下 enter(回車) 鍵退出革为,其它鍵顯示导披。

同一行顯示多條語句

Python可以在同一行中使用多條語句,語句之間使用分號(;)分割怀挠,以下是一個簡單的實例:

#!/usr/bin/pythonimport sys; x = 'runoob'; sys.stdout.write(x + '\n')

執(zhí)行以上代碼析蝴,輸入結(jié)果為:

$ python test.py

runoob

Print 輸出

print 默認(rèn)輸出是換行的,如果要實現(xiàn)不換行需要在變量末尾加上逗號?,

#!/usr/bin/python# -*- coding: UTF-8 -*-x="a"y="b"# 換行輸出print xprint yprint '---------'# 不換行輸出print x,print y,# 不換行輸出print x,y

以上實例執(zhí)行結(jié)果為:

a

b---------a b a b

多個語句構(gòu)成代碼組

縮進(jìn)相同的一組語句構(gòu)成一個代碼塊绿淋,我們稱之代碼組闷畸。

像if、while吞滞、def和class這樣的復(fù)合語句佑菩,首行以關(guān)鍵字開始,以冒號( : )結(jié)束,該行之后的一行或多行代碼構(gòu)成代碼組倘待。

我們將首行及后面的代碼組稱為一個子句(clause)疮跑。

如下實例:

if expression :

? suite elif expression :?

? suite? else :?

? suite

命令行參數(shù)

很多程序可以執(zhí)行一些操作來查看一些基本信息,Python 可以使用?-h?參數(shù)查看各參數(shù)幫助信息:

$ python -h

usage: python [option] ... [-c cmd | -m mod | file | -] [arg] ... Options and arguments (and corresponding environment variables): -c cmd : program passed in as string (terminates option list) -d? ? : debug output from parser (also PYTHONDEBUG=x) -E? ? : ignore environment variables (such as PYTHONPATH) -h? ? : print this help message and exit

[ etc. ]




三凸舵、Python?變量類型和運算符

4課時

實驗課

主要內(nèi)容

Python?變量類型

變量存儲在內(nèi)存中的值祖娘。這就意味著在創(chuàng)建變量時會在內(nèi)存中開辟一個空間。

基于變量的數(shù)據(jù)類型啊奄,解釋器會分配指定內(nèi)存渐苏,并決定什么數(shù)據(jù)可以被存儲在內(nèi)存中。

因此菇夸,變量可以指定不同的數(shù)據(jù)類型琼富,這些變量可以存儲整數(shù),小數(shù)或字符庄新。

變量賦值

Python 中的變量賦值不需要類型聲明鞠眉。

每個變量在內(nèi)存中創(chuàng)建,都包括變量的標(biāo)識择诈,名稱和數(shù)據(jù)這些信息械蹋。

每個變量在使用前都必須賦值,變量賦值以后該變量才會被創(chuàng)建羞芍。

等號(=)用來給變量賦值哗戈。

等號(=)運算符左邊是一個變量名,等號(=)運算符右邊是存儲在變量中的值。例如:

實例(Python 2.0+)

#!/usr/bin/python# -*- coding: UTF-8 -*- counter = 100 # 賦值整型變量miles = 1000.0 # 浮點型name = "John" # 字符串 print counterprint milesprint name


以上實例中荷科,100唯咬,1000.0和"John"分別賦值給counter,miles畏浆,name變量胆胰。

執(zhí)行以上程序會輸出如下結(jié)果:

1001000.0John

多個變量賦值

Python允許你同時為多個變量賦值。例如:

a = b = c = 1

以上實例刻获,創(chuàng)建一個整型對象煮剧,值為1,三個變量被分配到相同的內(nèi)存空間上将鸵。

您也可以為多個對象指定多個變量。例如:

a, b, c = 1, 2, "john"

以上實例佑颇,兩個整型對象 1 和 2 分別分配給變量 a 和 b顶掉,字符串對象 "john" 分配給變量 c。

標(biāo)準(zhǔn)數(shù)據(jù)類型

在內(nèi)存中存儲的數(shù)據(jù)可以有多種類型挑胸。

例如痒筒,一個人的年齡可以用數(shù)字來存儲,他的名字可以用字符來存儲。

Python 定義了一些標(biāo)準(zhǔn)類型簿透,用于存儲各種類型的數(shù)據(jù)移袍。

Python有五個標(biāo)準(zhǔn)的數(shù)據(jù)類型:

Numbers(數(shù)字)

String(字符串)

List(列表)

Tuple(元組)

Dictionary(字典)

Python數(shù)字

數(shù)字?jǐn)?shù)據(jù)類型用于存儲數(shù)值。

他們是不可改變的數(shù)據(jù)類型老充,這意味著改變數(shù)字?jǐn)?shù)據(jù)類型會分配一個新的對象葡盗。

當(dāng)你指定一個值時,Number對象就會被創(chuàng)建:

var1 = 1

var2 = 10

您也可以使用del語句刪除一些對象的引用啡浊。

del語句的語法是:

del var1[,var2[,var3[....,varN]]]]

您可以通過使用del語句刪除單個或多個對象的引用觅够。例如:

del var

del var_a, var_b

Python支持四種不同的數(shù)字類型:

int(有符號整型)

long(長整型[也可以代表八進(jìn)制和十六進(jìn)制])

float(浮點型)

complex(復(fù)數(shù))

實例

一些數(shù)值類型的實例:

int long float complex

1051924361L0.03.14j

100-0x19323L15.2045.j

-7860122L-21.99.322e-36j

0800xDEFABCECBDAECBFBAEl32.3e+18.876j

-0490535633629843L-90.-.6545+0J

-0x260-052318172735L-32.54e1003e+26J

0x69-4721885298529L70.2E-124.53e-7j

長整型也可以使用小寫 l,但是還是建議您使用大寫 L巷嚣,避免與數(shù)字 1 混淆喘先。Python使用 L 來顯示長整型。

Python 還支持復(fù)數(shù)廷粒,復(fù)數(shù)由實數(shù)部分和虛數(shù)部分構(gòu)成窘拯,可以用 a + bj,或者 complex(a,b) 表示, 復(fù)數(shù)的實部 a 和虛部 b 都是浮點型坝茎。

Python字符串

字符串或串(String)是由數(shù)字涤姊、字母、下劃線組成的一串字符景东。

一般記為 :

s="a1a2···an"(n>=0)

它是編程語言中表示文本的數(shù)據(jù)類型砂轻。

python的字串列表有2種取值順序:

從左到右索引默認(rèn)0開始的,最大范圍是字符串長度少1

從右到左索引默認(rèn)-1開始的斤吐,最大范圍是字符串開頭

如果你要實現(xiàn)從字符串中獲取一段子字符串的話搔涝,可以使用變量?[頭下標(biāo):尾下標(biāo)],就可以截取相應(yīng)的字符串和措,其中下標(biāo)是從 0 開始算起庄呈,可以是正數(shù)或負(fù)數(shù),下標(biāo)可以為空表示取到頭或尾派阱。

比如:

s = 'ilovepython'

s[1:5]的結(jié)果是love诬留。

當(dāng)使用以冒號分隔的字符串,python返回一個新的對象贫母,結(jié)果包含了以這對偏移標(biāo)識的連續(xù)的內(nèi)容文兑,左邊的開始是包含了下邊界。

上面的結(jié)果包含了s[1]的值l腺劣,而取到的最大范圍不包括上邊界绿贞,就是s[5]的值p。

加號(+)是字符串連接運算符橘原,星號(*)是重復(fù)操作籍铁。如下實例:

實例(Python 2.0+)

#!/usr/bin/python# -*- coding: UTF-8 -*-?

str = 'Hello World!' print str? ? ? ? ??

# 輸出完整字符串

print str[0]? ? ? ??

# 輸出字符串中的第一個字符

print str[2:5]? ? ??

# 輸出字符串中第三個至第五個之間的字符串

print str[2:]? ? ??

?# 輸出從第三個字符開始的字符串

print str * 2? ? ? ?

# 輸出字符串兩次

print str + "TEST"? # 輸出連接的字符串

以上實例輸出結(jié)果:

Hello World!H

llo

llo World!Hello World!Hello World!Hello World!TEST

Python列表

List(列表) 是 Python 中使用最頻繁的數(shù)據(jù)類型涡上。

列表可以完成大多數(shù)集合類的數(shù)據(jù)結(jié)構(gòu)實現(xiàn)。它支持字符拒名,數(shù)字吩愧,字符串甚至可以包含列表(即嵌套)。

列表用?[ ]?標(biāo)識增显,是 python 最通用的復(fù)合數(shù)據(jù)類型雁佳。

列表中值的切割也可以用到變量?[頭下標(biāo):尾下標(biāo)]?,就可以截取相應(yīng)的列表甸怕,從左到右索引默認(rèn) 0 開始甘穿,從右到左索引默認(rèn) -1 開始,下標(biāo)可以為空表示取到頭或尾梢杭。

加號?+?是列表連接運算符温兼,星號?*?是重復(fù)操作。如下實例:

實例(Python 2.0+)

#!/usr/bin/python#?

-*- coding: UTF-8 -*-?

list = [ 'runoob', 786 , 2.23, 'john', 70.2 ]

tinylist = [123, 'john'] print list? ? ? ? ? ? ??

# 輸出完整列表

print list[0]? ? ? ? ? ??

# 輸出列表的第一個元素

print list[1:3]? ? ? ? ??

# 輸出第二個至第三個元素?

print list[2:]? ? ? ? ??

?# 輸出從第三個開始至列表末尾的所有元素

print tinylist * 2? ? ??

?# 輸出列表兩次

print list + tinylist? ??

# 打印組合的列表

以上實例輸出結(jié)果:

['runoob', 786, 2.23, 'john', 70.2]runoob[786, 2.23][2.23, 'john', 70.2][123, 'john', 123, 'john']['runoob', 786, 2.23, 'john', 70.2, 123, 'john']

Python元組

元組是另一個數(shù)據(jù)類型武契,類似于List(列表)募判。

元組用"()"標(biāo)識。內(nèi)部元素用逗號隔開咒唆。但是元組不能二次賦值届垫,相當(dāng)于只讀列表。

實例(Python 2.0+)

#!/usr/bin/python#?

-*- coding: UTF-8 -*-?

tuple = ( 'runoob', 786 , 2.23, 'john', 70.2 )

tinytuple = (123, 'john') print tuple? ? ? ? ? ? ? # 輸出完整元組

print tuple[0]? ? ? ? ? ? # 輸出元組的第一個元素

print tuple[1:3]? ? ? ? ? # 輸出第二個至第三個的元素?

print tuple[2:]? ? ? ? ? # 輸出從第三個開始至列表末尾的所有元素

print tinytuple * 2? ? ? # 輸出元組兩次

print tuple + tinytuple? # 打印組合的元組

以上實例輸出結(jié)果:

('runoob', 786, 2.23, 'john', 70.2)runoob(786, 2.23)(2.23, 'john', 70.2)(123, 'john', 123, 'john')('runoob', 786, 2.23, 'john', 70.2, 123, 'john')

以下是元組無效的全释,因為元組是不允許更新的吠谢。而列表是允許更新的:

實例(Python 2.0+)

#!/usr/bin/python#?

-*- coding: UTF-8 -*-?

tuple = ( 'runoob', 786 , 2.23, 'john', 70.2 )

list = [ 'runoob', 786 , 2.23, 'john', 70.2 ]

tuple[2] = 1000? ? # 元組中是非法應(yīng)用

list[2] = 1000? ? # 列表中是合法應(yīng)用

Python 字典

字典(dictionary)是除列表以外python之中最靈活的內(nèi)置數(shù)據(jù)結(jié)構(gòu)類型许昨。列表是有序的對象集合,字典是無序的對象集合。

兩者之間的區(qū)別在于:字典當(dāng)中的元素是通過鍵來存取的尿招,而不是通過偏移存取讼呢。

字典用"{ }"標(biāo)識鲤竹。字典由索引(key)和它對應(yīng)的值value組成蕉汪。

實例(Python 2.0+)

#!/usr/bin/python#?

-*- coding: UTF-8 -*-?

dict = {}

dict['one'] = "This is one"

dict[2] = "This is two"?

tinydict = {'name': 'john','code':6734, 'dept': 'sales'}

print dict['one']? ? ? ? ? # 輸出鍵為'one' 的值

print dict[2]? ? ? ? ? ? ? # 輸出鍵為 2 的值

print tinydict? ? ? ? ? ? # 輸出完整的字典

print tinydict.keys()? ? ? # 輸出所有鍵

print tinydict.values()? ? # 輸出所有值

輸出結(jié)果為:

This is oneThis is two{'dept': 'sales', 'code': 6734, 'name': 'john'}['dept', 'code', 'name']['sales', 6734, 'john']

Python數(shù)據(jù)類型轉(zhuǎn)換

有時候,我們需要對數(shù)據(jù)內(nèi)置的類型進(jìn)行轉(zhuǎn)換封字,數(shù)據(jù)類型的轉(zhuǎn)換黔州,你只需要將數(shù)據(jù)類型作為函數(shù)名即可。

以下幾個內(nèi)置的函數(shù)可以執(zhí)行數(shù)據(jù)類型之間的轉(zhuǎn)換阔籽。這些函數(shù)返回一個新的對象流妻,表示轉(zhuǎn)換的值。

函數(shù)描述

int(x [,base])將x轉(zhuǎn)換為一個整數(shù)

long(x [,base] )將x轉(zhuǎn)換為一個長整數(shù)

float(x)將x轉(zhuǎn)換到一個浮點數(shù)

complex(real [,imag])創(chuàng)建一個復(fù)數(shù)

str(x)將對象 x 轉(zhuǎn)換為字符串

repr(x)將對象 x 轉(zhuǎn)換為表達(dá)式字符串

eval(str)用來計算在字符串中的有效Python表達(dá)式,并返回一個對象

tuple(s)將序列 s 轉(zhuǎn)換為一個元組

list(s)將序列 s 轉(zhuǎn)換為一個列表

set(s)轉(zhuǎn)換為可變集合

dict(d)創(chuàng)建一個字典笆制。d 必須是一個序列 (key,value)元組绅这。

frozenset(s)轉(zhuǎn)換為不可變集合

chr(x)將一個整數(shù)轉(zhuǎn)換為一個字符

unichr(x)將一個整數(shù)轉(zhuǎn)換為Unicode字符

ord(x)將一個字符轉(zhuǎn)換為它的整數(shù)值

hex(x)將一個整數(shù)轉(zhuǎn)換為一個十六進(jìn)制字符串

oct(x)將一個整數(shù)轉(zhuǎn)換為一個八進(jìn)制字符串



Python算術(shù)運算符

以下假設(shè)變量:?a=10,b=20

運算符描述實例

+加 - 兩個對象相加a + b 輸出結(jié)果 30

-減 - 得到負(fù)數(shù)或是一個數(shù)減去另一個數(shù)a - b 輸出結(jié)果 -10

*乘 - 兩個數(shù)相乘或是返回一個被重復(fù)若干次的字符串a(chǎn) * b 輸出結(jié)果 200

/除 - x除以yb / a 輸出結(jié)果 2

%取模 - 返回除法的余數(shù)b % a 輸出結(jié)果 0

**冪 - 返回x的y次冪a**b 為10的20次方项贺, 輸出結(jié)果 100000000000000000000

//取整除 - 返回商的整數(shù)部分(向下取整)9//2 輸出結(jié)果 4 , 9.0//2.0 輸出結(jié)果 4.0


實例

#!/usr/bin/python

# -*- coding: UTF-8 -*-

a = 21

b = 10

c = 0

c = a + b

print "1 - c 的值為:", c

c = a - b

print "2 - c 的值為:", c

c = a * b

print "3 - c 的值為:", c

c = a / b

print "4 - c 的值為:", c

c = a % b

print "5 - c 的值為:", c

# 修改變量 a 君躺、b 、c

a = 2

b = 3

c = a**b

print "6 - c 的值為:", c

a = 10

b = 5

c = a//b

print "7 - c 的值為:", c

結(jié)果



Python位運算符

按位運算符是把數(shù)字看作二進(jìn)制來進(jìn)行計算的开缎。Python中的按位運算法則如下:

下表中變量 a 為 60棕叫,b 為 13,二進(jìn)制格式如下:

#!/usr/bin/python

# -*- coding: UTF-8 -*-

a = 60

# 60 = 0011 1100

b = 13

# 13 = 0000 1101

c = 0











四奕删、Python?條件語句和循環(huán)語句

4課時

實驗課

主要內(nèi)容

Python條件語句

是通過一條或多條語句的執(zhí)行結(jié)果(True或者False)來決定執(zhí)行的代碼塊俺泣。

可以通過下圖來簡單了解條件語句的執(zhí)行過程:

Python程序語言指定任何非0和非空(null)值為true,0 或者 null為false完残。

Python 編程中 if 語句用于控制程序的執(zhí)行伏钠,基本形式為:

if 判斷條件:?

?????執(zhí)行語句……

else:?

?????執(zhí)行語句……

Python?循環(huán)語句

本章節(jié)將向大家介紹Python的循環(huán)語句,程序在一般情況下是按順序執(zhí)行的谨设。

編程語言提供了各種控制結(jié)構(gòu)熟掂,允許更復(fù)雜的執(zhí)行路徑。

循環(huán)語句允許我們執(zhí)行一個語句或語句組多次扎拣,下面是在大多數(shù)編程語言中的循環(huán)語句的一般形式:

Python提供了for循環(huán)和while循環(huán)(在Python中沒有do..while循環(huán)):



五赴肚、Python中的數(shù)據(jù)結(jié)構(gòu):字典

4課時

實驗課

主要內(nèi)容

Python?字典(Dictionary)

字典是另一種可變?nèi)萜髂P停铱纱鎯θ我忸愋蛯ο蟆?/p>

字典的每個鍵值(key=>value)對用冒號(:)分割二蓝,每個對之間用逗號(,)分割誉券,整個字典包括在花括號({})中 ,格式如下所示:

d = {key1 : value1, key2 : value2 }

鍵必須是唯一的,但值則不必刊愚。

值可以取任何數(shù)據(jù)類型踊跟,但鍵必須是不可變的,如字符串鸥诽,數(shù)字或元組商玫。

一個簡單的字典實例:

dict = {'Alice': '2341', 'Beth': '9102', 'Cecil': '3258'}

也可如此創(chuàng)建字典:

dict1 = { 'abc': 456 };

dict2 = { 'abc': 123, 98.6: 37 };

訪問字典里的值

把相應(yīng)的鍵放入熟悉的方括弧,如下實例:

#!/usr/bin/python

dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'};

print "dict['Name']: ", dict['Name'];

print "dict['Age']: ", dict['Age'];

以上實例輸出結(jié)果:

dict['Name']:? Zara

dict['Age']:? 7

如果用字典里沒有的鍵訪問數(shù)據(jù)衙传,會輸出錯誤如下:

#!/usr/bin/python

dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'};

print "dict['Alice']: ", dict['Alice'];

以上實例輸出結(jié)果:

dict['Zara']:

Traceback (most recent call last):

? File "test.py", line 4, in

? ? print "dict['Alice']: ", dict['Alice'];

KeyError: 'Alice'

修改字典

向字典添加新內(nèi)容的方法是增加新的鍵/值對决帖,修改或刪除已有鍵/值對如下實例:

#!/usr/bin/python

dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'};

dict['Age'] = 8; # update existing entry

dict['School'] = "DPS School"; # Add new entry

print "dict['Age']: ", dict['Age'];

print "dict['School']: ", dict['School'];

以上實例輸出結(jié)果:

dict['Age']:? 8

dict['School']:? DPS School

刪除字典元素

能刪單一的元素也能清空字典,清空只需一項操作蓖捶。

顯示刪除一個字典用del命令地回,如下實例:

#coding=utf-8

#!/usr/bin/python

dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'};

del dict['Name']; # 刪除鍵是'Name'的條目

dict.clear();? ? # 清空詞典所有條目

del dict ;? ? ? ? # 刪除詞典

print "dict['Age']: ", dict['Age'];

print "dict['School']: ", dict['School'];

但這會引發(fā)一個異常,因為用del后字典不再存在:

dict['Age']:

Traceback (most recent call last):

? File "test.py", line 8, in

? ? print "dict['Age']: ", dict['Age'];

TypeError: 'type' object is unsubscriptable

注:del()方法后面也會討論俊鱼。

字典鍵的特性

字典值可以沒有限制地取任何python對象刻像,既可以是標(biāo)準(zhǔn)的對象,也可以是用戶定義的并闲,但鍵不行细睡。

兩個重要的點需要記住:

1)不允許同一個鍵出現(xiàn)兩次帝火。創(chuàng)建時如果同一個鍵被賦值兩次溜徙,后一個值會被記住湃缎,如下實例:

#!/usr/bin/python

dict = {'Name': 'Zara', 'Age': 7, 'Name': 'Manni'};

print "dict['Name']: ", dict['Name'];

以上實例輸出結(jié)果:

dict['Name']:? Manni

2)鍵必須不可變,所以可以用數(shù)蠢壹,字符串或元組充當(dāng)嗓违,所以用列表就不行,如下實例:

#!/usr/bin/python

dict = {['Name']: 'Zara', 'Age': 7};

print "dict['Name']: ", dict['Name'];

以上實例輸出結(jié)果:

Traceback (most recent call last):

? File "test.py", line 3, in

? ? dict = {['Name']: 'Zara', 'Age': 7};

TypeError: list objects are unhashable

字典內(nèi)置函數(shù)&方法

Python字典包含了以下內(nèi)置函數(shù):

序號函數(shù)及描述

1cmp(dict1, dict2)

比較兩個字典元素图贸。

2len(dict)

計算字典元素個數(shù)蹂季,即鍵的總數(shù)。

3str(dict)

輸出字典可打印的字符串表示疏日。

4type(variable)

返回輸入的變量類型偿洁,如果變量是字典就返回字典類型。

Python字典包含了以下內(nèi)置函數(shù):

序號函數(shù)及描述

1radiansdict.clear()

刪除字典內(nèi)所有元素

2radiansdict.copy()

返回一個字典的淺復(fù)制

3radiansdict.fromkeys()

創(chuàng)建一個新字典沟优,以序列seq中元素做字典的鍵涕滋,val為字典所有鍵對應(yīng)的初始值

4radiansdict.get(key, default=None)

返回指定鍵的值,如果值不在字典中返回default值

5radiansdict.has_key(key)

如果鍵在字典dict里返回true净神,否則返回false

6radiansdict.items()

以列表返回可遍歷的(鍵, 值) 元組數(shù)組

7radiansdict.keys()

以列表返回一個字典所有的鍵

8radiansdict.setdefault(key, default=None)

和get()類似, 但如果鍵不已經(jīng)存在于字典中何吝,將會添加鍵并將值設(shè)為default

9radiansdict.update(dict2)

把字典dict2的鍵/值對更新到dict里

10radiansdict.values()

以列表返回字典中的所有值






六、Python的文件IO

4課時

實驗課

主要內(nèi)容

Python 文件I/O

打印到屏幕

最簡單的輸出方法是用print語句鹃唯,你可以給它傳遞零個或多個用逗號隔開的表達(dá)式爱榕。此函數(shù)把你傳遞的表達(dá)式轉(zhuǎn)換成一個字符串表達(dá)式,并將結(jié)果寫到標(biāo)準(zhǔn)輸出如下:

#!/usr/bin/python

print "Python is really a great language,", "isn't it?";

你的標(biāo)準(zhǔn)屏幕上會產(chǎn)生以下結(jié)果:

Python is really a great language, isn't it?

讀取鍵盤輸入

Python提供了兩個內(nèi)置函數(shù)從標(biāo)準(zhǔn)輸入讀入一行文本坡慌,默認(rèn)的標(biāo)準(zhǔn)輸入是鍵盤黔酥。如下:

raw_input

input

raw_input函數(shù)

raw_input([prompt]) 函數(shù)從標(biāo)準(zhǔn)輸入讀取一個行,并返回一個字符串(去掉結(jié)尾的換行符):

#!/usr/bin/python

# -*- coding: UTF-8 -*-?


str = raw_input("請輸入:");

print "你輸入的內(nèi)容是: ", str

這將提示你輸入任意字符串洪橘,然后在屏幕上顯示相同的字符串跪者。當(dāng)我輸入"Hello Python!"熄求,它的輸出如下:

請輸入:Hello Python渣玲!

你輸入的內(nèi)容是: ?Hello Python!

input函數(shù)

input([prompt]) 函數(shù)和raw_input([prompt]) 函數(shù)基本可以互換弟晚,但是input會假設(shè)你的輸入是一個有效的Python表達(dá)式忘衍,并返回運算結(jié)果。

#!/usr/bin/python

str = input("Enter your input: ");

print "Received input is : ", str

這會產(chǎn)生如下的對應(yīng)著輸入的結(jié)果:

Enter your input: [x*5 for x in range(2,10,2)]

Recieved input is :? [10, 20, 30, 40]

打開和關(guān)閉文件

到現(xiàn)在為止卿城,你已經(jīng)可以向標(biāo)準(zhǔn)輸入和輸出進(jìn)行讀寫∶兜觯現(xiàn)在,來看看怎么讀寫實際的數(shù)據(jù)文件瑟押。

Python提供了必要的函數(shù)和方法進(jìn)行默認(rèn)情況下的文件基本操作搀捷。你可以用file對象做大部分的文件操作。

open函數(shù)

你必須先用Python內(nèi)置的open()函數(shù)打開一個文件多望,創(chuàng)建一個file對象嫩舟,相關(guān)的輔助方法才可以調(diào)用它進(jìn)行讀寫氢烘。

語法:

file object = open(file_name [, access_mode][, buffering])

各個參數(shù)的細(xì)節(jié)如下:

file_name:file_name變量是一個包含了你要訪問的文件名稱的字符串值。

access_mode:access_mode決定了打開文件的模式:只讀家厌,寫入威始,追加等。所有可取值見如下的完全列表像街。這個參數(shù)是非強制的,默認(rèn)文件訪問模式為只讀(r)晋渺。

buffering:如果buffering的值被設(shè)為0镰绎,就不會有寄存。如果buffering的值取1木西,訪問文件時會寄存行畴栖。如果將buffering的值設(shè)為大于1的整數(shù),表明了這就是的寄存區(qū)的緩沖大小八千。如果取負(fù)值吗讶,寄存區(qū)的緩沖大小則為系統(tǒng)默認(rèn)。

不同模式打開文件的完全列表:

模式描述

r以只讀方式打開文件恋捆。文件的指針將會放在文件的開頭。這是默認(rèn)模式。

rb以二進(jìn)制格式打開一個文件用于只讀慎框。文件指針將會放在文件的開頭疾宏。這是默認(rèn)模式。

r+打開一個文件用于讀寫愤钾。文件指針將會放在文件的開頭瘟滨。

rb+以二進(jìn)制格式打開一個文件用于讀寫。文件指針將會放在文件的開頭能颁。

w打開一個文件只用于寫入杂瘸。如果該文件已存在則將其覆蓋。如果該文件不存在伙菊,創(chuàng)建新文件败玉。

wb以二進(jìn)制格式打開一個文件只用于寫入。如果該文件已存在則將其覆蓋占业。如果該文件不存在绒怨,創(chuàng)建新文件。

w+打開一個文件用于讀寫谦疾。如果該文件已存在則將其覆蓋南蹂。如果該文件不存在,創(chuàng)建新文件念恍。

wb+以二進(jìn)制格式打開一個文件用于讀寫六剥。如果該文件已存在則將其覆蓋晚顷。如果該文件不存在,創(chuàng)建新文件疗疟。

a打開一個文件用于追加该默。如果該文件已存在,文件指針將會放在文件的結(jié)尾策彤。也就是說栓袖,新的內(nèi)容將會被寫入到已有內(nèi)容之后。如果該文件不存在店诗,創(chuàng)建新文件進(jìn)行寫入裹刮。

ab以二進(jìn)制格式打開一個文件用于追加。如果該文件已存在庞瘸,文件指針將會放在文件的結(jié)尾捧弃。也就是說,新的內(nèi)容將會被寫入到已有內(nèi)容之后擦囊。如果該文件不存在违霞,創(chuàng)建新文件進(jìn)行寫入。

a+打開一個文件用于讀寫瞬场。如果該文件已存在买鸽,文件指針將會放在文件的結(jié)尾。文件打開時會是追加模式贯被。如果該文件不存在癞谒,創(chuàng)建新文件用于讀寫。

ab+以二進(jìn)制格式打開一個文件用于追加刃榨。如果該文件已存在弹砚,文件指針將會放在文件的結(jié)尾。如果該文件不存在枢希,創(chuàng)建新文件用于讀寫桌吃。

File對象的屬性

一個文件被打開后,你有一個file對象苞轿,你可以得到有關(guān)該文件的各種信息茅诱。

以下是和file對象相關(guān)的所有屬性的列表:

屬性描述

file.closed如果文件已被關(guān)閉返回true,否則返回false搬卒。

file.mode返回被打開文件的訪問模式瑟俭。

file.name返回文件的名稱。

file.softspace如果用print輸出后契邀,必須跟一個空格符摆寄,則返回false。否則返回true。

如下實例:

#!/usr/bin/python

# -*- coding: UTF-8 -*-


# 打開一個文件

fo = open("foo.txt", "wb")

print "文件名: ", fo.name

print "是否已關(guān)閉 : ", fo.closed

print "訪問模式 : ", fo.mode

print "末尾是否強制加空格 : ", fo.softspace

以上實例輸出結(jié)果:

文件名: ?foo.txt

是否已關(guān)閉 : ?False

訪問模式 : ?wb

末尾是否強制加空格 : ?0

Close()方法

File對象的close()方法刷新緩沖區(qū)里任何還沒寫入的信息微饥,并關(guān)閉該文件逗扒,這之后便不能再進(jìn)行寫入。

當(dāng)一個文件對象的引用被重新指定給另一個文件時欠橘,Python會關(guān)閉之前的文件矩肩。用close()方法關(guān)閉文件是一個很好的習(xí)慣。

語法:

fileObject.close();

例子:

#coding=utf-8

#!/usr/bin/python

# 打開一個文件

fo = open("foo.txt", "wb")

print "文件名: ", fo.name

# 關(guān)閉打開的文件

fo.close()

以上實例輸出結(jié)果:

文件名: ?foo.txt

讀寫文件:

file對象提供了一系列方法肃续,能讓我們的文件訪問更輕松黍檩。來看看如何使用read()和write()方法來讀取和寫入文件。

Write()方法

Write()方法可將任何字符串寫入一個打開的文件始锚。需要重點注意的是建炫,Python字符串可以是二進(jìn)制數(shù)據(jù),而不是僅僅是文字疼蛾。

Write()方法不在字符串的結(jié)尾不添加換行符('\n'):

語法:

fileObject.write(string);

在這里,被傳遞的參數(shù)是要寫入到已打開文件的內(nèi)容艺配。

例子:

#coding=utf-8

#!/usr/bin/python

# 打開一個文件

fo = open("/tmp/foo.txt", "wb")

fo.write( "Python is a great language.\nYeah its great!!\n");

# 關(guān)閉打開的文件

fo.close()

上述方法會創(chuàng)建foo.txt文件察郁,并將收到的內(nèi)容寫入該文件,并最終關(guān)閉文件转唉。如果你打開這個文件皮钠,將看到以下內(nèi)容:

Python is a great language.

Yeah its great!!

read()方法

read()方法從一個打開的文件中讀取一個字符串。需要重點注意的是赠法,Python字符串可以是二進(jìn)制數(shù)據(jù)麦轰,而不是僅僅是文字。

語法:

fileObject.read([count]);

在這里砖织,被傳遞的參數(shù)是要從已打開文件中讀取的字節(jié)計數(shù)款侵。該方法從文件的開頭開始讀入,如果沒有傳入count侧纯,它會嘗試盡可能多地讀取更多的內(nèi)容新锈,很可能是直到文件的末尾。

例子:

就用我們上面創(chuàng)建的文件foo.txt眶熬。

#coding=utf-8

#!/usr/bin/python

# 打開一個文件

fo = open("/tmp/foo.txt", "r+")

str = fo.read(10);

print "讀取的字符串是: ", str

# 關(guān)閉打開的文件

fo.close()

以上實例輸出結(jié)果:

讀取的字符串是:? Python is

文件位置:

tell()方法告訴你文件內(nèi)的當(dāng)前位置妹笆;換句話說,下一次的讀寫會發(fā)生在文件開頭這么多字節(jié)之后:

seek(offset [,from])方法改變當(dāng)前文件的位置娜氏。Offset變量表示要移動的字節(jié)數(shù)拳缠。From變量指定開始移動字節(jié)的參考位置。

如果from被設(shè)為0贸弥,這意味著將文件的開頭作為移動字節(jié)的參考位置窟坐。如果設(shè)為1,則使用當(dāng)前的位置作為參考位置。如果它被設(shè)為2狸涌,那么該文件的末尾將作為參考位置切省。

例子:

就用我們上面創(chuàng)建的文件foo.txt。

#coding=utf-8

#!/usr/bin/python

# 打開一個文件

fo = open("/tmp/foo.txt", "r+")

str = fo.read(10);

print "讀取的字符串是: ", str

# 查找當(dāng)前位置

position = fo.tell();

print "當(dāng)前文件位置: ", position

# 把指針再次重新定位到文件開頭

position = fo.seek(0, 0);

str = fo.read(10);

print "重新讀取字符串: ", str

# 關(guān)閉打開的文件

fo.close()

以上實例輸出結(jié)果:

讀取的字符串是:? Python is

當(dāng)前文件位置:? 10

重新讀取字符串:? Python is

重命名和刪除文件

Python的os模塊提供了幫你執(zhí)行文件處理操作的方法帕胆,比如重命名和刪除文件朝捆。

要使用這個模塊,你必須先導(dǎo)入它懒豹,然后可以調(diào)用相關(guān)的各種功能芙盘。

rename()方法:

rename()方法需要兩個參數(shù),當(dāng)前的文件名和新文件名脸秽。

語法:

os.rename(current_file_name, new_file_name)

例子:

下例將重命名一個已經(jīng)存在的文件test1.txt儒老。

#coding=utf-8

#!/usr/bin/python

import os

# 重命名文件test1.txt到test2.txt。

os.rename( "test1.txt", "test2.txt" )

remove()方法

你可以用remove()方法刪除文件记餐,需要提供要刪除的文件名作為參數(shù)驮樊。

語法:

os.remove(file_name)

例子:

下例將刪除一個已經(jīng)存在的文件test2.txt。

#coding=utf-8

#!/usr/bin/python

import os

# 刪除一個已經(jīng)存在的文件test2.txt

os.remove("text2.txt")

Python里的目錄:

所有文件都包含在各個不同的目錄下片酝,不過Python也能輕松處理囚衔。os模塊有許多方法能幫你創(chuàng)建,刪除和更改目錄雕沿。

mkdir()方法

可以使用os模塊的mkdir()方法在當(dāng)前目錄下創(chuàng)建新的目錄們练湿。你需要提供一個包含了要創(chuàng)建的目錄名稱的參數(shù)。

語法:

os.mkdir("newdir")

例子:

下例將在當(dāng)前目錄下創(chuàng)建一個新目錄test审轮。

#coding=utf-8

#!/usr/bin/python

import os

# 創(chuàng)建目錄test

os.mkdir("test")

chdir()方法

可以用chdir()方法來改變當(dāng)前的目錄肥哎。chdir()方法需要的一個參數(shù)是你想設(shè)成當(dāng)前目錄的目錄名稱卢厂。

語法:

os.chdir("newdir")

例子:

下例將進(jìn)入"/home/newdir"目錄涤垫。

#coding=utf-8

#!/usr/bin/python

import os

# 將當(dāng)前目錄改為"/home/newdir"

os.chdir("/home/newdir")

getcwd()方法:

getcwd()方法顯示當(dāng)前的工作目錄。

語法:

os.getcwd()

例子:

下例給出當(dāng)前目錄:

#coding=utf-8

#!/usr/bin/python

import os

# 給出當(dāng)前的目錄

os.getcwd()

rmdir()方法

rmdir()方法刪除目錄席镀,目錄名稱以參數(shù)傳遞榴捡。

在刪除這個目錄之前霞捡,它的所有內(nèi)容應(yīng)該先被清除。

語法:

os.rmdir('dirname')

例子:

以下是刪除" /tmp/test"目錄的例子薄疚。目錄的完全合規(guī)的名稱必須被給出碧信,否則會在當(dāng)前目錄下搜索該目錄。

#coding=utf-8

#!/usr/bin/python

import os

# 刪除”/tmp/test”目錄

os.rmdir( "/tmp/test"? )

文件街夭、目錄相關(guān)的方法

三個重要的方法來源能對Windows和Unix操作系統(tǒng)上的文件及目錄進(jìn)行一個廣泛且實用的處理及操控砰碴,如下:

File 對象方法: file對象提供了操作文件的一系列方法。

OS 對象方法: 提供了處理文件及目錄的一系列方法板丽。






七呈枉、Python 面向?qū)ο?/h1>

4課時

實驗課

主要內(nèi)容

Python 面向?qū)ο?/h4>

Python從設(shè)計之初就已經(jīng)是一門面向?qū)ο蟮恼Z言趁尼,正因為如此,在Python中創(chuàng)建一個類和對象是很容易的猖辫。本章節(jié)我們將詳細(xì)介紹Python的面向?qū)ο缶幊獭?/p>

如果你以前沒有接觸過面向?qū)ο蟮木幊陶Z言酥泞,那你可能需要先了解一些面向?qū)ο笳Z言的一些基本特征,在頭腦里頭形成一個基本的面向?qū)ο蟮母拍羁性鳎@樣有助于你更容易的學(xué)習(xí)Python的面向?qū)ο缶幊獭?/p>

接下來我們先來簡單的了解下面向?qū)ο蟮囊恍┗咎卣鳌?/p>

面向?qū)ο蠹夹g(shù)簡介

類(Class):?用來描述具有相同的屬性和方法的對象的集合芝囤。它定義了該集合中每個對象所共有的屬性和方法辛萍。對象是類的實例悯姊。

類變量:類變量在整個實例化的對象中是公用的。類變量定義在類中且在函數(shù)體之外贩毕。類變量通常不作為實例變量使用悯许。

數(shù)據(jù)成員:類變量或者實例變量用于處理類及其實例對象的相關(guān)的數(shù)據(jù)。

方法重載:如果從父類繼承的方法不能滿足子類的需求辉阶,可以對其進(jìn)行改寫先壕,這個過程叫方法的覆蓋(override),也稱為方法的重載谆甜。

實例變量:定義在方法中的變量垃僚,只作用于當(dāng)前實例的類。

繼承:即一個派生類(derived class)繼承基類(base class)的字段和方法店印。繼承也允許把一個派生類的對象作為一個基類對象對待。例如倒慧,有這樣一個設(shè)計:一個Dog類型的對象派生自Animal類按摘,這是模擬"是一個(is-a)"關(guān)系(例圖,Dog是一個Animal)纫谅。

實例化:創(chuàng)建一個類的實例炫贤,類的具體對象。

方法:類中定義的函數(shù)付秕。

對象:通過類定義的數(shù)據(jù)結(jié)構(gòu)實例兰珍。對象包括兩個數(shù)據(jù)成員(類變量和實例變量)和方法。

創(chuàng)建類

使用class語句來創(chuàng)建一個新類询吴,class之后為類的名稱并以冒號結(jié)尾掠河,如下實例:

class ClassName:

? '類的幫助信息'? #類文檔字符串

? class_suite? #類體

類的幫助信息可以通過ClassName.__doc__查看。

class_suite 由類成員猛计,方法唠摹,數(shù)據(jù)屬性組成。

實例

以下是一個簡單的Python類實例:

#coding=utf-8

class Employee:

? '所有員工的基類'

? empCount = 0

? def __init__(self, name, salary):

? ? ? self.name = name

? ? ? self.salary = salary

? ? ? Employee.empCount += 1


? def displayCount(self):

? ? print "Total Employee %d" % Employee.empCount

? def displayEmployee(self):

? ? ? print "Name : ", self.name,? ", Salary: ", self.salary

empCount變量是一個類變量奉瘤,它的值將在這個類的所有實例之間共享勾拉。你可以在內(nèi)部類或外部類使用Employee.empCount訪問。

第一種方法__init__()方法是一種特殊的方法,被稱為類的構(gòu)造函數(shù)或初始化方法藕赞,當(dāng)創(chuàng)建了這個類的實例時就會調(diào)用該方法

創(chuàng)建實例對象

要創(chuàng)建一個類的實例成肘,你可以使用類的名稱,并通過__init__方法接受參數(shù)斧蜕。

"創(chuàng)建 Employee 類的第一個對象"

emp1 = Employee("Zara", 2000)

"創(chuàng)建 Employee 類的第二個對象"

emp2 = Employee("Manni", 5000)

訪問屬性

您可以使用點(.)來訪問對象的屬性双霍。使用如下類的名稱訪問類變量:

emp1.displayEmployee()

emp2.displayEmployee()

print "Total Employee %d" % Employee.empCount

完整實例:

#coding=utf-8

#!/usr/bin/python

class Employee:

? '所有員工的基類'

? empCount = 0

? def __init__(self, name, salary):

? ? ? self.name = name

? ? ? self.salary = salary

? ? ? Employee.empCount += 1


? def displayCount(self):

? ? print "Total Employee %d" % Employee.empCount

? def displayEmployee(self):

? ? ? print "Name : ", self.name,? ", Salary: ", self.salary

"創(chuàng)建 Employee 類的第一個對象"

emp1 = Employee("Zara", 2000)

"創(chuàng)建 Employee 類的第二個對象"

emp2 = Employee("Manni", 5000)

emp1.displayEmployee()

emp2.displayEmployee()

print "Total Employee %d" % Employee.empCount

執(zhí)行以上代碼輸出結(jié)果如下:

Name :? Zara ,Salary:? 2000

Name :? Manni ,Salary:? 5000

Total Employee 2

你可以添加,刪除惩激,修改類的屬性店煞,如下所示:

emp1.age = 7? # 添加一個 'age' 屬性

emp1.age = 8? # 修改 'age' 屬性

del emp1.age? # 刪除 'age' 屬性

你也可以使用以下函數(shù)的方式來訪問屬性:

getattr(obj, name[, default]) : 訪問對象的屬性。

hasattr(obj,name) : 檢查是否存在一個屬性风钻。

setattr(obj,name,value) : 設(shè)置一個屬性顷蟀。如果屬性不存在,會創(chuàng)建一個新屬性骡技。

delattr(obj, name) : 刪除屬性鸣个。

hasattr(emp1, 'age')? ? # 如果存在 'age' 屬性返回 True。

getattr(emp1, 'age')? ? # 返回 'age' 屬性的值

setattr(emp1, 'age', 8) # 添加屬性 'age' 值為 8

delattr(empl, 'age')? ? # 刪除屬性 'age'

Python內(nèi)置類屬性

__dict__ : 類的屬性(包含一個字典布朦,由類的數(shù)據(jù)屬性組成)

__doc__ :類的文檔字符串

__name__: 類名

__module__: 類定義所在的模塊(類的全名是'__main__.className'囤萤,如果類位于一個導(dǎo)入模塊mymod中,那么className.__module__ 等于 mymod)

__bases__ : 類的所有父類構(gòu)成元素(包含了以個由所有父類組成的元組)

Python內(nèi)置類屬性調(diào)用實例如下:

#coding=utf-8

#!/usr/bin/python

class Employee:

? '所有員工的基類'

? empCount = 0

? def __init__(self, name, salary):

? ? ? self.name = name

? ? ? self.salary = salary

? ? ? Employee.empCount += 1


? def displayCount(self):

? ? print "Total Employee %d" % Employee.empCount

? def displayEmployee(self):

? ? ? print "Name : ", self.name,? ", Salary: ", self.salary

print "Employee.__doc__:", Employee.__doc__

print "Employee.__name__:", Employee.__name__

print "Employee.__module__:", Employee.__module__

print "Employee.__bases__:", Employee.__bases__

print "Employee.__dict__:", Employee.__dict__

執(zhí)行以上代碼輸出結(jié)果如下:

Employee.__doc__: 所有員工的基類

Employee.__name__: Employee

Employee.__module__: __main__

Employee.__bases__: ()

Employee.__dict__: {'__module__': '__main__', 'displayCount': , 'empCount': 0, 'displayEmployee': , '__doc__': '\xe6\x89\x80\xe6\x9c\x89\xe5\x91\x98\xe5\xb7\xa5\xe7\x9a\x84\xe5\x9f\xba\xe7\xb1\xbb', '__init__': }

python對象銷毀(垃圾回收)

同Java語言一樣是趴,Python使用了引用計數(shù)這一簡單技術(shù)來追蹤內(nèi)存中的對象涛舍。

在Python內(nèi)部記錄著所有使用中的對象各有多少引用。

一個內(nèi)部跟蹤變量唆途,稱為一個引用計數(shù)器富雅。

當(dāng)對象被創(chuàng)建時, 就創(chuàng)建了一個引用計數(shù)肛搬, 當(dāng)這個對象不再需要時没佑, 也就是說, 這個對象的引用計數(shù)變?yōu)? 時温赔, 它被垃圾回收蛤奢。但是回收不是"立即"的, 由解釋器在適當(dāng)?shù)臅r機陶贼,將垃圾對象占用的內(nèi)存空間回收啤贩。

a = 40? ? ? # 創(chuàng)建對象? <40>

b = a? ? ? # 增加引用, <40> 的計數(shù)

c = [b]? ? # 增加引用.? <40> 的計數(shù)

del a? ? ? # 減少引用 <40> 的計數(shù)

b = 100? ? # 減少引用 <40> 的計數(shù)

c[0] = -1? # 減少引用 <40> 的計數(shù)

垃圾回收機制不僅針對引用計數(shù)為0的對象拜秧,同樣也可以處理循環(huán)引用的情況瓜晤。循環(huán)引用指的是,兩個對象相互引用腹纳,但是沒有其他變量引用他們痢掠。這種情況下驱犹,僅使用引用計數(shù)是不夠的。Python 的垃圾收集器實際上是一個引用計數(shù)器和一個循環(huán)垃圾收集器足画。作為引用計數(shù)的補充雄驹, 垃圾收集器也會留心被分配的總量很大(及未通過引用計數(shù)銷毀的那些)的對象。 在這種情況下淹辞, 解釋器會暫停下來医舆, 試圖清理所有未引用的循環(huán)。

實例

析構(gòu)函數(shù) __del__ 象缀,__del__在對象消逝的時候被調(diào)用蔬将,當(dāng)對象不再被使用時,__del__方法運行:

#coding=utf-8

#!/usr/bin/python

class Point:

? def __init( self, x=0, y=0):

? ? ? self.x = x

? ? ? self.y = y

? def __del__(self):

? ? ? class_name = self.__class__.__name__

? ? ? print class_name, "destroyed"

pt1 = Point()

pt2 = pt1

pt3 = pt1

print id(pt1), id(pt2), id(pt3) # 打印對象的id

del pt1

del pt2

del pt3

以上實例運行結(jié)果如下:

3083401324 3083401324 3083401324

Point destroyed

注意:通常你需要在單獨的文件中定義一個類央星,

類的繼承

面向?qū)ο蟮木幊處淼闹饕锰幹皇谴a的重用霞怀,實現(xiàn)這種重用的方法之一是通過繼承機制。繼承完全可以理解成類之間的類型和子類型關(guān)系莉给。

需要注意的地方:繼承語法?class 派生類名(基類名)://... 基類名寫作括號里毙石,基本類是在類定義的時候,在元組之中指明的颓遏。

在python中繼承中的一些特點:

1:在繼承中基類的構(gòu)造(__init__()方法)不會被自動調(diào)用徐矩,它需要在其派生類的構(gòu)造中親自專門調(diào)用。

2:在調(diào)用基類的方法時叁幢,需要加上基類的類名前綴滤灯,且需要帶上self參數(shù)變量。區(qū)別于在類中調(diào)用普通函數(shù)時并不需要帶上self參數(shù)

3:Python總是首先查找對應(yīng)類型的方法曼玩,如果它不能在派生類中找到對應(yīng)的方法鳞骤,它才開始到基類中逐個查找。(先在本類中查找調(diào)用的方法演训,找不到才去基類中找)弟孟。

如果在繼承元組中列了一個以上的類贝咙,那么它就被稱作"多重繼承" 狈茉。

語法:

派生類的聲明划纽,與他們的父類類似,繼承的基類列表跟在類名之后,如下所示:

class SubClassName (ParentClass1[, ParentClass2, ...]):

? 'Optional class documentation string'

? class_suite

實例:

#coding=utf-8

#!/usr/bin/python

class Parent:? ? ? ? # 定義父類

? parentAttr = 100

? def __init__(self):

? ? ? print "調(diào)用父類構(gòu)造函數(shù)"

? def parentMethod(self):

? ? ? print '調(diào)用父類方法'

? def setAttr(self, attr):

? ? ? Parent.parentAttr = attr

? def getAttr(self):

? ? ? print "父類屬性 :", Parent.parentAttr

class Child(Parent): # 定義子類

? def __init__(self):

? ? ? print "調(diào)用子類構(gòu)造方法"

? def childMethod(self):

? ? ? print '調(diào)用子類方法 child method'

c = Child()? ? ? ? ? # 實例化子類

c.childMethod()? ? ? # 調(diào)用子類的方法

c.parentMethod()? ? # 調(diào)用父類方法

c.setAttr(200)? ? ? # 再次調(diào)用父類的方法

c.getAttr()? ? ? ? ? # 再次調(diào)用父類的方法

以上代碼執(zhí)行結(jié)果如下:

調(diào)用子類構(gòu)造方法

調(diào)用子類方法 child method

調(diào)用父類方法

父類屬性 : 200

你可以繼承多個類

class A:? ? ? ? # 定義類 A

.....

class B:? ? ? ? # 定義類 B

.....

class C(A, B):? # 繼承類 A 和 B

.....

你可以使用issubclass()或者isinstance()方法來檢測蜈膨。

issubclass() - 布爾函數(shù)判斷一個類是另一個類的子類或者子孫類,語法:issubclass(sub,sup)

isinstance(obj, Class) 布爾函數(shù)如果obj是Class類的實例對象或者是一個Class子類的實例對象則返回true萍启。

方法重寫

如果你的父類方法的功能不能滿足你的需求女揭,你可以在子類重寫你父類的方法:

實例:

#coding=utf-8

#!/usr/bin/python

class Parent:? ? ? ? # 定義父類

? def myMethod(self):

? ? ? print '調(diào)用父類方法'

class Child(Parent): # 定義子類

? def myMethod(self):

? ? ? print '調(diào)用子類方法'

c = Child()? ? ? ? ? # 子類實例

c.myMethod()? ? ? ? # 子類調(diào)用重寫方法

執(zhí)行以上代碼輸出結(jié)果如下:

調(diào)用子類方法

基礎(chǔ)重載方法

下表列出了一些通用的功能,你可以在自己的類重寫:

序號方法, 描述 & 簡單的調(diào)用

1__init__ ( self [,args...] )

構(gòu)造函數(shù)

簡單的調(diào)用方法:?obj = className(args)

2__del__( self )

析構(gòu)方法, 刪除一個對象

簡單的調(diào)用方法 :?dell obj

3__repr__( self )

轉(zhuǎn)化為供解釋器讀取的形式

簡單的調(diào)用方法 :?repr(obj)

4__str__( self )

用于將值轉(zhuǎn)化為適于人閱讀的形式

簡單的調(diào)用方法 :?str(obj)

5__cmp__ ( self, x )

對象比較

簡單的調(diào)用方法 :?cmp(obj, x)

運算符重載

Python同樣支持運算符重載趴腋,實例如下:

#!/usr/bin/python

class Vector:

? def __init__(self, a, b):

? ? ? self.a = a

? ? ? self.b = b

? def __str__(self):

? ? ? return 'Vector (%d, %d)' % (self.a, self.b)


? def __add__(self,other):

? ? ? return Vector(self.a + other.a, self.b + other.b)

v1 = Vector(2,10)

v2 = Vector(5,-2)

print v1 + v2

以上代碼執(zhí)行結(jié)果如下所示:

Vector(7,8)

類屬性與方法

類的私有屬性

__private_attrs:兩個下劃線開頭吊说,聲明該屬性為私有论咏,不能在類地外部被使用或直接訪問。在類內(nèi)部的方法中使用時?self.__private_attrs颁井。

類的方法

在類地內(nèi)部厅贪,使用def關(guān)鍵字可以為類定義一個方法,與一般函數(shù)定義不同雅宾,類方法必須包含參數(shù)self,且為第一個參數(shù)

類的私有方法

__private_method:兩個下劃線開頭养涮,聲明該方法為私有方法,不能在類地外部調(diào)用眉抬。在類的內(nèi)部調(diào)用?self.__private_methods

實例

#coding=utf-8

#!/usr/bin/python

class JustCounter:

__secretCount = 0? # 私有變量

publicCount = 0? ? # 公開變量

def count(self):

self.__secretCount += 1

self.publicCount += 1

print self.__secretCount

counter = JustCounter()

counter.count()

counter.count()

print counter.publicCount

print counter.__secretCount? # 報錯贯吓,實例不能訪問私有變量

Python 通過改變名稱來包含類名:

1

2

2

Traceback (most recent call last):

? File "test.py", line 17, in

? ? print counter.__secretCount? # 報錯,實例不能訪問私有變量

AttributeError: JustCounter instance has no attribute '__secretCount'

Python不允許實例化的類訪問私有數(shù)據(jù)蜀变,但你可以使用?object._className__attrName?訪問屬性悄谐,將如下代碼替換以上代碼的最后一行代碼:

.........................

print counter._JustCounter__secretCount

執(zhí)行以上代碼,執(zhí)行結(jié)果如下:

1

2

2

2





八昏苏、python操作mysql數(shù)據(jù)庫

4課時

實驗課

主要內(nèi)容

python操作mysql數(shù)據(jù)庫

Python 標(biāo)準(zhǔn)數(shù)據(jù)庫接口為 Python DB-API尊沸,Python DB-API為開發(fā)人員提供了數(shù)據(jù)庫應(yīng)用編程接口。

Python 數(shù)據(jù)庫接口支持非常多的數(shù)據(jù)庫贤惯,你可以選擇適合你項目的數(shù)據(jù)庫:

GadFly

mSQL

MySQL

PostgreSQL

Microsoft SQL Server 2000

Informix

Interbase

Oracle

Sybase

不同的數(shù)據(jù)庫你需要下載不同的DB API模塊洼专,例如你需要訪問Oracle數(shù)據(jù)庫和Mysql數(shù)據(jù),你需要下載Oracle和MySQL數(shù)據(jù)庫模塊孵构。

DB-API 是一個規(guī)范. 它定義了一系列必須的對象和數(shù)據(jù)庫存取方式, 以便為各種各樣的底層數(shù)據(jù)庫系統(tǒng)和多種多樣的數(shù)據(jù)庫接口程序提供一致的訪問接口 屁商。

Python的DB-API,為大多數(shù)的數(shù)據(jù)庫實現(xiàn)了接口颈墅,使用它連接各數(shù)據(jù)庫后蜡镶,就可以用相同的方式操作各數(shù)據(jù)庫。

Python DB-API使用流程:

引入 API 模塊恤筛。

獲取與數(shù)據(jù)庫的連接官还。

執(zhí)行SQL語句和存儲過程。

關(guān)閉數(shù)據(jù)庫連接毒坛。

什么是MySQLdb?

MySQLdb 是用于Python鏈接Mysql數(shù)據(jù)庫的接口望伦,它實現(xiàn)了 Python 數(shù)據(jù)庫 API 規(guī)范 V2.0,基于 MySQL C API 上建立的煎殷。

如何安裝MySQLdb?

為了用DB-API編寫MySQL腳本屯伞,必須確保已經(jīng)安裝了MySQL。復(fù)制以下代碼豪直,并執(zhí)行:

# encoding: utf-8

#!/usr/bin/python

import MySQLdb

如果執(zhí)行后的輸出結(jié)果如下所示劣摇,意味著你沒有安裝 MySQLdb 模塊:

Traceback (most recent call last):

? File "test.py", line 3, in

? ? import MySQLdb

ImportError: No module named MySQLdb

安裝MySQLdb,請訪問?http://sourceforge.net/projects/mysql-python?弓乙,(Linux平臺可以訪問:https://pypi.python.org/pypi/MySQL-python)從這里可選擇適合您的平臺的安裝包末融,分為預(yù)編譯的二進(jìn)制文件和源代碼安裝包钧惧。

如果您選擇二進(jìn)制文件發(fā)行版本的話,安裝過程基本安裝提示即可完成勾习。如果從源代碼進(jìn)行安裝的話垢乙,則需要切換到MySQLdb發(fā)行版本的頂級目錄,并鍵入下列命令:

$ gunzip MySQL-python-1.2.2.tar.gz

$ tar -xvf MySQL-python-1.2.2.tar

$ cd MySQL-python-1.2.2

$ python setup.py build

$ python setup.py install

注意:請確保您有root權(quán)限來安裝上述模塊语卤。

數(shù)據(jù)庫連接

連接數(shù)據(jù)庫前追逮,請先確認(rèn)以下事項:

您已經(jīng)創(chuàng)建了數(shù)據(jù)庫 TESTDB.

在TESTDB數(shù)據(jù)庫中您已經(jīng)創(chuàng)建了表 EMPLOYEE

EMPLOYEE表字段為 FIRST_NAME, LAST_NAME, AGE, SEX 和 INCOME。

連接數(shù)據(jù)庫TESTDB使用的用戶名為 "testuser" 粹舵,密碼為 "test123",你可以可以自己設(shè)定或者直接使用root用戶名及其密碼钮孵,Mysql數(shù)據(jù)庫用戶授權(quán)請使用Grant命令。

在你的機子上已經(jīng)安裝了 Python MySQLdb 模塊眼滤。

如果您對sql語句不熟悉巴席,可以訪問我們的?SQL基礎(chǔ)教程

實例:

以下實例鏈接Mysql的TESTDB數(shù)據(jù)庫:

# encoding: utf-8

#!/usr/bin/python

import MySQLdb

# 打開數(shù)據(jù)庫連接

db = MySQLdb.connect("localhost","testuser","test123","TESTDB" )

# 使用cursor()方法獲取操作游標(biāo)

cursor = db.cursor()

# 使用execute方法執(zhí)行SQL語句

cursor.execute("SELECT VERSION()")

# 使用 fetchone() 方法獲取一條數(shù)據(jù)庫。

data = cursor.fetchone()

print "Database version : %s " % data

# 關(guān)閉數(shù)據(jù)庫連接

db.close()

執(zhí)行以上腳本輸出結(jié)果如下:

Database version : 5.0.45

創(chuàng)建數(shù)據(jù)庫表

如果數(shù)據(jù)庫連接存在我們可以使用execute()方法來為數(shù)據(jù)庫創(chuàng)建表诅需,如下所示創(chuàng)建表EMPLOYEE:

# encoding: utf-8

#!/usr/bin/python

import MySQLdb

# 打開數(shù)據(jù)庫連接

db = MySQLdb.connect("localhost","testuser","test123","TESTDB" )

# 使用cursor()方法獲取操作游標(biāo)

cursor = db.cursor()

# 如果數(shù)據(jù)表已經(jīng)存在使用 execute() 方法刪除表漾唉。

cursor.execute("DROP TABLE IF EXISTS EMPLOYEE")

# 創(chuàng)建數(shù)據(jù)表SQL語句

sql = """CREATE TABLE EMPLOYEE (

? ? ? ? FIRST_NAME? CHAR(20) NOT NULL,

? ? ? ? LAST_NAME? CHAR(20),

? ? ? ? AGE INT,?

? ? ? ? SEX CHAR(1),

? ? ? ? INCOME FLOAT )"""

cursor.execute(sql)

# 關(guān)閉數(shù)據(jù)庫連接

db.close()

數(shù)據(jù)庫插入操作

以下實例使用執(zhí)行 SQL INSERT 語句向表 EMPLOYEE 插入記錄:

# encoding: utf-8

#!/usr/bin/python

import MySQLdb

# 打開數(shù)據(jù)庫連接

db = MySQLdb.connect("localhost","testuser","test123","TESTDB" )

# 使用cursor()方法獲取操作游標(biāo)

cursor = db.cursor()

# SQL 插入語句

sql = """INSERT INTO EMPLOYEE(FIRST_NAME,

? ? ? ? LAST_NAME, AGE, SEX, INCOME)

? ? ? ? VALUES ('Mac', 'Mohan', 20, 'M', 2000)"""

try:

? # 執(zhí)行sql語句

? cursor.execute(sql)

? # 提交到數(shù)據(jù)庫執(zhí)行

? db.commit()

except:

? # Rollback in case there is any error

? db.rollback()

# 關(guān)閉數(shù)據(jù)庫連接

db.close()

以上例子也可以寫成如下形式:

# encoding: utf-8

#!/usr/bin/python

import MySQLdb

# 打開數(shù)據(jù)庫連接

db = MySQLdb.connect("localhost","testuser","test123","TESTDB" )

# 使用cursor()方法獲取操作游標(biāo)

cursor = db.cursor()

# SQL 插入語句

sql = "INSERT INTO EMPLOYEE(FIRST_NAME, \

? ? ? LAST_NAME, AGE, SEX, INCOME) \

? ? ? VALUES ('%s', '%s', '%d', '%c', '%d' )" % \

? ? ? ('Mac', 'Mohan', 20, 'M', 2000)

try:

? # 執(zhí)行sql語句

? cursor.execute(sql)

? # 提交到數(shù)據(jù)庫執(zhí)行

? db.commit()

except:

? # 發(fā)生錯誤時回滾

? db.rollback()

# 關(guān)閉數(shù)據(jù)庫連接

db.close()

實例:

以下代碼使用變量向SQL語句中傳遞參數(shù):

..................................

user_id = "test123"

password = "password"

con.execute('insert into Login values("%s", "%s")' % \

? ? ? ? ? ? (user_id, password))

..................................

數(shù)據(jù)庫查詢操作

Python查詢Mysql使用 fetchone() 方法獲取單條數(shù)據(jù), 使用fetchall() 方法獲取多條數(shù)據(jù)。

fetchone():?該方法獲取下一個查詢結(jié)果集堰塌。結(jié)果集是一個對象

fetchall():接收全部的返回結(jié)果行.

rowcount:?這是一個只讀屬性赵刑,并返回執(zhí)行execute()方法后影響的行數(shù)。

實例:

查詢EMPLOYEE表中salary(工資)字段大于1000的所有數(shù)據(jù):

# encoding: utf-8

#!/usr/bin/python

import MySQLdb

# 打開數(shù)據(jù)庫連接

db = MySQLdb.connect("localhost","testuser","test123","TESTDB" )

# 使用cursor()方法獲取操作游標(biāo)

cursor = db.cursor()

# SQL 查詢語句

sql = "SELECT * FROM EMPLOYEE \

? ? ? WHERE INCOME > '%d'" % (1000)

try:

? # 執(zhí)行SQL語句

? cursor.execute(sql)

? # 獲取所有記錄列表

? results = cursor.fetchall()

? for row in results:

? ? ? fname = row[0]

? ? ? lname = row[1]

? ? ? age = row[2]

? ? ? sex = row[3]

? ? ? income = row[4]

? ? ? # 打印結(jié)果

? ? ? print "fname=%s,lname=%s,age=%d,sex=%s,income=%d" % \

? ? ? ? ? ? (fname, lname, age, sex, income )

except:

? print "Error: unable to fecth data"

# 關(guān)閉數(shù)據(jù)庫連接

db.close()

以上腳本執(zhí)行結(jié)果如下:

fname=Mac, lname=Mohan, age=20, sex=M, income=2000

數(shù)據(jù)庫更新操作

更新操作用于更新數(shù)據(jù)表的的數(shù)據(jù)场刑,以下實例將 TESTDB表中的 SEX 字段全部修改為 'M'般此,AGE 字段遞增1:

# encoding: utf-8#!/usr/bin/pythonimport MySQLdb# 打開數(shù)據(jù)庫連接db = MySQLdb.connect("localhost","testuser","test123","TESTDB" )# 使用cursor()方法獲取操作游標(biāo) cursor = db.cursor()# SQL 更新語句sql = "UPDATE EMPLOYEE SET AGE = AGE + 1 \

WHERE SEX = '%c'" % ('M')try:? # 執(zhí)行SQL語句? cursor.execute(sql)? # 提交到數(shù)據(jù)庫執(zhí)行? db.commit()except:? # 發(fā)生錯誤時回滾? db.rollback()# 關(guān)閉數(shù)據(jù)庫連接db.close()

執(zhí)行事務(wù)

事務(wù)機制可以確保數(shù)據(jù)一致性。

事務(wù)應(yīng)該具有4個屬性:原子性牵现、一致性铐懊、隔離性、持久性瞎疼。這四個屬性通常稱為ACID特性科乎。

原子性(atomicity)。一個事務(wù)是一個不可分割的工作單位贼急,事務(wù)中包括的諸操作要么都做茅茂,要么都不做。

一致性(consistency)竿裂。事務(wù)必須是使數(shù)據(jù)庫從一個一致性狀態(tài)變到另一個一致性狀態(tài)玉吁。一致性與原子性是密切相關(guān)的照弥。

隔離性(isolation)腻异。一個事務(wù)的執(zhí)行不能被其他事務(wù)干擾。即一個事務(wù)內(nèi)部的操作及使用的數(shù)據(jù)對并發(fā)的其他事務(wù)是隔離的这揣,并發(fā)執(zhí)行的各個事務(wù)之間不能互相干擾悔常。

持久性(durability)影斑。持續(xù)性也稱永久性(permanence),指一個事務(wù)一旦提交机打,它對數(shù)據(jù)庫中數(shù)據(jù)的改變就應(yīng)該是永久性的矫户。接下來的其他操作或故障不應(yīng)該對其有任何影響。

Python DB API 2.0 的事務(wù)提供了兩個方法 commit 或 rollback残邀。

實例:

# SQL刪除記錄語句

sql = "DELETE FROM EMPLOYEE WHERE AGE > '%d'" % (20)

try:

? # 執(zhí)行SQL語句

? cursor.execute(sql)

? # 向數(shù)據(jù)庫提交

? db.commit()

except:

? # 發(fā)生錯誤時回滾

? db.rollback()

對于支持事務(wù)的數(shù)據(jù)庫皆辽, 在Python數(shù)據(jù)庫編程中,當(dāng)游標(biāo)建立之時芥挣,就自動開始了一個隱形的數(shù)據(jù)庫事務(wù)驱闷。

commit()方法游標(biāo)的所有更新操作,rollback()方法回滾當(dāng)前游標(biāo)的所有操作空免。每一個方法都開始了一個新的事務(wù)空另。

錯誤處理

DB API中定義了一些數(shù)據(jù)庫操作的錯誤及異常,下表列出了這些錯誤和異常:

異常描述

Warning當(dāng)有嚴(yán)重警告時觸發(fā)蹋砚,例如插入數(shù)據(jù)是被截斷等等扼菠。必須是 StandardError 的子類。

Error警告以外所有其他錯誤類坝咐。必須是 StandardError 的子類循榆。

InterfaceError當(dāng)有數(shù)據(jù)庫接口模塊本身的錯誤(而不是數(shù)據(jù)庫的錯誤)發(fā)生時觸發(fā)。 必須是Error的子類墨坚。

DatabaseError和數(shù)據(jù)庫有關(guān)的錯誤發(fā)生時觸發(fā)冯痢。 必須是Error的子類。

DataError當(dāng)有數(shù)據(jù)處理時的錯誤發(fā)生時觸發(fā)框杜,例如:除零錯誤浦楣,數(shù)據(jù)超范圍等等。 必須是DatabaseError的子類咪辱。

OperationalError指非用戶控制的振劳,而是操作數(shù)據(jù)庫時發(fā)生的錯誤。例如:連接意外斷開油狂、 數(shù)據(jù)庫名未找到历恐、事務(wù)處理失敗、內(nèi)存分配錯誤等等操作數(shù)據(jù)庫是發(fā)生的錯誤专筷。 必須是DatabaseError的子類弱贼。

IntegrityError完整性相關(guān)的錯誤,例如外鍵檢查失敗等磷蛹。必須是DatabaseError子類欲险。

InternalError數(shù)據(jù)庫的內(nèi)部錯誤,例如游標(biāo)(cursor)失效了邢疙、事務(wù)同步失敗等等。 必須是DatabaseError子類檬嘀。

ProgrammingError程序錯誤,例如數(shù)據(jù)表(table)沒找到或已存在责嚷、SQL語句語法錯誤鸳兽、 參數(shù)數(shù)量錯誤等等。必須是DatabaseError的子類罕拂。

NotSupportedError不支持錯誤揍异,指使用了數(shù)據(jù)庫不支持的函數(shù)或API等。例如在連接對象上 使用.rollback()函數(shù)爆班,然而數(shù)據(jù)庫并不支持事務(wù)或者事務(wù)已關(guān)閉蒿秦。 必須是DatabaseError的子類。





九蛋济、Python 網(wǎng)絡(luò)編程

4課時

實驗課

主要內(nèi)容

Python 網(wǎng)絡(luò)編程

Python 提供了兩個級別訪問的網(wǎng)絡(luò)服務(wù):

低級別的網(wǎng)絡(luò)服務(wù)支持基本的 Socket棍鳖,它提供了標(biāo)準(zhǔn)的 BSD Sockets API,可以訪問底層操作系統(tǒng)Socket接口的全部方法碗旅。

高級別的網(wǎng)絡(luò)服務(wù)模塊 SocketServer渡处, 它提供了服務(wù)器中心類,可以簡化網(wǎng)絡(luò)服務(wù)器的開發(fā)祟辟。

什么是 Socket?

Socket又稱"套接字"医瘫,應(yīng)用程序通常通過"套接字"向網(wǎng)絡(luò)發(fā)出請求或者應(yīng)答網(wǎng)絡(luò)請求,使主機間或者一臺計算機上的進(jìn)程間可以通訊旧困。

socket()函數(shù)

Python 中醇份,我們用 socket()函數(shù)來創(chuàng)建套接字,語法格式如下:

socket.socket([family[, type[, proto]]])

參數(shù)

family: 套接字家族可以使AF_UNIX或者AF_INET

type: 套接字類型可以根據(jù)是面向連接的還是非連接分為SOCK_STREAM或SOCK_DGRAM

protocol: 一般不填默認(rèn)為0.

Socket 對象(內(nèi)建)方法

函數(shù)描述

服務(wù)器端套接字

s.bind()綁定地址(host,port)到套接字吼具, 在AF_INET下,以元組(host,port)的形式表示地址僚纷。

s.listen()開始TCP監(jiān)聽。backlog指定在拒絕連接之前拗盒,操作系統(tǒng)可以掛起的最大連接數(shù)量怖竭。該值至少為1,大部分應(yīng)用程序設(shè)為5就可以了陡蝇。

s.accept()被動接受TCP客戶端連接,(阻塞式)等待連接的到來

客戶端套接字

s.connect()主動初始化TCP服務(wù)器連接痊臭,。一般address的格式為元組(hostname,port)登夫,如果連接出錯广匙,返回socket.error錯誤。

s.connect_ex()connect()函數(shù)的擴展版本,出錯時返回出錯碼,而不是拋出異常

公共用途的套接字函數(shù)

s.recv()接收TCP數(shù)據(jù)恼策,數(shù)據(jù)以字符串形式返回鸦致,bufsize指定要接收的最大數(shù)據(jù)量。flag提供有關(guān)消息的其他信息,通程D可以忽略。

s.send()發(fā)送TCP數(shù)據(jù)总棵,將string中的數(shù)據(jù)發(fā)送到連接的套接字鳍寂。返回值是要發(fā)送的字節(jié)數(shù)量,該數(shù)量可能小于string的字節(jié)大小情龄。

s.sendall()完整發(fā)送TCP數(shù)據(jù)迄汛,完整發(fā)送TCP數(shù)據(jù)。將string中的數(shù)據(jù)發(fā)送到連接的套接字骤视,但在返回之前會嘗試發(fā)送所有數(shù)據(jù)鞍爱。成功返回None,失敗則拋出異常专酗。

s.recvform()接收UDP數(shù)據(jù)睹逃,與recv()類似,但返回值是(data,address)祷肯。其中data是包含接收數(shù)據(jù)的字符串沉填,address是發(fā)送數(shù)據(jù)的套接字地址。

s.sendto()發(fā)送UDP數(shù)據(jù)佑笋,將數(shù)據(jù)發(fā)送到套接字翼闹,address是形式為(ipaddr,port)的元組蒋纬,指定遠(yuǎn)程地址猎荠。返回值是發(fā)送的字節(jié)數(shù)。

s.close()關(guān)閉套接字

s.getpeername()返回連接套接字的遠(yuǎn)程地址蜀备。返回值通常是元組(ipaddr,port)关摇。

s.getsockname()返回套接字自己的地址。通常是一個元組(ipaddr,port)

s.setsockopt(level,optname,value)設(shè)置給定套接字選項的值碾阁。

s.getsockopt(level,optname[.buflen])返回套接字選項的值拒垃。

s.settimeout(timeout)設(shè)置套接字操作的超時期,timeout是一個浮點數(shù)瓷蛙,單位是秒悼瓮。值為None表示沒有超時期。一般艰猬,超時期應(yīng)該在剛創(chuàng)建套接字時設(shè)置横堡,因為它們可能用于連接的操作(如connect())

s.gettimeout()返回當(dāng)前超時期的值,單位是秒冠桃,如果沒有設(shè)置超時期命贴,則返回None。

s.fileno()返回套接字的文件描述符。

s.setblocking(flag)如果flag為0胸蛛,則將套接字設(shè)為非阻塞模式污茵,否則將套接字設(shè)為阻塞模式(默認(rèn)值)。非阻塞模式下葬项,如果調(diào)用recv()沒有發(fā)現(xiàn)任何數(shù)據(jù)泞当,或send()調(diào)用無法立即發(fā)送數(shù)據(jù),那么將引起socket.error異常民珍。

s.makefile()創(chuàng)建一個與該套接字相關(guān)連的文件

簡單實例

服務(wù)端

我們使用 socket 模塊的?socket?函數(shù)來創(chuàng)建一個 socket 對象襟士。socket 對象可以通過調(diào)用其他函數(shù)來設(shè)置一個 socket 服務(wù)。

現(xiàn)在我們可以通過調(diào)用?bind(hostname, port)?函數(shù)來指定服務(wù)的?port(端口)嚷量。

接著陋桂,我們調(diào)用 socket 對象的?accept?方法。該方法等待客戶端的連接蝶溶,并返回?connection?對象嗜历,表示已連接到客戶端。

完整代碼如下:

#!/usr/bin/python

# -*- coding: UTF-8 -*-

# 文件名:server.py

import socket? ? ? ? ? ? ? # 導(dǎo)入 socket 模塊

s = socket.socket()? ? ? ? # 創(chuàng)建 socket 對象

host = socket.gethostname() # 獲取本地主機名

port = 12345? ? ? ? ? ? ? ? # 設(shè)置端口

s.bind((host, port))? ? ? ? # 綁定端口

s.listen(5)? ? ? ? ? ? ? ? # 等待客戶端連接

while True:

? ? c, addr = s.accept()? ? # 建立客戶端連接抖所。

? ? print '連接地址:', addr

? ? c.send('歡迎訪問W3Cschool教程秸脱!')

? ? c.close()? ? ? ? ? ? ? ? # 關(guān)閉連接

客戶端

接下來我們寫一個簡單的客戶端實例連接到以上創(chuàng)建的服務(wù)。端口號為 12345部蛇。

socket.connect(hosname, port )?方法打開一個 TCP 連接到主機為?hostname?端口為?port?的服務(wù)商摊唇。連接后我們就可以從服務(wù)端后期數(shù)據(jù),記住涯鲁,操作完成后需要關(guān)閉連接巷查。

完整代碼如下:

#!/usr/bin/python

# -*- coding: UTF-8 -*-

# 文件名:client.py

import socket? ? ? ? ? ? ? # 導(dǎo)入 socket 模塊

s = socket.socket()? ? ? ? # 創(chuàng)建 socket 對象

host = socket.gethostname() # 獲取本地主機名

port = 12345? ? ? ? ? ? ? ? # 設(shè)置端口好

s.connect((host, port))

print s.recv(1024)

s.close()?

現(xiàn)在我們打開連個終端,第一個終端執(zhí)行 server.py 文件:

$ python server.py

第二個終端執(zhí)行 client.py 文件:

$ python client.py

歡迎訪問W3Cschool教程抹腿!

這是我們再打開第一個終端岛请,就會看到有以下信息輸出:

連接地址: ('192.168.0.118', 62461)

Python Internet 模塊

以下列出了 Python 網(wǎng)絡(luò)編程的一些重要模塊:

協(xié)議功能用處端口號Python 模塊

HTTP網(wǎng)頁訪問80httplib, urllib, xmlrpclib

NNTP閱讀和張貼新聞文章,俗稱為"帖子"119nntplib

FTP文件傳輸20ftplib, urllib

SMTP發(fā)送郵件25smtplib

POP3接收郵件110poplib

IMAP4獲取郵件143imaplib

Telnet命令行23telnetlib

Gopher信息查找70gopherlib, urllib







十警绩、Python 多線程

4課時

實驗課

主要內(nèi)容

Python 多線程

多線程類似于同時執(zhí)行多個不同程序崇败,多線程運行有如下優(yōu)點:

使用線程可以把占據(jù)長時間的程序中的任務(wù)放到后臺去處理。

用戶界面可以更加吸引人肩祥,這樣比如用戶點擊了一個按鈕去觸發(fā)某些事件的處理后室,可以彈出一個進(jìn)度條來顯示處理的進(jìn)度

程序的運行速度可能加快

在一些等待的任務(wù)實現(xiàn)上如用戶輸入、文件讀寫和網(wǎng)絡(luò)收發(fā)數(shù)據(jù)等混狠,線程就比較有用了岸霹。在這種情況下我們可以釋放一些珍貴的資源如內(nèi)存占用等等。

線程在執(zhí)行過程中與進(jìn)程還是有區(qū)別的将饺。每個獨立的線程有一個程序運行的入口贡避、順序執(zhí)行序列和程序的出口痛黎。但是線程不能夠獨立執(zhí)行,必須依存在應(yīng)用程序中刮吧,由應(yīng)用程序提供多個線程執(zhí)行控制湖饱。

每個線程都有他自己的一組CPU寄存器,稱為線程的上下文杀捻,該上下文反映了線程上次運行該線程的CPU寄存器的狀態(tài)井厌。

指令指針和堆棧指針寄存器是線程上下文中兩個最重要的寄存器,線程總是在進(jìn)程得到上下文中運行的水醋,這些地址都用于標(biāo)志擁有線程的進(jìn)程地址空間中的內(nèi)存旗笔。

線程可以被搶占(中斷)彪置。

在其他線程正在運行時枫绅,線程可以暫時擱置(也稱為睡眠) -- 這就是線程的退讓撮奏。

開始學(xué)習(xí)Python線程

Python中使用線程有兩種方式:函數(shù)或者用類來包裝線程對象。

函數(shù)式:調(diào)用thread模塊中的start_new_thread()函數(shù)來產(chǎn)生新線程。語法如下:

thread.start_new_thread ( function, args[, kwargs] )

參數(shù)說明:

function - 線程函數(shù)忠寻。

args - 傳遞給線程函數(shù)的參數(shù),他必須是個tuple類型。

kwargs - 可選參數(shù)线婚。

實例:

#!/usr/bin/python

# -*- coding: UTF-8 -*-

import thread

import time

# 為線程定義一個函數(shù)

def print_time( threadName, delay):

? ?count = 0

? ?while count < 5:

? ? ? time.sleep(delay)

? ? ? count += 1

? ? ? print "%s: %s" % ( threadName, time.ctime(time.time()) )

# 創(chuàng)建兩個線程

try:

? ?thread.start_new_thread( print_time, ("Thread-1", 2, ) )

? ?thread.start_new_thread( print_time, ("Thread-2", 4, ) )

except:

? ?print "Error: unable to start thread"

while 1:

? ?pass

執(zhí)行以上程序輸出結(jié)果如下:

Thread-1: Thu Jan 22 15:42:17 2009

Thread-1: Thu Jan 22 15:42:19 2009

Thread-2: Thu Jan 22 15:42:19 2009

Thread-1: Thu Jan 22 15:42:21 2009

Thread-2: Thu Jan 22 15:42:23 2009

Thread-1: Thu Jan 22 15:42:23 2009

Thread-1: Thu Jan 22 15:42:25 2009

Thread-2: Thu Jan 22 15:42:27 2009

Thread-2: Thu Jan 22 15:42:31 2009

Thread-2: Thu Jan 22 15:42:35 2009

線程的結(jié)束一般依靠線程函數(shù)的自然結(jié)束匈织;也可以在線程函數(shù)中調(diào)用thread.exit(),他拋出SystemExit exception授舟,達(dá)到退出線程的目的救恨。

線程模塊

Python通過兩個標(biāo)準(zhǔn)庫thread和threading提供對線程的支持。thread提供了低級別的释树、原始的線程以及一個簡單的鎖肠槽。

thread 模塊提供的其他方法:

threading.currentThread(): 返回當(dāng)前的線程變量。

threading.enumerate(): 返回一個包含正在運行的線程的list奢啥。正在運行指線程啟動后秸仙、結(jié)束前,不包括啟動前和終止后的線程桩盲。

threading.activeCount(): 返回正在運行的線程數(shù)量寂纪,與len(threading.enumerate())有相同的結(jié)果。

除了使用方法外赌结,線程模塊同樣提供了Thread類來處理線程捞蛋,Thread類提供了以下方法:

run():?用以表示線程活動的方法。

start():啟動線程活動柬姚。

join([time]):?等待至線程中止襟交。這阻塞調(diào)用線程直至線程的join() 方法被調(diào)用中止-正常退出或者拋出未處理的異常-或者是可選的超時發(fā)生。

isAlive():?返回線程是否活動的伤靠。

getName():?返回線程名捣域。

setName():?設(shè)置線程名啼染。

使用Threading模塊創(chuàng)建線程

使用Threading模塊創(chuàng)建線程,直接從threading.Thread繼承焕梅,然后重寫__init__方法和run方法:

#coding=utf-8

#!/usr/bin/python

import threading

import time

exitFlag = 0

class myThread (threading.Thread):? #繼承父類threading.Thread

? ? def __init__(self, threadID, name, counter):

? ? ? ? threading.Thread.__init__(self)

? ? ? ? self.threadID = threadID

? ? ? ? self.name = name

? ? ? ? self.counter = counter

? ? def run(self):? ? ? ? ? ? ? ? ? #把要執(zhí)行的代碼寫到run函數(shù)里面 線程在創(chuàng)建后會直接運行run函數(shù)

? ? ? ? print "Starting " + self.name

? ? ? ? print_time(self.name, self.counter, 5)

? ? ? ? print "Exiting " + self.name

def print_time(threadName, delay, counter):

? ? while counter:

? ? ? ? if exitFlag:

? ? ? ? ? ? thread.exit()

? ? ? ? time.sleep(delay)

? ? ? ? print "%s: %s" % (threadName, time.ctime(time.time()))

? ? ? ? counter -= 1

# 創(chuàng)建新線程

thread1 = myThread(1, "Thread-1", 1)

thread2 = myThread(2, "Thread-2", 2)

# 開啟線程

thread1.start()

thread2.start()

print "Exiting Main Thread"

以上程序執(zhí)行結(jié)果如下迹鹅;

Starting Thread-1

Starting Thread-2

Exiting Main Thread

Thread-1: Thu Mar 21 09:10:03 2013

Thread-1: Thu Mar 21 09:10:04 2013

Thread-2: Thu Mar 21 09:10:04 2013

Thread-1: Thu Mar 21 09:10:05 2013

Thread-1: Thu Mar 21 09:10:06 2013

Thread-2: Thu Mar 21 09:10:06 2013

Thread-1: Thu Mar 21 09:10:07 2013

Exiting Thread-1

Thread-2: Thu Mar 21 09:10:08 2013

Thread-2: Thu Mar 21 09:10:10 2013

Thread-2: Thu Mar 21 09:10:12 2013

Exiting Thread-2

線程同步

如果多個線程共同對某個數(shù)據(jù)修改,則可能出現(xiàn)不可預(yù)料的結(jié)果贞言,為了保證數(shù)據(jù)的正確性斜棚,需要對多個線程進(jìn)行同步。

使用Thread對象的Lock和Rlock可以實現(xiàn)簡單的線程同步该窗,這兩個對象都有acquire方法和release方法弟蚀,對于那些需要每次只允許一個線程操作的數(shù)據(jù),可以將其操作放到acquire和release方法之間酗失。如下:

多線程的優(yōu)勢在于可以同時運行多個任務(wù)(至少感覺起來是這樣)义钉。但是當(dāng)線程需要共享數(shù)據(jù)時,可能存在數(shù)據(jù)不同步的問題规肴。

考慮這樣一種情況:一個列表里所有元素都是0捶闸,線程"set"從后向前把所有元素改成1,而線程"print"負(fù)責(zé)從前往后讀取列表并打印拖刃。

那么删壮,可能線程"set"開始改的時候,線程"print"便來打印列表了兑牡,輸出就成了一半0一半1央碟,這就是數(shù)據(jù)的不同步。為了避免這種情況均函,引入了鎖的概念亿虽。

鎖有兩種狀態(tài)——鎖定和未鎖定。每當(dāng)一個線程比如"set"要訪問共享數(shù)據(jù)時边酒,必須先獲得鎖定经柴;如果已經(jīng)有別的線程比如"print"獲得鎖定了,那么就讓線程"set"暫停墩朦,也就是同步阻塞坯认;等到線程"print"訪問完畢,釋放鎖以后氓涣,再讓線程"set"繼續(xù)牛哺。

經(jīng)過這樣的處理,打印列表時要么全部輸出0劳吠,要么全部輸出1引润,不會再出現(xiàn)一半0一半1的尷尬場面。

實例:

#coding=utf-8

#!/usr/bin/python

import threading

import time

class myThread (threading.Thread):

? ? def __init__(self, threadID, name, counter):

? ? ? ? threading.Thread.__init__(self)

? ? ? ? self.threadID = threadID

? ? ? ? self.name = name

? ? ? ? self.counter = counter

? ? def run(self):

? ? ? ? print "Starting " + self.name

? ? ? # 獲得鎖痒玩,成功獲得鎖定后返回True

? ? ? # 可選的timeout參數(shù)不填時將一直阻塞直到獲得鎖定

? ? ? # 否則超時后將返回False

? ? ? ? threadLock.acquire()

? ? ? ? print_time(self.name, self.counter, 3)

? ? ? ? # 釋放鎖

? ? ? ? threadLock.release()

def print_time(threadName, delay, counter):

? ? while counter:

? ? ? ? time.sleep(delay)

? ? ? ? print "%s: %s" % (threadName, time.ctime(time.time()))

? ? ? ? counter -= 1

threadLock = threading.Lock()

threads = []

# 創(chuàng)建新線程

thread1 = myThread(1, "Thread-1", 1)

thread2 = myThread(2, "Thread-2", 2)

# 開啟新線程

thread1.start()

thread2.start()

# 添加線程到線程列表

threads.append(thread1)

threads.append(thread2)

# 等待所有線程完成

for t in threads:

? ? t.join()

print "Exiting Main Thread"

線程優(yōu)先級隊列( Queue)

Python的Queue模塊中提供了同步的淳附、線程安全的隊列類议慰,包括FIFO(先入先出)隊列Queue,LIFO(后入先出)隊列LifoQueue奴曙,和優(yōu)先級隊列PriorityQueue别凹。這些隊列都實現(xiàn)了鎖原語,能夠在多線程中直接使用洽糟÷疲可以使用隊列來實現(xiàn)線程間的同步。

Queue模塊中的常用方法:

Queue.qsize() 返回隊列的大小

Queue.empty() 如果隊列為空坤溃,返回True,反之False

Queue.full() 如果隊列滿了拍霜,返回True,反之False

Queue.full 與 maxsize 大小對應(yīng)

Queue.get([block[, timeout]])獲取隊列,timeout等待時間

Queue.get_nowait() 相當(dāng)Queue.get(False)

Queue.put(item) 寫入隊列薪介,timeout等待時間

Queue.put_nowait(item) 相當(dāng)Queue.put(item, False)

Queue.task_done() 在完成一項工作之后祠饺,Queue.task_done()函數(shù)向任務(wù)已經(jīng)完成的隊列發(fā)送一個信號

Queue.join() 實際上意味著等到隊列為空,再執(zhí)行別的操作

實例:

#coding=utf-8

#!/usr/bin/python

import Queue

import threading

import time

exitFlag = 0

class myThread (threading.Thread):

? ? def __init__(self, threadID, name, q):

? ? ? ? threading.Thread.__init__(self)

? ? ? ? self.threadID = threadID

? ? ? ? self.name = name

? ? ? ? self.q = q

? ? def run(self):

? ? ? ? print "Starting " + self.name

? ? ? ? process_data(self.name, self.q)

? ? ? ? print "Exiting " + self.name

def process_data(threadName, q):

? ? while not exitFlag:

? ? ? ? queueLock.acquire()

? ? ? ? if not workQueue.empty():

? ? ? ? ? ? data = q.get()

? ? ? ? ? ? queueLock.release()

? ? ? ? ? ? print "%s processing %s" % (threadName, data)

? ? ? ? else:

? ? ? ? ? ? queueLock.release()

? ? ? ? time.sleep(1)

threadList = ["Thread-1", "Thread-2", "Thread-3"]

nameList = ["One", "Two", "Three", "Four", "Five"]

queueLock = threading.Lock()

workQueue = Queue.Queue(10)

threads = []

threadID = 1

# 創(chuàng)建新線程

for tName in threadList:

? ? thread = myThread(threadID, tName, workQueue)

? ? thread.start()

? ? threads.append(thread)

? ? threadID += 1

# 填充隊列

queueLock.acquire()

for word in nameList:

? ? workQueue.put(word)

queueLock.release()

# 等待隊列清空

while not workQueue.empty():

? ? pass

# 通知線程是時候退出

exitFlag = 1

# 等待所有線程完成

for t in threads:

? ? t.join()

print "Exiting Main Thread"

以上程序執(zhí)行結(jié)果:

Starting Thread-1

Starting Thread-2

Starting Thread-3

Thread-1 processing One

Thread-2 processing Two

Thread-3 processing Three

Thread-1 processing Four

Thread-2 processing Five

Exiting Thread-3

Exiting Thread-1

Exiting Thread-2

Exiting Main Thread




十一昭灵、Linux 入門和安裝

4課時

實驗課

主要內(nèi)容

Linux?簡介

Linux內(nèi)核最初只是由芬蘭人李納斯·托瓦茲(Linus Torvalds)在赫爾辛基大學(xué)上學(xué)時出于個人愛好而編寫的吠裆。

Linux是一套免費使用和自由傳播的類Unix操作系統(tǒng)伐谈,是一個基于POSIX和UNIX的多用戶烂完、多任務(wù)、支持多線程和多CPU的操作系統(tǒng)诵棵。

Linux能運行主要的UNIX工具軟件抠蚣、應(yīng)用程序和網(wǎng)絡(luò)協(xié)議。它支持32位和64位硬件履澳。Linux繼承了Unix以網(wǎng)絡(luò)為核心的設(shè)計思想嘶窄,是一個性能穩(wěn)定的多用戶網(wǎng)絡(luò)操作系統(tǒng)。

Linux的發(fā)行版

Linux的發(fā)行版說簡單點就是將Linux內(nèi)核與應(yīng)用軟件做一個打包距贷。

目前市面上較知名的發(fā)行版有:Ubuntu柄冲、RedHat、CentOS忠蝗、Debian现横、Fedora、SuSE阁最、OpenSUSE戒祠、TurboLinux、BluePoint速种、RedFlag姜盈、Xterm、SlackWare等配阵。

Linux應(yīng)用領(lǐng)域

今天各種場合都有使用各種Linux發(fā)行版馏颂,從嵌入式設(shè)備到超級計算機示血,并且在服務(wù)器領(lǐng)域確定了地位,通常服務(wù)器使用LAMP(Linux + Apache + MySQL + PHP)或LNMP(Linux + Nginx+ MySQL + PHP)組合救拉。

目前Linux不僅在家庭與企業(yè)中使用矾芙,并且在政府中也很受歡迎。

巴西聯(lián)邦政府由于支持Linux而世界聞名近上。

有新聞報道俄羅斯軍隊自己制造的Linux發(fā)布版的剔宪,做為G.H.ost項目已經(jīng)取得成果.

印度的Kerala聯(lián)邦計劃在向全聯(lián)邦的高中推廣使用Linux。

中華人民共和國為取得技術(shù)獨立壹无,在龍芯過程中排他性地使用Linux葱绒。

在西班牙的一些地區(qū)開發(fā)了自己的Linux發(fā)布版,并且在政府與教育領(lǐng)域廣泛使用斗锭,如Extremadura地區(qū)的gnuLinEx和Andalusia地區(qū)的Guadalinex地淀。

葡萄牙同樣使用自己的Linux發(fā)布版Caixa Mágica,用于Magalh?es筆記本電腦和e-escola政府軟件岖是。

法國和德國同樣開始逐步采用Linux帮毁。

Linux vs Window

目前國內(nèi)Linux更多的是應(yīng)用于服務(wù)器上,而桌面操作系統(tǒng)更多使用的是Window豺撑。主要區(qū)別如下:

比較WindowsLinux

界面界面統(tǒng)一烈疚,外殼程序固定所有Windows程序菜單幾乎一致,快捷鍵也幾乎相同圖形界面風(fēng)格依發(fā)布版不同而不同聪轿,可能互不兼容爷肝。GNU/Linux的終端機是從UNIX傳承下來,基本命令和操作方法也幾乎一致陆错。

驅(qū)動程序驅(qū)動程序豐富啤斗,版本更新頻繁肢础。默認(rèn)安裝程序里面一般包含有該版本發(fā)布時流行的硬件驅(qū)動程序跳昼,之后所出的新硬件驅(qū)動依賴于硬件廠商提供瓣俯。對于一些老硬件,如果沒有了原配的驅(qū)動有時很難支持绳慎。另外纵竖,有時硬件廠商未提供所需版本的Windows下的驅(qū)動,也會比較頭痛偷线。由志愿者開發(fā)磨确,由Linux核心開發(fā)小組發(fā)布,很多硬件廠商基于版權(quán)考慮并未提供驅(qū)動程序声邦,盡管多數(shù)無需手動安裝乏奥,但是涉及安裝則相對復(fù)雜,使得新用戶面對驅(qū)動程序問題(是否存在和安裝方法)會一籌莫展亥曹。但是在開源開發(fā)模式下邓了,許多老硬件盡管在Windows下很難支持的也容易找到驅(qū)動恨诱。HP、Intel骗炉、AMD等硬件廠商逐步不同程度支持開源驅(qū)動照宝,問題正在得到緩解。

使用使用比較簡單句葵,容易入門厕鹃。圖形化界面對沒有計算機背景知識的用戶使用十分有利。圖形界面使用簡單乍丈,容易入門剂碴。文字界面,需要學(xué)習(xí)才能掌握轻专。

學(xué)習(xí)系統(tǒng)構(gòu)造復(fù)雜忆矛、變化頻繁,且知識请垛、技能淘汰快催训,深入學(xué)習(xí)困難。系統(tǒng)構(gòu)造簡單宗收、穩(wěn)定漫拭,且知識、技能傳承性好镜雨,深入學(xué)習(xí)相對容易嫂侍。

軟件每一種特定功能可能都需要商業(yè)軟件的支持儿捧,需要購買相應(yīng)的授權(quán)荚坞。大部分軟件都可以自由獲取,同樣功能的軟件選擇較少菲盾。


Linux?安裝

centos6.4 為例颓影。

centos6.4 下載地址:

網(wǎng)易鏡像:http://mirrors.163.com/centos/6/isos/

搜狐鏡像:http://mirrors.sohu.com/centos/6/isos/

注:建議安裝64位Linux系統(tǒng)。

接下來你需要將下載的Linux系統(tǒng)刻錄成光盤或U盤懒鉴。

注:你也可以在Window上安裝VMware虛擬機來安裝Linux系統(tǒng)诡挂。

Linux 安裝步驟

1、首先临谱,使用光驅(qū)或U盤或你下載的Linux ISO文件進(jìn)行安裝璃俗。

界面說明:

Install or upgrade an existing system 安裝或升級現(xiàn)有的系統(tǒng)

install system with basic video driver 安裝過程中采用基本的顯卡驅(qū)動

Rescue installed system 進(jìn)入系統(tǒng)修復(fù)模式

Boot from local drive?? 退出安裝從硬盤啟動

Memory test? 內(nèi)存檢測

注:用聯(lián)想E49安裝時選擇第一項安裝時會出現(xiàn)屏幕顯示異常的問題,后改用第二項安裝時就沒有出現(xiàn)問題

2悉默、介質(zhì)直接"skip"就可以了

3城豁、出現(xiàn)引導(dǎo)界面,點擊"next"

4抄课、選中"English(English)"否則會有部分亂碼問題

5唱星、鍵盤布局選擇"U.S.English"

6雳旅、選擇"Basic Storage Devies"點擊"Next"

7、詢問是否忽略所有數(shù)據(jù)间聊,新電腦安裝系統(tǒng)選擇"Yes,discard any data"

8攒盈、Hostname填寫格式"英文名.姓"

9、網(wǎng)絡(luò)設(shè)置安裝圖示順序點擊就可以了

10哎榴、時區(qū)可以在地圖上點擊型豁,選擇"shanghai"并取消System clock uses UTC前面的對勾

11、設(shè)置root的密碼

12尚蝌、硬盤分區(qū)偷遗,一定要按照圖示點選

13、調(diào)整分區(qū)驼壶,必須要有/home這個分區(qū)氏豌,如果沒有這個分區(qū),安裝部分軟件會出現(xiàn)不能安裝的問題

14热凹、詢問是否格式化分區(qū)

15泵喘、將更改寫入到硬盤

16、引導(dǎo)程序安裝位置

17般妙、最重要的一步纪铺,也是本教程最關(guān)鍵的一步,也是其他教程沒有提及的一步碟渺,按圖示順序點擊

18鲜锚、取消以下內(nèi)容的所有選項

Applications

Base System

Servers

并對Desktops進(jìn)行如下設(shè)置

即取消如下選項:

Desktop Debugging and Performance Tools

Desktop Platform

Remote Desktop Clients

Input Methods中僅保留ibus-pinyin-1.3.8-1.el6.x86_64,其他的全部取消

19、選中Languages苫拍,并選中右側(cè)的Chinese Support然后點擊紅色區(qū)域

20芜繁、調(diào)整完成后如下圖所示

21、至此绒极,一個最精簡的桌面環(huán)境就設(shè)置完成了骏令,

22、安裝完成垄提,重啟

23榔袋、重啟之后,的License Information

24铡俐、Create User

Username:填寫您的英文名(不帶.姓)

Full Name:填寫您的英文名.姓(首字母大寫)

25凰兑、"Date and Time" 選中 "Synchronize data and time over the network"

Finsh之后系統(tǒng)將重啟

26、第一次登錄审丘,登錄前不要做任何更改吏够,這個很重要!!稿饰!登錄之后緊接著退出

第二次登錄锦秒,選擇語言,在紅色區(qū)域選擇下拉小三角喉镰,選other旅择,選中"漢語(中國)"

27、登錄之后侣姆,請一定按照如下順序點擊生真!

至此,CentOS安裝完成捺宗,如有其他問題柱蟀,請隨時與我聯(lián)系!蚜厉!




十二长已、Linux系統(tǒng)啟動過程和目錄結(jié)構(gòu)

4課時

實驗課

主要內(nèi)容

Linux?系統(tǒng)啟動過程

linux啟動時我們會看到許多啟動信息。

Linux系統(tǒng)的啟動過程并不是大家想象中的那么復(fù)雜昼牛,其過程可以分為5個階段:

內(nèi)核的引導(dǎo)术瓮。

運行init。

系統(tǒng)初始化贰健。

建立終端 胞四。

用戶登錄系統(tǒng)。

內(nèi)核引導(dǎo)

當(dāng)計算機打開電源后伶椿,首先是BIOS開機自檢辜伟,按照BIOS中設(shè)置的啟動設(shè)備(通常是硬盤)來啟動。

操作系統(tǒng)接管硬件以后脊另,首先讀入 /boot 目錄下的內(nèi)核文件导狡。

運行init

init 進(jìn)程是系統(tǒng)所有進(jìn)程的起點,你可以把它比擬成系統(tǒng)所有進(jìn)程的老祖宗尝蠕,沒有這個進(jìn)程烘豌,系統(tǒng)中任何進(jìn)程都不會啟動。

init 程序首先是需要讀取配置文件 /etc/inittab看彼。

運行級別

許多程序需要開機啟動。它們在Windows叫做"服務(wù)"(service)囚聚,在Linux就叫做"守護(hù)進(jìn)程"(daemon)靖榕。

init進(jìn)程的一大任務(wù),就是去運行這些開機啟動的程序顽铸。

但是茁计,不同的場合需要啟動不同的程序,比如用作服務(wù)器時,需要啟動Apache星压,用作桌面就不需要践剂。

Linux允許為不同的場合,分配不同的開機啟動程序娜膘,這就叫做"運行級別"(runlevel)。也就是說,啟動時根據(jù)"運行級別"牲证,確定要運行哪些程序玫荣。

Linux系統(tǒng)有7個運行級別(runlevel):

運行級別0:系統(tǒng)停機狀態(tài),系統(tǒng)默認(rèn)運行級別不能設(shè)為0演怎,否則不能正常啟動

運行級別1:單用戶工作狀態(tài)匕争,root權(quán)限,用于系統(tǒng)維護(hù)爷耀,禁止遠(yuǎn)程登陸

運行級別2:多用戶狀態(tài)(沒有NFS)

運行級別3:完全的多用戶狀態(tài)(有NFS)甘桑,登陸后進(jìn)入控制臺命令行模式

運行級別4:系統(tǒng)未使用,保留

運行級別5:X11控制臺歹叮,登陸后進(jìn)入圖形GUI模式

運行級別6:系統(tǒng)正常關(guān)閉并重啟扇住,默認(rèn)運行級別不能設(shè)為6,否則不能正常啟動

系統(tǒng)初始化

在init的配置文件中有這么一行: si::sysinit:/etc/rc.d/rc.sysinit 它調(diào)用執(zhí)行了/etc/rc.d/rc.sysinit盗胀,而rc.sysinit是一個bash shell的腳本艘蹋,它主要是完成一些系統(tǒng)初始化的工作,rc.sysinit是每一個運行級別都要首先運行的重要腳本票灰。

它主要完成的工作有:激活交換分區(qū)女阀,檢查磁盤,加載硬件模塊以及其它一些需要優(yōu)先執(zhí)行任務(wù)屑迂。

l5:5:wait:/etc/rc.d/rc 5

這一行表示以5為參數(shù)運行/etc/rc.d/rc浸策,/etc/rc.d/rc是一個Shell腳本,它接受5作為參數(shù)惹盼,去執(zhí)行/etc/rc.d/rc5.d/目錄下的所有的rc啟動腳本庸汗,/etc/rc.d/rc5.d/目錄中的這些啟動腳本實際上都是一些連接文件,而不是真正的rc啟動腳本手报,真正的rc啟動腳本實際上都是放在/etc/rc.d/init.d/目錄下蚯舱。

而這些rc啟動腳本有著類似的用法,它們一般能接受start掩蛤、stop枉昏、restart、status等參數(shù)揍鸟。

/etc/rc.d/rc5.d/中的rc啟動腳本通常是K或S開頭的連接文件兄裂,對于以以S開頭的啟動腳本,將以start參數(shù)來運行。

而如果發(fā)現(xiàn)存在相應(yīng)的腳本也存在K打頭的連接晰奖,而且已經(jīng)處于運行態(tài)了(以/var/lock/subsys/下的文件作為標(biāo)志)谈撒,則將首先以stop為參數(shù)停止這些已經(jīng)啟動了的守護(hù)進(jìn)程,然后再重新運行匾南。

這樣做是為了保證是當(dāng)init改變運行級別時啃匿,所有相關(guān)的守護(hù)進(jìn)程都將重啟。

至于在每個運行級中將運行哪些守護(hù)進(jìn)程午衰,用戶可以通過chkconfig或setup中的"System Services"來自行設(shè)定立宜。

建立終端

rc執(zhí)行完畢后,返回init臊岸。這時基本系統(tǒng)環(huán)境已經(jīng)設(shè)置好了橙数,各種守護(hù)進(jìn)程也已經(jīng)啟動了。

init接下來會打開6個終端帅戒,以便用戶登錄系統(tǒng)灯帮。在inittab中的以下6行就是定義了6個終端:

1:2345:respawn:/sbin/mingetty tty1

2:2345:respawn:/sbin/mingetty tty2

3:2345:respawn:/sbin/mingetty tty3

4:2345:respawn:/sbin/mingetty tty4

5:2345:respawn:/sbin/mingetty tty5

6:2345:respawn:/sbin/mingetty tty6

從上面可以看出在2、3逻住、4钟哥、5的運行級別中都將以respawn方式運行mingetty程序,mingetty程序能打開終端瞎访、設(shè)置模式腻贰。

同時它會顯示一個文本登錄界面,這個界面就是我們經(jīng)嘲墙眨看到的登錄界面播演,在這個登錄界面中會提示用戶輸入用戶名,而用戶輸入的用戶將作為參數(shù)傳給login程序來驗證用戶的身份伴奥。

用戶登錄系統(tǒng)

一般來說写烤,用戶的登錄方式有三種:

(1)命令行登錄

(2)ssh登錄

(3)圖形界面登錄

對于運行級別為5的圖形方式用戶來說,他們的登錄是通過一個圖形化的登錄界面拾徙。登錄成功后可以直接進(jìn)入KDE洲炊、Gnome等窗口管理器。

而本文主要講的還是文本方式登錄的情況:當(dāng)我們看到mingetty的登錄界面時尼啡,我們就可以輸入用戶名和密碼來登錄系統(tǒng)了暂衡。

Linux的賬號驗證程序是login,login會接收mingetty傳來的用戶名作為用戶名參數(shù)玄叠。

然后login會對用戶名進(jìn)行分析:如果用戶名不是root古徒,且存在/etc/nologin文件,login將輸出nologin文件的內(nèi)容读恃,然后退出。

這通常用來系統(tǒng)維護(hù)時防止非root用戶登錄寺惫。只有/etc/securetty中登記了的終端才允許root用戶登錄西雀,如果不存在這個文件艇肴,則root可以在任何終端上登錄冲九。

/etc/usertty文件用于對用戶作出附加訪問限制,如果不存在這個文件甚疟,則沒有其他限制黄痪。

圖形模式與文字模式的切換方式

Linux預(yù)設(shè)提供了六個命令窗口終端機讓我們來登錄。

默認(rèn)我們登錄的就是第一個窗口遭铺,也就是tty1馁筐,這個六個窗口分別為tty1,tty2 … tty6盟迟,你可以按下Ctrl + Alt + F1 ~ F6 來切換它們要尔。

如果你安裝了圖形界面还惠,默認(rèn)情況下是進(jìn)入圖形界面的锣光,此時你就可以按Ctrl + Alt + F1 ~ F6來進(jìn)入其中一個命令窗口界面频丘。

當(dāng)你進(jìn)入命令窗口界面后再返回圖形界面只要按下Ctrl + Alt + F7 就回來了而克。

如果你用的vmware 虛擬機,命令窗口切換的快捷鍵為 Alt + Space + F1~F6. 如果你在圖形界面下請按Alt + Shift + Ctrl + F1~F6 切換至命令窗口。

Linux 關(guān)機

在linux領(lǐng)域內(nèi)大多用在服務(wù)器上宿接,很少遇到關(guān)機的操作蚣旱。畢竟服務(wù)器上跑一個服務(wù)是永無止境的异吻,除非特殊情況下懊昨,不得已才會關(guān)機躏惋。

正確的關(guān)機流程為:sync > shutdown > reboot > halt

關(guān)機指令為:shutdown 准潭,你可以man shutdown 來看一下幫助文檔。

例如你可以運行如下命令關(guān)機:

sync 將數(shù)據(jù)由內(nèi)存同步到硬盤中蝠检。

shutdown 關(guān)機指令憔涉,你可以man shutdown 來看一下幫助文檔国旷。例如你可以運行如下命令關(guān)機:

shutdown –h 10 ‘This server will shutdown after 10 mins’ 這個命令告訴大家忆首,計算機將在10分鐘后關(guān)機,并且會顯示在登陸用戶的當(dāng)前屏幕中漠酿。

Shutdown –h now 立馬關(guān)機

Shutdown –h 20:25 系統(tǒng)會在今天20:25關(guān)機

Shutdown –h +10 十分鐘后關(guān)機

Shutdown –r now 系統(tǒng)立馬重啟

Shutdown –r +10 系統(tǒng)十分鐘后重啟

reboot 就是重啟,等同于 shutdown –r now

halt 關(guān)閉系統(tǒng)衷咽,等同于shutdown –h now 和 poweroff

最后總結(jié)一下,不管是重啟系統(tǒng)還是關(guān)閉系統(tǒng)唤衫,首先要運行sync命令份帐,把內(nèi)存中的數(shù)據(jù)寫到磁盤中巴元。

關(guān)機的命令有 shutdown –h now halt poweroff 和 init 0 , 重啟系統(tǒng)的命令有 shutdown –r now , reboot?和?init 6.


Linux?系統(tǒng)目錄結(jié)構(gòu)

登錄系統(tǒng)后纹安,在當(dāng)前命令窗口下輸入命令:

?ls /?

你會看到如下圖所示:

樹狀目錄結(jié)構(gòu):

以下是對這些目錄的解釋:

/bin

bin是Binary的縮寫, 這個目錄存放著最經(jīng)常使用的命令。

/boot:

這里存放的是啟動Linux時使用的一些核心文件努隙,包括一些連接文件以及鏡像文件张惹。

/dev :

dev是Device(設(shè)備)的縮寫, 該目錄下存放的是Linux的外部設(shè)備告私,在Linux中訪問設(shè)備的方式和訪問文件的方式是相同的番挺。

/etc:

這個目錄用來存放所有的系統(tǒng)管理所需要的配置文件和子目錄瀑晒。

/home

用戶的主目錄,在Linux中向臀,每個用戶都有一個自己的目錄叉庐,一般該目錄名是以用戶的賬號命名的。

/lib

這個目錄里存放著系統(tǒng)最基本的動態(tài)連接共享庫昵慌,其作用類似于Windows里的DLL文件裁眯。幾乎所有的應(yīng)用程序都需要用到這些共享庫。

/lost+found

這個目錄一般情況下是空的搔课,當(dāng)系統(tǒng)非法關(guān)機后却桶,這里就存放了一些文件黔攒。

/media?linux系統(tǒng)會自動識別一些設(shè)備,例如U盤留拾、光驅(qū)等等搔驼,當(dāng)識別后,linux會把識別的設(shè)備掛載到這個目錄下。

/mnt

系統(tǒng)提供該目錄是為了讓用戶臨時掛載別的文件系統(tǒng)的温技,我們可以將光驅(qū)掛載在/mnt/上,然后進(jìn)入該目錄就可以查看光驅(qū)里的內(nèi)容了舵鳞。

/opt

這是給主機額外安裝軟件所擺放的目錄震檩。比如你安裝一個ORACLE數(shù)據(jù)庫則就可以放到這個目錄下。默認(rèn)是空的蜓堕。

/proc

這個目錄是一個虛擬的目錄抛虏,它是系統(tǒng)內(nèi)存的映射,我們可以通過直接訪問這個目錄來獲取系統(tǒng)信息套才。

這個目錄的內(nèi)容不在硬盤上而是在內(nèi)存里尖昏,我們也可以直接修改里面的某些文件山害,比如可以通過下面的命令來屏蔽主機的ping命令,使別人無法ping你的機器:

echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all

/root

該目錄為系統(tǒng)管理員,也稱作超級權(quán)限者的用戶主目錄抚岗。

/sbin

s就是Super User的意思,這里存放的是系統(tǒng)管理員使用的系統(tǒng)管理程序组贺。

/selinux

這個目錄是Redhat/CentOS所特有的目錄泡躯,Selinux是一個安全機制,類似于windows的防火墻崎逃,但是這套機制比較復(fù)雜掷倔,這個目錄就是存放selinux相關(guān)的文件的。

/srv

該目錄存放一些服務(wù)啟動之后需要提取的數(shù)據(jù)个绍。

/sys

這是linux2.6內(nèi)核的一個很大的變化勒葱。該目錄下安裝了2.6內(nèi)核中新出現(xiàn)的一個文件系統(tǒng)?sysfs?。

sysfs文件系統(tǒng)集成了下面3種文件系統(tǒng)的信息:針對進(jìn)程信息的proc文件系統(tǒng)巴柿、針對設(shè)備的devfs文件系統(tǒng)以及針對偽終端的devpts文件系統(tǒng)凛虽。

該文件系統(tǒng)是內(nèi)核設(shè)備樹的一個直觀反映。

當(dāng)一個內(nèi)核對象被創(chuàng)建的時候广恢,對應(yīng)的文件和目錄也在內(nèi)核對象子系統(tǒng)種被創(chuàng)建凯旋。

/tmp

這個目錄是用來存放一些臨時文件的。

/usr

這是一個非常重要的目錄钉迷,用戶的很多應(yīng)用程序和文件都放在這個目錄下至非,類似與windows下的program files目錄。

/usr/bin:

系統(tǒng)用戶使用的應(yīng)用程序糠聪。

/usr/sbin:

超級用戶使用的比較高級的管理程序和系統(tǒng)守護(hù)程序荒椭。

/usr/src:內(nèi)核源代碼默認(rèn)的放置目錄。

/var

這個目錄中存放著在不斷擴充著的東西舰蟆,我們習(xí)慣將那些經(jīng)常被修改的目錄放在這個目錄下趣惠。包括各種日志文件狸棍。

在linux系統(tǒng)中,有幾個目錄是比較重要的信卡,平時需要注意不要誤刪除或者隨意更改內(nèi)部文件隔缀。

/etc:?上邊也提到了,這個是系統(tǒng)中的配置文件傍菇,如果你更改了該目錄下的某個文件可能會導(dǎo)致系統(tǒng)不能啟動猾瘸。

/bin, /sbin, /usr/bin, /usr/sbin:?這是系統(tǒng)預(yù)設(shè)的執(zhí)行文件的放置目錄,比如?ls?就是在/bin/ls?目錄下的丢习。

值得提出的是牵触,/bin, /usr/bin?是給系統(tǒng)用戶使用的指令(除root外的通用戶),而/sbin, /usr/sbin?則是給root使用的指令咐低。

/var:?這是一個非常重要的目錄揽思,系統(tǒng)上跑了很多程序,那么每個程序都會有相應(yīng)的日志產(chǎn)生见擦,而這些日志就被記錄到這個目錄下钉汗,具體在/var/log?目錄下,另外mail的預(yù)設(shè)放置也是在這里鲤屡。




十三损痰、Linux 文件與目錄管理

4課時

實驗課

主要內(nèi)容

Linux?文件與目錄管理

我們知道Linux的目錄結(jié)構(gòu)為樹狀結(jié)構(gòu),最頂級的目錄為根目錄 /酒来。

其他目錄通過掛載可以將它們添加到樹中卢未,通過解除掛載可以移除它們。

在開始本教程前我們需要先知道什么是絕對路徑與相對路徑堰汉。

絕對路徑:

路徑的寫法辽社,由根目錄 / 寫起,例如: /usr/share/doc 這個目錄翘鸭。

相對路徑:

路徑的寫法滴铅,不是由 / 寫起,例如由 /usr/share/doc 要到 /usr/share/man 底下時就乓,可以寫成: cd ../man 這就是相對路徑的寫法啦失息!

處理目錄的常用命令

接下來我們就來看幾個常見的處理目錄的命令吧:

ls: 列出目錄

cd:切換目錄

pwd:顯示目前的目錄

mkdir:創(chuàng)建一個新的目錄

rmdir:刪除一個空的目錄

cp: 復(fù)制文件或目錄

rm: 移除文件或目錄

mv: 移動文件與目錄、文件重命名

你可以使用?man [命令]?來查看各個命令的使用文檔档址,如 :man cp。

ls (列出目錄)

在Linux系統(tǒng)當(dāng)中邻梆, ls 命令可能是最常被運行的守伸。

語法:

[root@www ~]# ls [-aAdfFhilnrRSt] 目錄名稱

[root@www ~]# ls [--color={never,auto,always}] 目錄名稱

[root@www ~]# ls [--full-time] 目錄名稱

選項與參數(shù):

-a :全部的文件,連同隱藏檔( 開頭為 . 的文件) 一起列出來(常用)

-d :僅列出目錄本身浦妄,而不是列出目錄內(nèi)的文件數(shù)據(jù)(常用)

-l :長數(shù)據(jù)串列出尼摹,包含文件的屬性與權(quán)限等等數(shù)據(jù)见芹;(常用)

將家目錄下的所有文件列出來(含屬性與隱藏檔)

[root@www ~]# ls -al ~

cd (切換目錄)

cd是Change Directory的縮寫,這是用來變換工作目錄的命令蠢涝。

語法:

cd [相對路徑或絕對路徑]

#使用 mkdir 命令創(chuàng)建w3cschool.cn目錄

[root@www ~]# mkdir w3cschool.cn

#使用絕對路徑切換到w3cschool.cn目錄

[root@www ~]# cd /root/w3cschool.cn/

#使用相對路徑切換到w3cschool.cn目錄

[root@www ~]# cd ./w3cschool.cn/

# 表示回到自己的家目錄玄呛,亦即是 /root 這個目錄

[root@www w3cschool.cn]# cd ~

# 表示去到目前的上一級目錄,亦即是 /root 的上一級目錄的意思和二;

[root@www ~]# cd ..

接下來大家多操作幾次應(yīng)該就可以很好的理解 cd 命令的徘铝。

pwd (顯示目前所在的目錄)

pwd是Print Working Directory的縮寫,也就是顯示目前所在目錄的命令惯吕。

[root@www ~]# pwd [-P]

選項與參數(shù):

-P? :顯示出確實的路徑惕它,而非使用連結(jié) (link) 路徑。

范例:單純顯示出目前的工作目錄:

[root@www ~]# pwd

/root? <== 顯示出目錄啦~?

范例:顯示出實際的工作目錄废登,而非連結(jié)檔本身的目錄名而已

[root@www ~]# cd /var/mail? <==注意淹魄,/var/mail是一個連結(jié)檔

[root@www mail]# pwd

/var/mail? ? ? ? <==列出目前的工作目錄

[root@www mail]# pwd -P

/var/spool/mail? <==怎么回事?有沒有加 -P 差很多~

[root@www mail]# ls -ld /var/mail

lrwxrwxrwx 1 root root 10 Sep? 4 17:54 /var/mail -> spool/mail

# 看到這里應(yīng)該知道為啥了吧堡距?因為 /var/mail 是連結(jié)檔甲锡,連結(jié)到 /var/spool/mail

# 所以,加上 pwd -P 的選項后羽戒,會不以連結(jié)檔的數(shù)據(jù)顯示缤沦,而是顯示正確的完整路徑啊半醉!

mkdir (創(chuàng)建新目錄)

如果想要創(chuàng)建新的目錄的話疚俱,那么就使用mkdir (make directory)吧。

語法:

mkdir [-mp] 目錄名稱

選項與參數(shù):

-m :配置文件的權(quán)限喔缩多!直接配置呆奕,不需要看默認(rèn)權(quán)限 (umask) 的臉色~

-p :幫助你直接將所需要的目錄(包含上一級目錄)遞回創(chuàng)建起來!

范例:請到/tmp底下嘗試創(chuàng)建數(shù)個新目錄看看:

[root@www ~]# cd /tmp

[root@www tmp]# mkdir test? ? <==創(chuàng)建一名為 test 的新目錄

[root@www tmp]# mkdir test1/test2/test3/test4

mkdir: cannot create directory `test1/test2/test3/test4':?

No such file or directory? ? ? <== 沒辦法直接創(chuàng)建此目錄俺倪骸梁钾!

[root@www tmp]# mkdir -p test1/test2/test3/test4

加了這個 -p 的選項,可以自行幫你創(chuàng)建多層目錄逊抡!

范例:創(chuàng)建權(quán)限為rwx--x--x的目錄

[root@www tmp]# mkdir -m 711 test2

[root@www tmp]# ls -l

drwxr-xr-x? 3 root? root 4096 Jul 18 12:50 test

drwxr-xr-x? 3 root? root 4096 Jul 18 12:53 test1

drwx--x--x? 2 root? root 4096 Jul 18 12:54 test2

上面的權(quán)限部分姆泻,如果沒有加上 -m 來強制配置屬性,系統(tǒng)會使用默認(rèn)屬性冒嫡。

如果我們使用 -m 拇勃,如上例我們給予 -m 711 來給予新的目錄 drwx--x--x 的權(quán)限。

rmdir (刪除空的目錄)

語法:

rmdir [-p] 目錄名稱

選項與參數(shù):

-p :連同上一級『空的』目錄也一起刪除

刪除 w3cschool.cn 目錄

[root@www tmp]# rmdir w3cschool.cn/

范例:將於mkdir范例中創(chuàng)建的目錄(/tmp底下)刪除掉孝凌!

[root@www tmp]# ls -l? <==看看有多少目錄存在方咆?

drwxr-xr-x? 3 root? root 4096 Jul 18 12:50 test

drwxr-xr-x? 3 root? root 4096 Jul 18 12:53 test1

drwx--x--x? 2 root? root 4096 Jul 18 12:54 test2

[root@www tmp]# rmdir test? <==可直接刪除掉,沒問題

[root@www tmp]# rmdir test1? <==因為尚有內(nèi)容蟀架,所以無法刪除瓣赂!

rmdir: `test1': Directory not empty

[root@www tmp]# rmdir -p test1/test2/test3/test4

[root@www tmp]# ls -l? ? ? ? <==您看看榆骚,底下的輸出中test與test1不見了!

drwx--x--x? 2 root? root 4096 Jul 18 12:54 test2

利用 -p 這個選項煌集,立刻就可以將 test1/test2/test3/test4 一次刪除妓肢。

不過要注意的是,這個 rmdir 僅能刪除空的目錄苫纤,你可以使用 rm 命令來刪除非空目錄碉钠。

cp (復(fù)制文件或目錄)

cp 即拷貝文件和目錄。

語法:

[root@www ~]# cp [-adfilprsu] 來源檔(source) 目標(biāo)檔(destination)

[root@www ~]# cp [options] source1 source2 source3 .... directory

選項與參數(shù):

-a :相當(dāng)於 -pdr 的意思方面,至於 pdr 請參考下列說明放钦;(常用)

-d :若來源檔為連結(jié)檔的屬性(link file),則復(fù)制連結(jié)檔屬性而非文件本身恭金;

-f :為強制(force)的意思操禀,若目標(biāo)文件已經(jīng)存在且無法開啟,則移除后再嘗試一次横腿;

-i :若目標(biāo)檔(destination)已經(jīng)存在時颓屑,在覆蓋時會先詢問動作的進(jìn)行(常用)

-l :進(jìn)行硬式連結(jié)(hard link)的連結(jié)檔創(chuàng)建,而非復(fù)制文件本身耿焊;

-p :連同文件的屬性一起復(fù)制過去揪惦,而非使用默認(rèn)屬性(備份常用);

-r :遞回持續(xù)復(fù)制罗侯,用於目錄的復(fù)制行為器腋;(常用)

-s :復(fù)制成為符號連結(jié)檔 (symbolic link),亦即『捷徑』文件钩杰;

-u :若 destination 比 source 舊才升級 destination 纫塌!

用root身份,將家目錄下的 .bashrc 復(fù)制到 /tmp 下讲弄,并更名為 bashr

[root@www ~]# cp ~/.bashrc /tmp/bashrc

[root@www ~]# cp -i ~/.bashrc /tmp/bashrc

cp: overwrite `/tmp/bashrc'? n? <==n不覆蓋措左,y為覆蓋

rm (移除文件或目錄)

語法:

rm [-fir] 文件或目錄

選項與參數(shù):

-f :就是 force 的意思,忽略不存在的文件避除,不會出現(xiàn)警告信息怎披;

-i :互動模式,在刪除前會詢問使用者是否動作

-r :遞回刪除捌堪凇凉逛!最常用在目錄的刪除了!這是非常危險的選項H壕S愠础!

將剛剛在 cp 的范例中創(chuàng)建的 bashrc 刪除掉!

[root@www tmp]# rm -i bashrc

rm: remove regular file `bashrc'? y

如果加上 -i 的選項就會主動詢問喔昔瞧,避免你刪除到錯誤的檔名!

mv (移動文件與目錄漱病,或修改名稱)

語法:

[root@www ~]# mv [-fiu] source destination

[root@www ~]# mv [options] source1 source2 source3 .... directory

選項與參數(shù):

-f :force 強制的意思锚赤,如果目標(biāo)文件已經(jīng)存在沛膳,不會詢問而直接覆蓋;

-i :若目標(biāo)文件 (destination) 已經(jīng)存在時酬荞,就會詢問是否覆蓋!

-u :若目標(biāo)文件已經(jīng)存在瞧哟,且 source 比較新混巧,才會升級 (update)

復(fù)制一文件,創(chuàng)建一目錄勤揩,將文件移動到目錄中

[root@www ~]# cd /tmp

[root@www tmp]# cp ~/.bashrc bashrc

[root@www tmp]# mkdir mvtest

[root@www tmp]# mv bashrc mvtest

將某個文件移動到某個目錄去咧党,就是這樣做!

將剛剛的目錄名稱更名為 mvtest2

[root@www tmp]# mv mvtest mvtest2

Linux 文件內(nèi)容查看

Linux系統(tǒng)中使用以下命令來查看文件的內(nèi)容:

cat? 由第一行開始顯示文件內(nèi)容

tac? 從最后一行開始顯示陨亡,可以看出 tac 是 cat 的倒著寫傍衡!

nl ??顯示的時候,順道輸出行號负蠕!

more 一頁一頁的顯示文件內(nèi)容

less 與 more 類似蛙埂,但是比 more 更好的是,他可以往前翻頁遮糖!

head 只看頭幾行

tail 只看尾巴幾行

你可以使用?man [命令]來查看各個命令的使用文檔绣的,如 :man cp。

cat

由第一行開始顯示文件內(nèi)容

語法:

cat [-AbEnTv]

選項與參數(shù):

-A :相當(dāng)於 -vET 的整合選項欲账,可列出一些特殊字符而不是空白而已屡江;

-b :列出行號,僅針對非空白行做行號顯示敬惦,空白行不標(biāo)行號盼理!

-E :將結(jié)尾的斷行字節(jié) $ 顯示出來;

-n :列印出行號俄删,連同空白行也會有行號宏怔,與 -b 的選項不同;

-T :將 [tab] 按鍵以 ^I 顯示出來畴椰;

-v :列出一些看不出來的特殊字符

檢看 /etc/issue 這個文件的內(nèi)容:

[root@www ~]# cat /etc/issue

CentOS release 6.4 (Final)

Kernel \r on an \m

tac

tac與cat命令剛好相反臊诊,文件內(nèi)容從最后一行開始顯示,可以看出 tac 是 cat 的倒著寫斜脂!如:

[root@www ~]# tac /etc/issue

Kernel \r on an \m

CentOS release 6.4 (Final)

nl

顯示行號

語法:

nl [-bnw] 文件

選項與參數(shù):

-b :指定行號指定的方式抓艳,主要有兩種:

-b a :表示不論是否為空行,也同樣列出行號(類似 cat -n)帚戳;

-b t :如果有空行玷或,空的那一行不要列出行號(默認(rèn)值)儡首;

-n :列出行號表示的方法,主要有三種:

-n ln :行號在螢?zāi)坏淖钭蠓斤@示偏友;

-n rn :行號在自己欄位的最右方顯示蔬胯,且不加 0 ;

-n rz :行號在自己欄位的最右方顯示位他,且加 0 氛濒;

-w :行號欄位的占用的位數(shù)。

范例一:用 nl 列出 /etc/issue 的內(nèi)容

[root@www ~]# nl /etc/issue

? ? 1? CentOS release 6.4 (Final)

? ? 2? Kernel \r on an \m

more

一頁一頁翻動

[root@www ~]# more /etc/man.config

#

# Generated automatically from man.conf.in by the

# configure script.

#

# man.conf from man-1.6d

....(中間省略)....

--More--(28%)? <== 重點在這一行喔鹅髓!你的光標(biāo)也會在這里等待你的命令

在 more 這個程序的運行過程中舞竿,你有幾個按鍵可以按的:

空白鍵 (space):代表向下翻一頁;

Enter???????? :代表向下翻『一行』窿冯;

/字串???????? :代表在這個顯示的內(nèi)容當(dāng)中骗奖,向下搜尋『字串』這個關(guān)鍵字;

:f??????????? :立刻顯示出檔名以及目前顯示的行數(shù)靡菇;

q???????????? :代表立刻離開 more 重归,不再顯示該文件內(nèi)容。

b 或 [ctrl]-b :代表往回翻頁厦凤,不過這動作只對文件有用鼻吮,對管線無用。

less

一頁一頁翻動较鼓,以下實例輸出/etc/man.config文件的內(nèi)容:

[root@www ~]# less /etc/man.config

#

# Generated automatically from man.conf.in by the

# configure script.

#

# man.conf from man-1.6d

....(中間省略)....

:? <== 這里可以等待你輸入命令椎木!

less運行時可以輸入的命令有:

空白鍵????:向下翻動一頁;

[pagedown]:向下翻動一頁博烂;

[pageup]??:向上翻動一頁香椎;

/字串?????:向下搜尋『字串』的功能;

?字串?????:向上搜尋『字串』的功能禽篱;

n???????? :重復(fù)前一個搜尋 (與 / 或 ? 有關(guān)畜伐!)

N???????? :反向的重復(fù)前一個搜尋 (與 / 或 ? 有關(guān)!)

q???????? :離開 less 這個程序躺率;

head

取出文件前面幾行

語法:

head [-n number] 文件

選項與參數(shù):

-n :后面接數(shù)字玛界,代表顯示幾行的意思

[root@www ~]# head /etc/man.config

默認(rèn)的情況中,顯示前面 10 行悼吱!若要顯示前 20 行慎框,就得要這樣:

[root@www ~]# head -n 20 /etc/man.config

tail

取出文件后面幾行

語法:

tail [-n number] 文件

選項與參數(shù):

-n :后面接數(shù)字,代表顯示幾行的意思

-f :表示持續(xù)偵測后面所接的檔名后添,要等到按下[ctrl]-c才會結(jié)束tail的偵測

[root@www ~]# tail /etc/man.config

# 默認(rèn)的情況中笨枯,顯示最后的十行!若要顯示最后的 20 行,就得要這樣:

[root@www ~]# tail -n 20 /etc/man.config




十四馅精、Linux用戶與用戶組管理

4課時

實驗課

主要內(nèi)容

Linux?用戶和用戶組管理

Linux系統(tǒng)是一個多用戶多任務(wù)的分時操作系統(tǒng)严嗜,任何一個要使用系統(tǒng)資源的用戶,都必須首先向系統(tǒng)管理員申請一個賬號洲敢,然后以這個賬號的身份進(jìn)入系統(tǒng)阻问。

用戶的賬號一方面可以幫助系統(tǒng)管理員對使用系統(tǒng)的用戶進(jìn)行跟蹤,并控制他們對系統(tǒng)資源的訪問沦疾;另一方面也可以幫助用戶組織文件,并為用戶提供安全性保護(hù)第队。

每個用戶賬號都擁有一個惟一的用戶名和各自的口令哮塞。

用戶在登錄時鍵入正確的用戶名和口令后,就能夠進(jìn)入系統(tǒng)和自己的主目錄凳谦。

實現(xiàn)用戶賬號的管理忆畅,要完成的工作主要有如下幾個方面:

用戶賬號的添加、刪除與修改尸执。

用戶口令的管理家凯。

用戶組的管理。

一如失、Linux系統(tǒng)用戶賬號的管理

用戶賬號的管理工作主要涉及到用戶賬號的添加绊诲、修改和刪除。

添加用戶賬號就是在系統(tǒng)中創(chuàng)建一個新賬號褪贵,然后為新賬號分配用戶號掂之、用戶組、主目錄和登錄Shell等資源脆丁。剛添加的賬號是被鎖定的世舰,無法使用。

1槽卫、添加新的用戶賬號使用useradd命令跟压,其語法如下:

useradd 選項 用戶名

參數(shù)說明:

選項:

-c comment 指定一段注釋性描述。

-d 目錄 指定用戶主目錄歼培,如果此目錄不存在震蒋,則同時使用-m選項,可以創(chuàng)建主目錄丐怯。

-g 用戶組 指定用戶所屬的用戶組喷好。

-G 用戶組,用戶組 指定用戶所屬的附加組读跷。

-s Shell文件 指定用戶的登錄Shell梗搅。

-u 用戶號 指定用戶的用戶號,如果同時有-o選項,則可以重復(fù)使用其他用戶的標(biāo)識號无切。

用戶名:

指定新賬號的登錄名荡短。

實例1

# useradd –d /usr/sam -m sam

此命令創(chuàng)建了一個用戶sam,其中-d和-m選項用來為登錄名sam產(chǎn)生一個主目錄/usr/sam(/usr為默認(rèn)的用戶主目錄所在的父目錄)哆键。

實例2

# useradd -s /bin/sh -g group –G adm,root gem

此命令新建了一個用戶gem掘托,該用戶的登錄Shell是?/bin/sh,它屬于group用戶組籍嘹,同時又屬于adm和root用戶組闪盔,其中g(shù)roup用戶組是其主組。

這里可能新建組:#groupadd group及groupadd adm

增加用戶賬號就是在/etc/passwd文件中為新用戶增加一條記錄辱士,同時更新其他系統(tǒng)文件如/etc/shadow, /etc/group等泪掀。

Linux提供了集成的系統(tǒng)管理工具userconf,它可以用來對用戶賬號進(jìn)行統(tǒng)一管理颂碘。

3异赫、刪除帳號

如果一個用戶的賬號不再使用,可以從系統(tǒng)中刪除头岔。刪除用戶賬號就是要將/etc/passwd等系統(tǒng)文件中的該用戶記錄刪除塔拳,必要時還刪除用戶的主目錄。

刪除一個已有的用戶賬號使用userdel命令峡竣,其格式如下:

userdel 選項 用戶名

常用的選項是-r靠抑,它的作用是把用戶的主目錄一起刪除。

例如:

# userdel sam

此命令刪除用戶sam在系統(tǒng)文件中(主要是/etc/passwd, /etc/shadow, /etc/group等)的記錄澎胡,同時刪除用戶的主目錄孕荠。

4、修改帳號

修改用戶賬號就是根據(jù)實際情況更改用戶的有關(guān)屬性攻谁,如用戶號稚伍、主目錄、用戶組戚宦、登錄Shell等个曙。

修改已有用戶的信息使用usermod命令,其格式如下:

usermod 選項 用戶名

常用的選項包括-c, -d, -m, -g, -G, -s, -u以及-o等受楼,這些選項的意義與useradd命令中的選項一樣垦搬,可以為用戶指定新的資源值。

另外艳汽,有些系統(tǒng)可以使用選項:-l 新用戶名

這個選項指定一個新的賬號猴贰,即將原來的用戶名改為新的用戶名。

例如:

# usermod -s /bin/ksh -d /home/z –g developer sam

此命令將用戶sam的登錄Shell修改為ksh河狐,主目錄改為/home/z撑帖,用戶組改為developer。

5湃累、用戶口令的管理

用戶管理的一項重要內(nèi)容是用戶口令的管理。用戶賬號剛創(chuàng)建時沒有口令迈套,但是被系統(tǒng)鎖定,無法使用碱鳞,必須為其指定口令后才可以使用桑李,即使是指定空口令。

指定和修改用戶口令的Shell命令是passwd窿给。超級用戶可以為自己和其他用戶指定口令贵白,普通用戶只能用它修改自己的口令。命令的格式為:

passwd 選項 用戶名

可使用的選項:

-l 鎖定口令崩泡,即禁用賬號戒洼。

-u 口令解鎖。

-d 使賬號無口令允华。

-f 強迫用戶下次登錄時修改口令。

如果默認(rèn)用戶名寥掐,則修改當(dāng)前用戶的口令靴寂。

例如,假設(shè)當(dāng)前用戶是sam召耘,則下面的命令修改該用戶自己的口令:

$ passwd

Old password:******

New password:*******

Re-enter new password:*******

如果是超級用戶百炬,可以用下列形式指定任何用戶的口令:

# passwd sam

New password:*******

Re-enter new password:*******

普通用戶修改自己的口令時,passwd命令會先詢問原口令污它,驗證后再要求用戶輸入兩遍新口令剖踊,如果兩次輸入的口令一致,則將這個口令指定給用戶衫贬;而超級用戶為用戶指定口令時德澈,就不需要知道原口令。

為了系統(tǒng)安全起見固惯,用戶應(yīng)該選擇比較復(fù)雜的口令梆造,例如最好使用8位長的口令,口令中包含有大寫葬毫、小寫字母和數(shù)字镇辉,并且應(yīng)該與姓名、生日等不相同贴捡。

為用戶指定空口令時忽肛,執(zhí)行下列形式的命令:

# passwd -d sam

此命令將用戶sam的口令刪除,這樣用戶sam下一次登錄時烂斋,系統(tǒng)就不再詢問口令屹逛。

passwd命令還可以用-l(lock)選項鎖定某一用戶础废,使其不能登錄,例如:

# passwd -l sam

二煎源、Linux系統(tǒng)用戶組的管理

每個用戶都有一個用戶組色迂,系統(tǒng)可以對一個用戶組中的所有用戶進(jìn)行集中管理。不同Linux 系統(tǒng)對用戶組的規(guī)定有所不同手销,如Linux下的用戶屬于與它同名的用戶組歇僧,這個用戶組在創(chuàng)建用戶時同時創(chuàng)建。

用戶組的管理涉及用戶組的添加锋拖、刪除和修改诈悍。組的增加、刪除和修改實際上就是對/etc/group文件的更新兽埃。

1侥钳、增加一個新的用戶組使用groupadd命令。其格式如下:

groupadd 選項 用戶組

可以使用的選項有:

-g GID 指定新用戶組的組標(biāo)識號(GID)柄错。

-o 一般與-g選項同時使用舷夺,表示新用戶組的GID可以與系統(tǒng)已有用戶組的GID相同。

實例1:

# groupadd group1

此命令向系統(tǒng)中增加了一個新組group1售貌,新組的組標(biāo)識號是在當(dāng)前已有的最大組標(biāo)識號的基礎(chǔ)上加1给猾。

實例2:

# groupadd -g 101 group2

此命令向系統(tǒng)中增加了一個新組group2,同時指定新組的組標(biāo)識號是101颂跨。

2敢伸、如果要刪除一個已有的用戶組,使用groupdel命令恒削,其格式如下:

groupdel 用戶組

例如:

# groupdel group1

此命令從系統(tǒng)中刪除組group1池颈。

3、修改用戶組的屬性使用groupmod命令钓丰。其語法如下:

groupmod 選項 用戶組

常用的選項有:

-g GID 為用戶組指定新的組標(biāo)識號躯砰。

-o 與-g選項同時使用,用戶組的新GID可以與系統(tǒng)已有用戶組的GID相同携丁。

-n新用戶組 將用戶組的名字改為新名字

實例1:

# groupmod -g 102 group2

此命令將組group2的組標(biāo)識號修改為102弃揽。

實例2:

# groupmod –g 10000 -n group3 group2

此命令將組group2的標(biāo)識號改為10000,組名修改為group3则北。

4矿微、如果一個用戶同時屬于多個用戶組,那么用戶可以在用戶組之間切換尚揣,以便具有其他用戶組的權(quán)限涌矢。

用戶可以在登錄后,使用命令newgrp切換到其他用戶組快骗,這個命令的參數(shù)就是目的用戶組娜庇。例如:

$ newgrp root

這條命令將當(dāng)前用戶切換到root用戶組塔次,前提條件是root用戶組確實是該用戶的主組或附加組。類似于用戶賬號的管理名秀,用戶組的管理也可以通過集成的系統(tǒng)管理工具來完成励负。

三、與用戶賬號有關(guān)的系統(tǒng)文件

完成用戶管理的工作有許多種方法匕得,但是每一種方法實際上都是對有關(guān)的系統(tǒng)文件進(jìn)行修改继榆。

與用戶和用戶組相關(guān)的信息都存放在一些系統(tǒng)文件中,這些文件包括/etc/passwd, /etc/shadow, /etc/group等汁掠。

下面分別介紹這些文件的內(nèi)容略吨。

1、/etc/passwd文件是用戶管理工作涉及的最重要的一個文件考阱。

Linux系統(tǒng)中的每個用戶都在/etc/passwd文件中有一個對應(yīng)的記錄行翠忠,它記錄了這個用戶的一些基本屬性。

這個文件對所有用戶都是可讀的乞榨。它的內(nèi)容類似下面的例子:

# cat /etc/passwd

root:x:0:0:Superuser:/:

daemon:x:1:1:System daemons:/etc:

bin:x:2:2:Owner of system commands:/bin:

sys:x:3:3:Owner of system files:/usr/sys:

adm:x:4:4:System accounting:/usr/adm:

uucp:x:5:5:UUCP administrator:/usr/lib/uucp:

auth:x:7:21:Authentication administrator:/tcb/files/auth:

cron:x:9:16:Cron daemon:/usr/spool/cron:

listen:x:37:4:Network daemon:/usr/net/nls:

lp:x:71:18:Printer administrator:/usr/spool/lp:

sam:x:200:50:Sam san:/usr/sam:/bin/sh

從上面的例子我們可以看到秽之,/etc/passwd中一行記錄對應(yīng)著一個用戶,每行記錄又被冒號(:)分隔為7個字段吃既,其格式和具體含義如下:

用戶名:口令:用戶標(biāo)識號:組標(biāo)識號:注釋性描述:主目錄:登錄Shell

1)"用戶名"是代表用戶賬號的字符串政溃。

通常長度不超過8個字符,并且由大小寫字母和/或數(shù)字組成态秧。登錄名中不能有冒號(:),因為冒號在這里是分隔符扼鞋。

為了兼容起見申鱼,登錄名中最好不要包含點字符(.),并且不使用連字符(-)和加號(+)打頭云头。

2)“口令”一些系統(tǒng)中捐友,存放著加密后的用戶口令字。

雖然這個字段存放的只是用戶口令的加密串溃槐,不是明文匣砖,但是由于/etc/passwd文件對所有用戶都可讀,所以這仍是一個安全隱患昏滴。因此猴鲫,現(xiàn)在許多Linux 系統(tǒng)(如SVR4)都使用了shadow技術(shù),把真正的加密后的用戶口令字存放到/etc/shadow文件中谣殊,而在/etc/passwd文件的口令字段中只存放一個特殊的字符拂共,例如“x”或者“*”。

3)“用戶標(biāo)識號”是一個整數(shù)姻几,系統(tǒng)內(nèi)部用它來標(biāo)識用戶宜狐。

一般情況下它與用戶名是一一對應(yīng)的势告。如果幾個用戶名對應(yīng)的用戶標(biāo)識號是一樣的,系統(tǒng)內(nèi)部將把它們視為同一個用戶抚恒,但是它們可以有不同的口令咱台、不同的主目錄以及不同的登錄Shell等。

通常用戶標(biāo)識號的取值范圍是0~65 535俭驮。0是超級用戶root的標(biāo)識號回溺,1~99由系統(tǒng)保留,作為管理賬號表鳍,普通用戶的標(biāo)識號從100開始馅而。在Linux系統(tǒng)中,這個界限是500譬圣。

4)“組標(biāo)識號”字段記錄的是用戶所屬的用戶組瓮恭。

它對應(yīng)著/etc/group文件中的一條記錄。

5)“注釋性描述”字段記錄著用戶的一些個人情況厘熟。

例如用戶的真實姓名屯蹦、電話、地址等绳姨,這個字段并沒有什么實際的用途登澜。在不同的Linux 系統(tǒng)中,這個字段的格式并沒有統(tǒng)一飘庄。在許多Linux系統(tǒng)中脑蠕,這個字段存放的是一段任意的注釋性描述文字,用做finger命令的輸出跪削。

6)“主目錄”谴仙,也就是用戶的起始工作目錄。

它是用戶在登錄到系統(tǒng)之后所處的目錄碾盐。在大多數(shù)系統(tǒng)中晃跺,各用戶的主目錄都被組織在同一個特定的目錄下,而用戶主目錄的名稱就是該用戶的登錄名毫玖。各用戶對自己的主目錄有讀掀虎、寫、執(zhí)行(搜索)權(quán)限付枫,其他用戶對此目錄的訪問權(quán)限則根據(jù)具體情況設(shè)置烹玉。

7)用戶登錄后,要啟動一個進(jìn)程阐滩,負(fù)責(zé)將用戶的操作傳給內(nèi)核排监,這個進(jìn)程是用戶登錄到系統(tǒng)后運行的命令解釋器或某個特定的程序支救,即Shell。

Shell是用戶與Linux系統(tǒng)之間的接口钱骂。Linux的Shell有許多種,每種都有不同的特點。常用的有sh(Bourne Shell), csh(C Shell), ksh(Korn Shell), tcsh(TENEX/TOPS-20 type C Shell), bash(Bourne Again Shell)等。

系統(tǒng)管理員可以根據(jù)系統(tǒng)情況和用戶習(xí)慣為用戶指定某個Shell。如果不指定Shell鸳慈,那么系統(tǒng)使用sh為默認(rèn)的登錄Shell,即這個字段的值為/bin/sh喧伞。

用戶的登錄Shell也可以指定為某個特定的程序(此程序不是一個命令解釋器)走芋。

利用這一特點,我們可以限制用戶只能運行指定的應(yīng)用程序潘鲫,在該應(yīng)用程序運行結(jié)束后翁逞,用戶就自動退出了系統(tǒng)。有些Linux 系統(tǒng)要求只有那些在系統(tǒng)中登記了的程序才能出現(xiàn)在這個字段中溉仑。

8)系統(tǒng)中有一類用戶稱為偽用戶(psuedo users)挖函。

這些用戶在/etc/passwd文件中也占有一條記錄,但是不能登錄浊竟,因為它們的登錄Shell為空怨喘。它們的存在主要是方便系統(tǒng)管理,滿足相應(yīng)的系統(tǒng)進(jìn)程對文件屬主的要求振定。

常見的偽用戶如下所示:

偽 用 戶 含 義

bin 擁有可執(zhí)行的用戶命令文件

sys 擁有系統(tǒng)文件

adm 擁有帳戶文件

uucp UUCP使用

lp lp或lpd子系統(tǒng)使用

nobody NFS使用

擁有帳戶文件

1必怜、除了上面列出的偽用戶外,還有許多標(biāo)準(zhǔn)的偽用戶后频,例如:audit, cron, mail, usenet等梳庆,它們也都各自為相關(guān)的進(jìn)程和文件所需要。

由于/etc/passwd文件是所有用戶都可讀的卑惜,如果用戶的密碼太簡單或規(guī)律比較明顯的話膏执,一臺普通的計算機就能夠很容易地將它破解,因此對安全性要求較高的Linux系統(tǒng)都把加密后的口令字分離出來残揉,單獨存放在一個文件中,這個文件是/etc/shadow文件芋浮。 有超級用戶才擁有該文件讀權(quán)限抱环,這就保證了用戶密碼的安全性。

2纸巷、/etc/shadow中的記錄行與/etc/passwd中的一一對應(yīng)镇草,它由pwconv命令根據(jù)/etc/passwd中的數(shù)據(jù)自動產(chǎn)生

它的文件格式與/etc/passwd類似,由若干個字段組成瘤旨,字段之間用":"隔開梯啤。這些字段是:

登錄名:加密口令:最后一次修改時間:最小時間間隔:最大時間間隔:警告時間:不活動時間:失效時間:標(biāo)志

"登錄名"是與/etc/passwd文件中的登錄名相一致的用戶賬號

"口令"字段存放的是加密后的用戶口令字,長度為13個字符存哲。如果為空因宇,則對應(yīng)用戶沒有口令七婴,登錄時不需要口令;如果含有不屬于集合 { ./0-9A-Za-z }中的字符察滑,則對應(yīng)的用戶不能登錄打厘。

"最后一次修改時間"表示的是從某個時刻起,到用戶最后一次修改口令時的天數(shù)贺辰。時間起點對不同的系統(tǒng)可能不一樣户盯。例如在SCO Linux 中,這個時間起點是1970年1月1日饲化。

"最小時間間隔"指的是兩次修改口令之間所需的最小天數(shù)莽鸭。

"最大時間間隔"指的是口令保持有效的最大天數(shù)。

"警告時間"字段表示的是從系統(tǒng)開始警告用戶到用戶密碼正式失效之間的天數(shù)吃靠。

"不活動時間"表示的是用戶沒有登錄活動但賬號仍能保持有效的最大天數(shù)硫眨。

"失效時間"字段給出的是一個絕對的天數(shù),如果使用了這個字段撩笆,那么就給出相應(yīng)賬號的生存期捺球。期滿后,該賬號就不再是一個合法的賬號夕冲,也就不能再用來登錄了氮兵。

下面是/etc/shadow的一個例子:

# cat /etc/shadow

root:Dnakfw28zf38w:8764:0:168:7:::

daemon:*::0:0::::

bin:*::0:0::::

sys:*::0:0::::

adm:*::0:0::::

uucp:*::0:0::::

nuucp:*::0:0::::

auth:*::0:0::::

cron:*::0:0::::

listen:*::0:0::::

lp:*::0:0::::

sam:EkdiSECLWPdSa:9740:0:0::::

3、用戶組的所有信息都存放在/etc/group文件中歹鱼。

將用戶分組是Linux 系統(tǒng)中對用戶進(jìn)行管理及控制訪問權(quán)限的一種手段泣栈。

每個用戶都屬于某個用戶組;一個組中可以有多個用戶弥姻,一個用戶也可以屬于不同的組南片。

當(dāng)一個用戶同時是多個組中的成員時,在/etc/passwd文件中記錄的是用戶所屬的主組庭敦,也就是登錄時所屬的默認(rèn)組疼进,而其他組稱為附加組。

用戶要訪問屬于附加組的文件時秧廉,必須首先使用newgrp命令使自己成為所要訪問的組中的成員伞广。

用戶組的所有信息都存放在/etc/group文件中。此文件的格式也類似于/etc/passwd文件疼电,由冒號(:)隔開若干個字段嚼锄,這些字段有:

組名:口令:組標(biāo)識號:組內(nèi)用戶列表

"組名"是用戶組的名稱,由字母或數(shù)字構(gòu)成蔽豺。與/etc/passwd中的登錄名一樣区丑,組名不應(yīng)重復(fù)。

"口令"字段存放的是用戶組加密后的口令字。一般Linux 系統(tǒng)的用戶組都沒有口令沧侥,即這個字段一般為空可霎,或者是*。

"組標(biāo)識號"與用戶標(biāo)識號類似正什,也是一個整數(shù)啥纸,被系統(tǒng)內(nèi)部用來標(biāo)識組。

"組內(nèi)用戶列表"是屬于這個組的所有用戶的列表/b]婴氮,不同用戶之間用逗號(,)分隔斯棒。這個用戶組可能是用戶的主組,也可能是附加組主经。

/etc/group文件的一個例子如下:

root::0:root

bin::2:root,bin

sys::3:root,uucp

adm::4:root,adm

daemon::5:root,daemon

lp::7:root,lp

users::20:root,sam

四荣暮、批量添加用戶

添加和刪除用戶對每位Linux系統(tǒng)管理員都是輕而易舉的事,比較棘手的是如果要添加幾十個罩驻、上百個甚至上千個用戶時穗酥,我們不太可能還使用useradd一個一個地添加,必然要找一種簡便的創(chuàng)建大量用戶的方法惠遏。Linux系統(tǒng)提供了創(chuàng)建大量用戶的工具砾跃,可以讓您立即創(chuàng)建大量用戶,方法如下:

(1)先編輯一個文本用戶文件节吮。

每一列按照/etc/passwd密碼文件的格式書寫抽高,要注意每個用戶的用戶名、UID透绩、宿主目錄都不可以相同翘骂,其中密碼欄可以留做空白或輸入x號。一個范例文件user.txt內(nèi)容如下:

user001::600:100:user:/home/user001:/bin/bash

user002::601:100:user:/home/user002:/bin/bash

user003::602:100:user:/home/user003:/bin/bash

user004::603:100:user:/home/user004:/bin/bash

user005::604:100:user:/home/user005:/bin/bash

user006::605:100:user:/home/user006:/bin/bash

(2)以root身份執(zhí)行命令?/usr/sbin/newusers帚豪,從剛創(chuàng)建的用戶文件user.txt中導(dǎo)入數(shù)據(jù)碳竟,創(chuàng)建用戶:

# newusers < user.txt

然后可以執(zhí)行命令?vipw?或?vi /etc/passwd?檢查?/etc/passwd?文件是否已經(jīng)出現(xiàn)這些用戶的數(shù)據(jù),并且用戶的宿主目錄是否已經(jīng)創(chuàng)建狸臣。

(3)執(zhí)行命令/usr/sbin/pwunconv莹桅。

將?/etc/shadow?產(chǎn)生的?shadow?密碼解碼,然后回寫到?/etc/passwd?中烛亦,并將/etc/shadow的shadow密碼欄刪掉诈泼。這是為了方便下一步的密碼轉(zhuǎn)換工作,即先取消?shadow password?功能此洲。

# pwunconv

(4)編輯每個用戶的密碼對照文件厂汗。

范例文件?passwd.txt?內(nèi)容如下:

user001:密碼

user002:密碼

user003:密碼

user004:密碼

user005:密碼

user006:密碼

(5)以root身份執(zhí)行命令?/usr/sbin/chpasswd委粉。

創(chuàng)建用戶密碼呜师,chpasswd?會將經(jīng)過?/usr/bin/passwd?命令編碼過的密碼寫入?/etc/passwd?的密碼欄。

# chpasswd < passwd.txt

(6)確定密碼經(jīng)編碼寫入/etc/passwd的密碼欄后贾节。

執(zhí)行命令?/usr/sbin/pwconv?將密碼編碼為?shadow password汁汗,并將結(jié)果寫入?/etc/shadow衷畦。

# pwconv

這樣就完成了大量用戶的創(chuàng)建了,之后您可以到/home下檢查這些用戶宿主目錄的權(quán)限設(shè)置是否都正確知牌,并登錄驗證用戶密碼是否正確祈争。






十五、Linux VI VIM

4課時

實驗課

主要內(nèi)容

所有的 Unix Like 系統(tǒng)都會內(nèi)建 vi 文書編輯器角寸,其他的文書編輯器則不一定會存在菩混。

但是目前我們使用比較多的是 vim 編輯器。

vim 具有程序編輯的能力扁藕,可以主動的以字體顏色辨別語法的正確性沮峡,方便程序設(shè)計。

什么是 vim亿柑?

Vim是從 vi 發(fā)展出來的一個文本編輯器邢疙。代碼補完、編譯及錯誤跳轉(zhuǎn)等方便編程的功能特別豐富望薄,在程序員中被廣泛使用疟游。

簡單的來說, vi 是老式的字處理器痕支,不過功能已經(jīng)很齊全了颁虐,但是還是有可以進(jìn)步的地方。 vim 則可以說是程序開發(fā)者的一項很好用的工具采转。 連 vim 的官方網(wǎng)站 (http://www.vim.org) 自己也說 vim 是一個程序開發(fā)工具而不是文字處理軟件聪廉。?

vim 鍵盤圖:

vi/vim 的使用

基本上?vi/vim?共分為三種模式,分別是命令模式(Command?mode)故慈,輸入模式(Insert?mode)底線命令模式(Last?line?mode)板熊。?這三種模式的作用分別是:

命令模式:

用戶剛剛啟動?vi/vim,便進(jìn)入了命令模式察绷。

此狀態(tài)下敲擊鍵盤動作會被Vim識別為命令干签,而非輸入字符。比如我們此時按下i拆撼,并不會輸入一個字符容劳,i被當(dāng)作了一個命令。

以下是常用的幾個命令:

i?切換到輸入模式闸度,以輸入字符竭贩。

x?刪除當(dāng)前光標(biāo)所在處的字符。

:?切換到底線命令模式莺禁,以在最底一行輸入命令留量。

若想要編輯文本:啟動Vim抢野,進(jìn)入了命令模式聊记,按下i念赶,切換到輸入模式闸与。

命令模式只有一些最基本的命令,因此仍要依靠底線命令模式輸入更多命令可岂。

輸入模式

在命令模式下按下i就進(jìn)入了輸入模式错敢。

在輸入模式中,可以使用以下按鍵:

字符按鍵以及Shift組合缕粹,輸入字符

ENTER稚茅,回車鍵,換行

BACK?SPACE平斩,退格鍵峰锁,刪除光標(biāo)前一個字符

DEL,刪除鍵双戳,刪除光標(biāo)后一個字符

方向鍵虹蒋,在文本中移動光標(biāo)

HOME/END,移動光標(biāo)到行首/行尾

Page?Up/Page?Down飒货,上/下翻頁

Insert魄衅,切換光標(biāo)為輸入/替換模式,光標(biāo)將變成豎線/下劃線

ESC塘辅,退出輸入模式晃虫,切換到命令模式

底線命令模式

在命令模式下按下:(英文冒號)就進(jìn)入了底線命令模式。

底線命令模式可以輸入單個或多個字符的命令扣墩,可用的命令非常多哲银。

在底線命令模式中,基本的命令有(已經(jīng)省略了冒號):

q?退出程序

w?保存文件

按ESC鍵可隨時退出底線命令模式呻惕。

簡單的說荆责,我們可以將這三個模式想成底下的圖標(biāo)來表示:

vi/vim 使用實例

使用 vi/vim 進(jìn)入命令模式

如果你想要使用 vi 來建立一個名為 test.txt 的文件時,你可以這樣做:

[root@www ~]# vi test.txt

直接輸入?vi 文件名?就能夠進(jìn)入 vi 的命令模式了亚脆。請注意做院,記得 vi 后面一定要加文件名,不管該文件存在與否濒持!

按下 i 進(jìn)入輸入模式键耕,開始編輯文字

在命令模式之中,只要按下 i, o, a 等字符就可以進(jìn)入輸入模式了柑营!

在輸入模式當(dāng)中屈雄,你可以發(fā)現(xiàn)在左下角狀態(tài)欄中會出現(xiàn) –INSERT- 的字樣,那就是可以輸入任意字符的提示官套。

這個時候酒奶,鍵盤上除了 [Esc] 這個按鍵之外蓖议,其他的按鍵都可以視作為一般的輸入按鈕了,所以你可以進(jìn)行任何的編輯讥蟆。

按下 [ESC] 按鈕回到命令模式

好了,假設(shè)我已經(jīng)按照上面的樣式給他編輯完畢了纺阔,那么應(yīng)該要如何退出呢瘸彤?是的!沒錯笛钝!就是給他按下 [Esc] 這個按鈕即可质况!馬上你就會發(fā)現(xiàn)畫面左下角的 – INSERT – 不見了!

在命令模式中按下 :wq 儲存后離開 vi

OK玻靡,我們要存檔了结榄,存盤并離開的指令很簡單,輸入『:wq』即可保存離開囤捻!

OK! 這樣我們就成功創(chuàng)建了一個 test.txt 的文件臼朗。是不是很簡單。

vi/vim 按鍵說明

除了上面簡易范例的 i, [Esc], :wq 之外蝎土,其實 vim 還有非常多的按鍵可以使用视哑。

第一部份:命令模式可用的按鈕說明,光標(biāo)移動誊涯、復(fù)制貼上挡毅、搜尋取代等

移動光標(biāo)的方法

h 或 向左箭頭鍵(←)光標(biāo)向左移動一個字符

j 或 向下箭頭鍵(↓)光標(biāo)向下移動一個字符

k 或 向上箭頭鍵(↑)光標(biāo)向上移動一個字符

l 或 向右箭頭鍵(→)光標(biāo)向右移動一個字符

如果你將右手放在鍵盤上的話,你會發(fā)現(xiàn) hjkl 是排列在一起的暴构,因此可以使用這四個按鈕來移動光標(biāo)跪呈。 如果想要進(jìn)行多次移動的話,例如向下移動 30 行取逾,可以使用 "30j" 或 "30↓" 的組合按鍵耗绿, 亦即加上想要進(jìn)行的次數(shù)(數(shù)字)后,按下動作即可砾隅!

[Ctrl] + [f]屏幕『向下』移動一頁缭乘,相當(dāng)于 [Page Down]按鍵 (常用)

[Ctrl] + [b]屏幕『向上』移動一頁,相當(dāng)于 [Page Up] 按鍵 (常用)

[Ctrl] + [d]屏幕『向下』移動半頁

[Ctrl] + [u]屏幕『向上』移動半頁

+光標(biāo)移動到非空格符的下一列

-光標(biāo)移動到非空格符的上一列

n那個 n 表示『數(shù)字』琉用,例如 20 堕绩。按下數(shù)字后再按空格鍵,光標(biāo)會向右移動這一行的 n 個字符邑时。例如 20 則光標(biāo)會向后面移動 20 個字符距離奴紧。

0 或功能鍵[Home]這是數(shù)字『 0 』:移動到這一行的最前面字符處 (常用)

$ 或功能鍵[End]移動到這一行的最后面字符處(常用)

H光標(biāo)移動到這個屏幕的最上方那一行的第一個字符

M光標(biāo)移動到這個屏幕的中央那一行的第一個字符

L光標(biāo)移動到這個屏幕的最下方那一行的第一個字符

G移動到這個檔案的最后一行(常用)

nGn 為數(shù)字。移動到這個檔案的第 n 行晶丘。例如 20G 則會移動到這個檔案的第 20 行(可配合 :set nu)

gg移動到這個檔案的第一行黍氮,相當(dāng)于 1G 疤坪! (常用)

nn 為數(shù)字沫浆。光標(biāo)向下移動 n 行(常用)

搜尋與取代

/word向光標(biāo)之下尋找一個名稱為 word 的字符串捷枯。例如要在檔案內(nèi)搜尋 vbird 這個字符串,就輸入 /vbird 即可专执! (常用)

?word向光標(biāo)之上尋找一個字符串名稱為 word 的字符串淮捆。

n這個 n 是英文按鍵。代表重復(fù)前一個搜尋的動作本股。舉例來說攀痊, 如果剛剛我們執(zhí)行 /vbird 去向下搜尋 vbird 這個字符串,則按下 n 后拄显,會向下繼續(xù)搜尋下一個名稱為 vbird 的字符串苟径。如果是執(zhí)行 ?vbird 的話,那么按下 n 則會向上繼續(xù)搜尋名稱為 vbird 的字符串躬审!

N這個 N 是英文按鍵棘街。與 n 剛好相反,為『反向』進(jìn)行前一個搜尋動作承边。 例如 /vbird 后蹬碧,按下 N 則表示『向上』搜尋 vbird 。

使用 /word 配合 n 及 N 是非常有幫助的炒刁!可以讓你重復(fù)的找到一些你搜尋的關(guān)鍵詞恩沽!

:n1,n2s/word1/word2/gn1 與 n2 為數(shù)字。在第 n1 與 n2 行之間尋找 word1 這個字符串翔始,并將該字符串取代為 word2 罗心!舉例來說,在 100 到 200 行之間搜尋 vbird 并取代為 VBIRD 則:

『:100,200s/vbird/VBIRD/g』城瞎。(常用)

:1,$s/word1/word2/g從第一行到最后一行尋找 word1 字符串渤闷,并將該字符串取代為 word2 !(常用)

:1,$s/word1/word2/gc從第一行到最后一行尋找 word1 字符串脖镀,并將該字符串取代為 word2 飒箭!且在取代前顯示提示字符給用戶確認(rèn) (confirm) 是否需要取代!(常用)

刪除蜒灰、復(fù)制與貼上

x, X在一行字當(dāng)中弦蹂,x 為向后刪除一個字符 (相當(dāng)于 [del] 按鍵), X 為向前刪除一個字符(相當(dāng)于 [backspace] 亦即是退格鍵) (常用)

nxn 為數(shù)字强窖,連續(xù)向后刪除 n 個字符凸椿。舉例來說,我要連續(xù)刪除 10 個字符翅溺, 『10x』脑漫。

dd刪除游標(biāo)所在的那一整行(常用)

nddn 為數(shù)字髓抑。刪除光標(biāo)所在的向下 n 行,例如 20dd 則是刪除 20 行 (常用)

d1G刪除光標(biāo)所在到第一行的所有數(shù)據(jù)

dG刪除光標(biāo)所在到最后一行的所有數(shù)據(jù)

d$刪除游標(biāo)所在處优幸,到該行的最后一個字符

d0那個是數(shù)字的 0 吨拍,刪除游標(biāo)所在處,到該行的最前面一個字符

yy復(fù)制游標(biāo)所在的那一行(常用)

nyyn 為數(shù)字网杆。復(fù)制光標(biāo)所在的向下 n 列羹饰,例如 20yy 則是復(fù)制 20 列(常用)

y1G復(fù)制游標(biāo)所在列到第一列的所有數(shù)據(jù)

yG復(fù)制游標(biāo)所在列到最后一列的所有數(shù)據(jù)

y0復(fù)制光標(biāo)所在的那個字符到該行行首的所有數(shù)據(jù)

y$復(fù)制光標(biāo)所在的那個字符到該行行尾的所有數(shù)據(jù)

p, Pp 為將已復(fù)制的數(shù)據(jù)在光標(biāo)下一行貼上,P 則為貼在游標(biāo)上一行跛璧! 舉例來說,我目前光標(biāo)在第 20 行新啼,且已經(jīng)復(fù)制了 10 行數(shù)據(jù)追城。則按下 p 后, 那 10 行數(shù)據(jù)會貼在原本的 20 行之后燥撞,亦即由 21 行開始貼座柱。但如果是按下 P 呢? 那么原本的第 20 行會被推到變成 30 行物舒。 (常用)

J將光標(biāo)所在列與下一列的數(shù)據(jù)結(jié)合成同一列

c重復(fù)刪除多個數(shù)據(jù)色洞,例如向下刪除 10 行,[ 10cj ]

u復(fù)原前一個動作冠胯。(常用)

[Ctrl]+r重做上一個動作火诸。(常用)

這個 u 與 [Ctrl]+r 是很常用的指令!一個是復(fù)原荠察,另一個則是重做一次~ 利用這兩個功能按鍵置蜀,你的編輯,嘿嘿悉盆!很快樂的啦盯荤!

.不要懷疑!這就是小數(shù)點焕盟!意思是重復(fù)前一個動作的意思秋秤。 如果你想要重復(fù)刪除、重復(fù)貼上等等動作脚翘,按下小數(shù)點『.』就好了灼卢! (常用)

第二部份:命令模式切換到輸入模式的可用的按鈕說明

進(jìn)入輸入或取代的編輯模式

i, I進(jìn)入輸入模式(Insert mode):

i 為『從目前光標(biāo)所在處輸入』, I 為『在目前所在行的第一個非空格符處開始輸入』来农。 (常用)

a, A進(jìn)入輸入模式(Insert mode):

a 為『從目前光標(biāo)所在的下一個字符處開始輸入』芥玉, A 為『從光標(biāo)所在行的最后一個字符處開始輸入』。(常用)

o, O進(jìn)入輸入模式(Insert mode):

這是英文字母 o 的大小寫备图。o 為『在目前光標(biāo)所在的下一行處輸入新的一行』灿巧; O 為在目前光標(biāo)所在處的上一行輸入新的一行赶袄!(常用)

r, R進(jìn)入取代模式(Replace mode):

r 只會取代光標(biāo)所在的那一個字符一次;R會一直取代光標(biāo)所在的文字抠藕,直到按下 ESC 為止似舵;(常用)

上面這些按鍵中扰柠,在 vi 畫面的左下角處會出現(xiàn)『--INSERT--』或『--REPLACE--』的字樣。 由名稱就知道該動作了吧!积瞒!特別注意的是,我們上面也提過了劳吠,你想要在檔案里面輸入字符時懒闷, 一定要在左下角處看到 INSERT 或 REPLACE 才能輸入喔!

[Esc]退出編輯模式告抄,回到命令模式中(常用)

第三部份:命令模式切換到底線命令模式的可用的按鈕說明

底線命令模式的儲存撰茎、離開等指令

:w將編輯的數(shù)據(jù)寫入硬盤檔案中(常用)

:w!若文件屬性為『只讀』時,強制寫入該檔案打洼。不過龄糊,到底能不能寫入, 還是跟你對該檔案的檔案權(quán)限有關(guān)澳即炫惩!

:q離開 vi (常用)

:q!若曾修改過檔案,又不想儲存阿浓,使用 ! 為強制離開不儲存檔案他嚷。

注意一下啊,那個驚嘆號 (!) 在 vi 當(dāng)中芭毙,常常具有『強制』的意思~

:wq儲存后離開爸舒,若為 :wq! 則為強制儲存后離開 (常用)

ZZ這是大寫的 Z 喔!若檔案沒有更動稿蹲,則不儲存離開扭勉,若檔案已經(jīng)被更動過,則儲存后離開苛聘!

:w [filename]將編輯的數(shù)據(jù)儲存成另一個檔案(類似另存新檔)

:r [filename]在編輯的數(shù)據(jù)中涂炎,讀入另一個檔案的數(shù)據(jù)。亦即將 『filename』 這個檔案內(nèi)容加到游標(biāo)所在行后面

:n1,n2 w [filename]將 n1 到 n2 的內(nèi)容儲存成 filename 這個檔案设哗。

:! command暫時離開 vi 到指令列模式下執(zhí)行 command 的顯示結(jié)果唱捣!例如

『:! ls /home』即可在 vi 當(dāng)中察看 /home 底下以 ls 輸出的檔案信息!

vim 環(huán)境的變更

:set nu顯示行號网梢,設(shè)定之后震缭,會在每一行的前綴顯示該行的行號

:set nonu與 set nu 相反,為取消行號战虏!

特別注意拣宰,在 vi/vim 中党涕,數(shù)字是很有意義的!數(shù)字通常代表重復(fù)做幾次的意思巡社! 也有可能是代表去到第幾個什么什么的意思膛堤。

舉例來說,要刪除 50 行晌该,則是用 『50dd』 對吧肥荔! 數(shù)字加在動作之前燕耿,如我要向下移動 20 行呢?那就是『20j』或者是『20↓』即可姜胖。





十六誉帅、Shell 變量

2課時

實驗課

主要內(nèi)容

Shell 變量

定義變量時,變量名不加美元符號($谭期,PHP語言中變量需要)堵第,如:

your_name="w3cschool.cn"

注意吧凉,變量名和等號之間不能有空格隧出,這可能和你熟悉的所有編程語言都不一樣。同時,變量名的命名須遵循如下規(guī)則:

首個字符必須為字母(a-z朴肺,A-Z)需了。

中間不能有空格挪略,可以使用下劃線(_)。

不能使用標(biāo)點符號。

不能使用bash里的關(guān)鍵字(可用help命令查看保留關(guān)鍵字)恼除。

除了顯式地直接賦值气破,還可以用語句給變量賦值,如:

for file in `ls /etc`

以上語句將 /etc 下目錄的文件名循環(huán)出來。

使用變量

使用一個定義過的變量灸姊,只要在變量名前面加美元符號即可,如:

your_name="qinjx"

echo $your_name

echo ${your_name}

變量名外面的花括號是可選的甲喝,加不加都行非竿,加花括號是為了幫助解釋器識別變量的邊界,比如下面這種情況:

for skill in Ada Coffe Action Java do

? ? echo "I am good at ${skill}Script"

done

如果不給skill變量加花括號众眨,寫成echo "I am good at $skillScript",解釋器就會把$skillScript當(dāng)成一個變量(其值為空),代碼執(zhí)行結(jié)果就不是我們期望的樣子了让蕾。

推薦給所有變量加上花括號,這是個好的編程習(xí)慣栖疑。

已定義的變量,可以被重新定義奄容,如:

your_name="tom"

echo $your_name

your_name="alibaba"

echo $your_name

這樣寫是合法的奠衔,但注意,第二次賦值的時候不能寫$your_name="alibaba"合蔽,使用變量的時候才加美元符($)徘公。

Shell 字符串

字符串是shell編程中最常用最有用的數(shù)據(jù)類型(除了數(shù)字和字符串,也沒啥其它類型好用了)缝其,字符串可以用單引號,也可以用雙引號,也可以不用引號潜沦。單雙引號的區(qū)別跟PHP類似。

單引號

str='this is a string'

單引號字符串的限制:

單引號里的任何字符都會原樣輸出绪氛,單引號字符串中的變量是無效的;

單引號字串中不能出現(xiàn)單引號(對單引號使用轉(zhuǎn)義符后也不行)嘿辟。

雙引號

your_name='qinjx'

str="Hello, I know your are \"$your_name\"! \n"

雙引號的優(yōu)點:

雙引號里可以有變量

雙引號里可以出現(xiàn)轉(zhuǎn)義字符

拼接字符串

your_name="qinjx"

greeting="hello, "$your_name" !"

greeting_1="hello, ${your_name} !"

echo $greeting $greeting_1

獲取字符串長度

string="abcd"

echo ${#string} #輸出 4

提取子字符串

string="alibaba is a great company"

echo ${string:1:4} #輸出liba

查找子字符串

string="alibaba is a great company"

echo `expr index "$string" is`

注意:?以上腳本中 "`" 是反引號调鲸,而不是單引號 "'"呆万,不要看錯了哦祟印。

Shell 數(shù)組

bash支持一維數(shù)組(不支持多維數(shù)組)稚失,并且沒有限定數(shù)組的大小绪杏。

類似與C語言吮成,數(shù)組元素的下標(biāo)由0開始編號。獲取數(shù)組中的元素要利用下標(biāo)稻薇,下標(biāo)可以是整數(shù)或算術(shù)表達(dá)式名段,其值應(yīng)大于或等于0。

定義數(shù)組

在Shell中蓬抄,用括號來表示數(shù)組,數(shù)組元素用"空格"符號分割開夯到。定義數(shù)組的一般形式為:

數(shù)組名=(值1 值2 ... 值n)

例如:

array_name=(value0 value1 value2 value3)

或者

array_name=(

value0

value1

value2

value3

)

還可以單獨定義數(shù)組的各個分量:

array_name[0]=value0

array_name[1]=value1

array_name[n]=valuen

可以不使用連續(xù)的下標(biāo)嚷缭,而且下標(biāo)的范圍沒有限制。

讀取數(shù)組

讀取數(shù)組元素值的一般格式是:

${數(shù)組名[下標(biāo)]}

例如:

valuen=${array_name[n]}

使用@符號可以獲取數(shù)組中的所有元素耍贾,例如:

echo ${array_name[@]}

獲取數(shù)組的長度

獲取數(shù)組長度的方法與獲取字符串長度的方法相同阅爽,例如:

# 取得數(shù)組元素的個數(shù)

length=${#array_name[@]}

# 或者

length=${#array_name[*]}

# 取得數(shù)組單個元素的長度

lengthn=${#array_name[n]}

Shell 注釋

以"#"開頭的行就是注釋,會被解釋器忽略荐开。

sh里沒有多行注釋付翁,只能每一行加一個#號。只能像這樣:

#--------------------------------------------

# 這是一個自動打ipa的腳本誓焦,基于webfrogs的ipa-build書寫:

# https://github.com/webfrogs/xcode_shell/blob/master/ipa-build

# 功能:自動為etao ios app打包胆敞,產(chǎn)出物為14個渠道的ipa包

# 特色:全自動打包,不需要輸入任何參數(shù)

#--------------------------------------------

##### 用戶配置區(qū) 開始 #####

#

#

# 項目根目錄杂伟,推薦將此腳本放在項目的根目錄移层,這里就不用改了

# 應(yīng)用名,確保和Xcode里Product下的target_name.app名字一致

#

##### 用戶配置區(qū) 結(jié)束? #####

如果在開發(fā)過程中赫粥,遇到大段的代碼需要臨時注釋起來观话,過一會兒又取消注釋,怎么辦呢越平?

每一行加個#符號太費力了频蛔,可以把這一段要注釋的代碼用一對花括號括起來,定義成一個函數(shù)秦叛,沒有地方調(diào)用這個函數(shù)晦溪,這塊代碼就不會執(zhí)行,達(dá)到了和注釋一樣的效果挣跋。




十七三圆、Shell 傳遞參數(shù)

4課時

實驗課

主要內(nèi)容

Shell 傳遞參數(shù)

我們可以在執(zhí)行 Shell 腳本時,向腳本傳遞參數(shù),腳本內(nèi)獲取參數(shù)的格式為:$n舟肉。n?代表一個數(shù)字修噪,1 為執(zhí)行腳本的第一個參數(shù),2 為執(zhí)行腳本的第二個參數(shù)路媚,以此類推……

實例

以下實例我們向腳本傳遞三個參數(shù)黄琼,并分別輸出,其中?$0?為執(zhí)行的文件名:

#!/bin/bash

# author:W3Cschool教程

# url:www.w3cschool.cn

echo "Shell 傳遞參數(shù)實例整慎!";

echo "執(zhí)行的文件名:$0";

echo "第一個參數(shù)為:$1";

echo "第二個參數(shù)為:$2";

echo "第三個參數(shù)為:$3";

為腳本設(shè)置可執(zhí)行權(quán)限脏款,并執(zhí)行腳本,輸出結(jié)果如下所示:

$ chmod +x test.sh

$ ./test.sh 1 2 3

Shell 傳遞參數(shù)實例院领!

執(zhí)行的文件名:test.sh

第一個參數(shù)為:1

第二個參數(shù)為:2

第三個參數(shù)為:3

另外弛矛,還有幾個特殊字符用來處理參數(shù):

參數(shù)處理說明

$#傳遞到腳本的參數(shù)個數(shù)

$*以一個單字符串顯示所有向腳本傳遞的參數(shù)够吩。

如"$*"用「"」括起來的情況比然、以"$1 $2 … $n"的形式輸出所有參數(shù)。

$$腳本運行的當(dāng)前進(jìn)程ID號

$!后臺運行的最后一個進(jìn)程的ID號

$@與$*相同周循,但是使用時加引號强法,并在引號中返回每個參數(shù)。

如"$@"用「"」括起來的情況湾笛、以"$1" "$2" … "$n" 的形式輸出所有參數(shù)饮怯。

$-顯示Shell使用的當(dāng)前選項,與set命令功能相同嚎研。

$?顯示最后命令的退出狀態(tài)蓖墅。0表示沒有錯誤,其他任何值表明有錯誤临扮。

#!/bin/bash

# author:W3Cschool教程

# url:www.w3cschool.cn

echo "Shell 傳遞參數(shù)實例论矾!";

echo "第一個參數(shù)為:$1";

echo "參數(shù)個數(shù)為:$#";

echo "傳遞的參數(shù)作為一個字符串顯示:$*";

執(zhí)行腳本,輸出結(jié)果如下所示:

$ chmod +x test.sh

$ ./test.sh 1 2 3

Shell 傳遞參數(shù)實例杆勇!

第一個參數(shù)為:1

參數(shù)個數(shù)為:3

傳遞的參數(shù)作為一個字符串顯示:1 2 3

$* 與 $@ 區(qū)別:

相同點:都是引用所有參數(shù)贪壳。

不同點:只有在雙引號中體現(xiàn)出來。假設(shè)在腳本運行時寫了三個參數(shù) 1蚜退、2闰靴、3,钻注,則 " * " 等價于 "1 2 3"(傳遞了一個參數(shù))蚂且,而 "@" 等價于 "1" "2" "3"(傳遞了三個參數(shù))。

#!/bin/bash

# author:W3Cschool教程

# url:www.w3cschool.cn

echo "-- \$* 演示 ---"

for i in "$*"; do

? ? echo $i

done

echo "-- \$@ 演示 ---"

for i in "$@"; do

? ? echo $i

done

執(zhí)行腳本幅恋,輸出結(jié)果如下所示:

$ chmod +x test.sh

$ ./test.sh 1 2 3

-- $* 演示 ---

1 2 3

-- $@ 演示 ---

1

2

3





十八杏死、Shell 運算符

4課時

實驗課

主要內(nèi)容

Shell 基本運算符

Shell 和其他編程語言一樣,支持多種運算符仇冯,包括:

算數(shù)運算符

關(guān)系運算符

布爾運算符

字符串運算符

文件測試運算符

expr 是一款表達(dá)式計算工具姥份,使用它能完成表達(dá)式的求值操作。

例如擦盾,兩個數(shù)相加(注意使用的是反引號 ` 而不是單引號 '):

#!/bin/bash

val=`expr 2 + 2`

echo "兩數(shù)之和為 : $val"

執(zhí)行腳本窒舟,輸出結(jié)果如下所示:

兩數(shù)之和為 : 4

兩點注意:

表達(dá)式和運算符之間要有空格系忙,例如 2+2 是不對的,必須寫成 2 + 2惠豺,這與我們熟悉的大多數(shù)編程語言不一樣银还。

完整的表達(dá)式要被 ` ` 包含,注意這個字符不是常用的單引號洁墙,在 Esc 鍵下邊蛹疯。

算術(shù)運算符

下表列出了常用的算術(shù)運算符,假定變量 a 為 10热监,變量 b 為 20:

運算符說明舉例

+加法`expr $a + $b` 結(jié)果為?30捺弦。

-減法`expr $a - $b` 結(jié)果為 -10。

*乘法`expr $a \* $b` 結(jié)果為 ?200孝扛。

/除法`expr $b / $a` 結(jié)果為?2列吼。

%取余`expr $b % $a` 結(jié)果為?0。

=賦值a=$b 將把變量 b 的值賦給 a苦始。

==相等寞钥。用于比較兩個數(shù)字,相同則返回 true陌选。[ $a == $b ] 返回?false理郑。

!=不相等。用于比較兩個數(shù)字咨油,不相同則返回 true您炉。[ $a != $b ] 返回 true。

注意:條件表達(dá)式要放在方括號之間臼勉,并且要有空格邻吭,例如:?[$a==$b]?是錯誤的,必須寫成?[ $a == $b ]宴霸。

實例

算術(shù)運算符實例如下:

#!/bin/bash

# author:W3Cschool教程

# url:www.w3cschool.cn

a=10

b=20

val=`expr $a + $b`

echo "a + b : $val"

val=`expr $a - $b`

echo "a - b : $val"

val=`expr $a \* $b`

echo "a * b : $val"

val=`expr $b / $a`

echo "b / a : $val"

val=`expr $b % $a`

echo "b % a : $val"

if [ $a == $b ]

then

? echo "a 等于 b"

fi

if [ $a != $b ]

then

? echo "a 不等于 b"

fi

執(zhí)行腳本囱晴,輸出結(jié)果如下所示:

a + b : 30

a - b : -10

a * b : 200

b / a : 2

b % a : 0

a 不等于 b

注意:乘號(*)前邊必須加反斜杠(\)才能實現(xiàn)乘法運算;if...then...fi 是條件語句瓢谢,后續(xù)將會講解畸写。在 MAC 中 shell 的 expr 語法是:$((表達(dá)式)),此處表達(dá)式中的 "*" 不需要轉(zhuǎn)義符號 "\" 氓扛。

關(guān)系運算符

關(guān)系運算符只支持?jǐn)?shù)字枯芬,不支持字符串论笔,除非字符串的值是數(shù)字。

下表列出了常用的關(guān)系運算符千所,假定變量 a 為 10狂魔,變量 b 為 20:

運算符說明舉例

-eq檢測兩個數(shù)是否相等,相等返回 true淫痰。[ $a -eq $b ] 返回?false最楷。

-ne檢測兩個數(shù)是否相等,不相等返回 true待错。[ $a -ne $b ] 返回 true籽孙。

-gt檢測左邊的數(shù)是否大于右邊的,如果是火俄,則返回 true犯建。[ $a -gt $b ] 返回 false。

-lt檢測左邊的數(shù)是否小于右邊的瓜客,如果是适瓦,則返回 true。[ $a -lt $b ] 返回 true忆家。

-ge檢測左邊的數(shù)是否大于等于右邊的犹菇,如果是,則返回 true芽卿。[ $a -ge $b ] 返回 false。

-le檢測左邊的數(shù)是否小于等于右邊的胳搞,如果是卸例,則返回 true。[ $a -le $b ] 返回 true肌毅。

實例

關(guān)系運算符實例如下:

#!/bin/bash

# author:W3Cschool教程

# url:www.w3cschool.cn

a=10

b=20

if [ $a -eq $b ]

then

? echo "$a -eq $b : a 等于 b"

else

? echo "$a -eq $b: a 不等于 b"

fi

if [ $a -ne $b ]

then

? echo "$a -ne $b: a 不等于 b"

else

? echo "$a -ne $b : a 等于 b"

fi

if [ $a -gt $b ]

then

? echo "$a -gt $b: a 大于 b"

else

? echo "$a -gt $b: a 不大于 b"

fi

if [ $a -lt $b ]

then

? echo "$a -lt $b: a 小于 b"

else

? echo "$a -lt $b: a 不小于 b"

fi

if [ $a -ge $b ]

then

? echo "$a -ge $b: a 大于或等于 b"

else

? echo "$a -ge $b: a 小于 b"

fi

if [ $a -le $b ]

then

? echo "$a -le $b: a 小于或等于 b"

else

? echo "$a -le $b: a 大于 b"

fi

執(zhí)行腳本筷转,輸出結(jié)果如下所示:

10 -eq 20: a 不等于 b

10 -ne 20: a 不等于 b

10 -gt 20: a 不大于 b

10 -lt 20: a 小于 b

10 -ge 20: a 小于 b

10 -le 20: a 小于或等于 b

布爾運算符

下表列出了常用的布爾運算符,假定變量 a 為 10悬而,變量 b 為 20:

運算符說明舉例

!非運算呜舒,表達(dá)式為 true 則返回 false,否則返回 true笨奠。[ ! false ] 返回 true袭蝗。

-o或運算,有一個表達(dá)式為 true 則返回 true般婆。[ $a -lt 20 -o $b -gt 100 ] 返回?true到腥。

-a與運算,兩個表達(dá)式都為 true 才返回 true蔚袍。[ $a -lt 20 -a $b -gt 100 ] 返回?false乡范。

實例

布爾運算符實例如下:

#!/bin/bash

# author:W3Cschool教程

# url:www.w3cschool.cn

a=10

b=20

if [ $a != $b ]

then

? echo "$a != $b : a 不等于 b"

else

? echo "$a != $b: a 等于 b"

fi

if [ $a -lt 100 -a $b -gt 15 ]

then

? echo "$a -lt 100 -a $b -gt 15 : 返回 true"

else

? echo "$a -lt 100 -a $b -gt 15 : 返回 false"

fi

if [ $a -lt 100 -o $b -gt 100 ]

then

? echo "$a -lt 100 -o $b -gt 100 : 返回 true"

else

? echo "$a -lt 100 -o $b -gt 100 : 返回 false"

fi

if [ $a -lt 5 -o $b -gt 100 ]

then

? echo "$a -lt 5 -o $b -gt 100 : 返回 true"

else

? echo "$a -lt 5 -o $b -gt 100 : 返回 false"

fi

執(zhí)行腳本,輸出結(jié)果如下所示:

10 != 20 : a 不等于 b

10 -lt 100 -a 20 -gt 15 : 返回 true

10 -lt 100 -o 20 -gt 100 : 返回 true

10 -lt 5 -o 20 -gt 100 : 返回 false

邏輯運算符

以下介紹 Shell 的邏輯運算符,假定變量 a 為 10晋辆,變量 b 為 20:

運算符說明舉例

&&邏輯的 AND[[ $a -lt 100 && $b -gt 100 ]] 返回 false

||邏輯的 OR[[ $a -lt 100 || $b -gt 100 ]] 返回 true

實例

邏輯運算符實例如下:

#!/bin/bash

# author:W3Cschool教程

# url:www.w3cschool.cn

a=10

b=20

if [[ $a -lt 100 && $b -gt 100 ]]

then

? echo "返回 true"

else

? echo "返回 false"

fi

if [[ $a -lt 100 || $b -gt 100 ]]

then

? echo "返回 true"

else

? echo "返回 false"

fi

執(zhí)行腳本渠脉,輸出結(jié)果如下所示:

返回 false

返回 true

字符串運算符

下表列出了常用的字符串運算符,假定變量 a 為 "abc"瓶佳,變量 b 為 "efg":

運算符說明舉例

=檢測兩個字符串是否相等连舍,相等返回 true。[ $a = $b ] 返回 false涩哟。

!=檢測兩個字符串是否相等索赏,不相等返回 true。[ $a != $b ] 返回?true贴彼。

-z檢測字符串長度是否為0潜腻,為0返回 true。[ -z $a ] 返回 false器仗。

-n檢測字符串長度是否為0融涣,不為0返回 true。[ -n $a ] 返回 true精钮。

str檢測字符串是否為空威鹿,不為空返回 true。[ $a ] 返回?true轨香。

實例

字符串運算符實例如下:

#!/bin/bash

# author:W3Cschool教程

# url:www.w3cschool.cn

a="abc"

b="efg"

if [ $a = $b ]

then

? echo "$a = $b : a 等于 b"

else

? echo "$a = $b: a 不等于 b"

fi

if [ $a != $b ]

then

? echo "$a != $b : a 不等于 b"

else

? echo "$a != $b: a 等于 b"

fi

if [ -z $a ]

then

? echo "-z $a : 字符串長度為 0"

else

? echo "-z $a : 字符串長度不為 0"

fi

if [ -n $a ]

then

? echo "-n $a : 字符串長度不為 0"

else

? echo "-n $a : 字符串長度為 0"

fi

if [ $a ]

then

? echo "$a : 字符串不為空"

else

? echo "$a : 字符串為空"

fi

執(zhí)行腳本忽你,輸出結(jié)果如下所示:

abc = efg: a 不等于 b

abc != efg : a 不等于 b

-z abc : 字符串長度不為 0

-n abc : 字符串長度不為 0

abc : 字符串不為空

文件測試運算符

文件測試運算符用于檢測 Unix 文件的各種屬性。

屬性檢測描述如下:

操作符說明舉例

-b file檢測文件是否是塊設(shè)備文件臂容,如果是科雳,則返回 true。[ -b $file ] 返回 false脓杉。

-c file檢測文件是否是字符設(shè)備文件糟秘,如果是,則返回 true球散。[ -c $file ] 返回?false尿赚。

-d file檢測文件是否是目錄,如果是蕉堰,則返回 true凌净。[ -d $file ] 返回 false。

-f file檢測文件是否是普通文件(既不是目錄嘁灯,也不是設(shè)備文件)泻蚊,如果是,則返回 true丑婿。[ -f $file ] 返回?true性雄。

-g file檢測文件是否設(shè)置了 SGID 位没卸,如果是,則返回 true秒旋。[ -g $file ] 返回?false约计。

-k file檢測文件是否設(shè)置了粘著位(Sticky Bit),如果是迁筛,則返回 true煤蚌。[ -k $file ] 返回?false。

-p file檢測文件是否是有名管道细卧,如果是尉桩,則返回 true。[ -p $file ] 返回?false贪庙。

-u file檢測文件是否設(shè)置了 SUID 位蜘犁,如果是,則返回 true止邮。[ -u $file ] 返回?false这橙。

-r file檢測文件是否可讀,如果是导披,則返回 true屈扎。[ -r $file ] 返回?true。

-w file檢測文件是否可寫撩匕,如果是鹰晨,則返回 true。[ -w $file ] 返回?true滑沧。

-x file檢測文件是否可執(zhí)行并村,如果是,則返回 true滓技。[ -x $file ] 返回?true。

-s file檢測文件是否為空(文件大小是否大于0)棚潦,不為空返回 true令漂。[ -s $file ] 返回?true。

-e file檢測文件(包括目錄)是否存在丸边,如果是叠必,則返回 true。[ -e $file ] 返回?true妹窖。

實例

變量 file 表示文件"/var/www/w3cschool/test.sh"纬朝,它的大小為100字節(jié),具有 rwx 權(quán)限骄呼。下面的代碼共苛,將檢測該文件的各種屬性:

#!/bin/bash

# author:W3Cschool教程

# url:www.w3cschool.cn

file="/var/www/w3cschool/test.sh"

if [ -r $file ]

then

? echo "文件可讀"

else

? echo "文件不可讀"

fi

if [ -w $file ]

then

? echo "文件可寫"

else

? echo "文件不可寫"

fi

if [ -x $file ]

then

? echo "文件可執(zhí)行"

else

? echo "文件不可執(zhí)行"

fi

if [ -f $file ]

then

? echo "文件為普通文件"

else

? echo "文件為特殊文件"

fi

if [ -d $file ]

then

? echo "文件是個目錄"

else

? echo "文件不是個目錄"

fi

if [ -s $file ]

then

? echo "文件不為空"

else

? echo "文件為空"

fi

if [ -e $file ]

then

? echo "文件存在"

else

? echo "文件不存在"

fi

執(zhí)行腳本判没,輸出結(jié)果如下所示:

文件可讀文件可寫文件可執(zhí)行文件為普通文件文件不是個目錄文件不為空文件存在。




十九隅茎、Shell 函數(shù)

2課時

實驗課

主要內(nèi)容

Shell 函數(shù)

linux shell 可以用戶定義函數(shù)澄峰,然后在shell腳本中可以隨便調(diào)用。

shell中函數(shù)的定義格式如下:

[ function ] funname [()]

{

? ? action;

? ? [return int;]

}

說明:

1辟犀、可以帶function fun() 定義俏竞,也可以直接fun() 定義,不帶任何參數(shù)。

2堂竟、參數(shù)返回魂毁,可以顯示加:return 返回,如果不加出嘹,將以最后一條命令運行結(jié)果席楚,作為返回值。 return后跟數(shù)值n(0-255

下面的例子定義了一個函數(shù)并進(jìn)行調(diào)用:

#!/bin/bash

demoFun(){

??? echo "這是我的第一個 shell 函數(shù)!"

}

echo "-----函數(shù)開始執(zhí)行-----"

demoFun

echo "-----函數(shù)執(zhí)行完畢-----"

輸出結(jié)果:

-----函數(shù)開始執(zhí)行-----

這是我的第一個 shell 函數(shù)!

-----函數(shù)執(zhí)行完畢-----

下面定義一個帶有return語句的函數(shù):

#!/bin/bash

funWithReturn(){

? ? echo "這個函數(shù)會對輸入的兩個數(shù)字進(jìn)行相加運算..."

??? echo "輸入第一個數(shù)字: "

??? read aNum

??? echo "輸入第二個數(shù)字: "

??? read anotherNum

??? echo "兩個數(shù)字分別為 $aNum 和 $anotherNum !"

??? return $(($aNum+$anotherNum))

}

funWithReturn

echo "輸入的兩個數(shù)字之和為 $? !"

輸出類似下面:

這個函數(shù)會對輸入的兩個數(shù)字進(jìn)行相加運算...

輸入第一個數(shù)字:

1

輸入第二個數(shù)字:

2

兩個數(shù)字分別為 1 和 2 !

輸入的兩個數(shù)字之和為 3 !

函數(shù)返回值在調(diào)用該函數(shù)后通過 $? 來獲得疚漆。

注意:所有函數(shù)在使用前必須定義帐要。這意味著必須將函數(shù)放在腳本開始部分,直至shell解釋器首次發(fā)現(xiàn)它時幔妨,才可以使用斥滤。調(diào)用函數(shù)僅使用其函數(shù)名即可。

函數(shù)參數(shù)

在Shell中丸升,調(diào)用函數(shù)時可以向其傳遞參數(shù)铆农。在函數(shù)體內(nèi)部,通過 $n 的形式來獲取參數(shù)的值狡耻,例如墩剖,$1表示第一個參數(shù),$2表示第二個參數(shù)...

帶參數(shù)的函數(shù)示例:

#!/bin/bash

funWithParam(){

? ? echo "第一個參數(shù)為 $1 !"

??? echo "第二個參數(shù)為 $2 !"

??? echo "第十個參數(shù)為 $10 !"

??? echo "第十個參數(shù)為 ${10} !"

??? echo "第十一個參數(shù)為 ${11} !"

??? echo "參數(shù)總數(shù)有 $# 個!"

??? echo "作為一個字符串輸出所有參數(shù) $* !"

}

funWithParam 1 2 3 4 5 6 7 8 9 34 73

輸出結(jié)果:

第一個參數(shù)為 1 !

第二個參數(shù)為 2 !

第十個參數(shù)為 10 !

第十個參數(shù)為 34 !

第十一個參數(shù)為 73 !

參數(shù)總數(shù)有 11 個!

作為一個字符串輸出所有參數(shù) 1 2 3 4 5 6 7 8 9 34 73 !

注意夷狰,$10 不能獲取第十個參數(shù)岭皂,獲取第十個參數(shù)需要${10}。當(dāng)n>=10時沼头,需要使用${n}來獲取參數(shù)爷绘。

另外,還有幾個特殊字符用來處理參數(shù):

參數(shù)處理說明

$#傳遞到腳本的參數(shù)個數(shù)

$*以一個單字符串顯示所有向腳本傳遞的參數(shù)

$$腳本運行的當(dāng)前進(jìn)程ID號

$!后臺運行的最后一個進(jìn)程的ID號

$@與$*相同进倍,但是使用時加引號土至,并在引號中返回每個參數(shù)。

$-顯示Shell使用的當(dāng)前選項猾昆,與set命令功能相同陶因。

$?顯示最后命令的退出狀態(tài)。0表示沒有錯誤垂蜗,其他任何值表明有錯誤楷扬。




二十解幽、Shell 輸入/輸出重定向

2課時

實驗課

主要內(nèi)容

Shell 輸入/輸出重定向

大多數(shù) UNIX 系統(tǒng)命令從你的終端接受輸入并將所產(chǎn)生的輸出發(fā)送回??到您的終端。一個命令通常從一個叫標(biāo)準(zhǔn)輸入的地方讀取輸入毅否,默認(rèn)情況下亚铁,這恰好是你的終端。同樣螟加,一個命令通常將其輸出寫入到標(biāo)準(zhǔn)輸出徘溢,默認(rèn)情況下,這也是你的終端捆探。

重定向命令列表如下:

命令說明

command > file將輸出重定向到 file然爆。

command < file將輸入重定向到 file。

command >> file將輸出以追加的方式重定向到 file黍图。

n > file將文件描述符為 n 的文件重定向到 file曾雕。

n >> file將文件描述符為 n 的文件以追加的方式重定向到 file。

n >& m將輸出文件 m 和 n 合并助被。

n <& m將輸入文件 m 和 n 合并剖张。

<< tag將開始標(biāo)記 tag 和結(jié)束標(biāo)記 tag 之間的內(nèi)容作為輸入。

需要注意的是文件描述符 0 通常是標(biāo)準(zhǔn)輸入(STDIN)揩环,1 是標(biāo)準(zhǔn)輸出(STDOUT)搔弄,2 是標(biāo)準(zhǔn)錯誤輸出(STDERR)。

輸出重定向

重定向一般通過在命令間插入特定的符號來實現(xiàn)丰滑。特別的顾犹,這些符號的語法如下所示:

command1 > file1

上面這個命令執(zhí)行command1然后將輸出的內(nèi)容存入file1。

注意任何file1內(nèi)的已經(jīng)存在的內(nèi)容將被新內(nèi)容替代褒墨。如果要將新內(nèi)容添加在文件末尾炫刷,請使用>>操作符。

實例

執(zhí)行下面的 who 命令郁妈,它將命令的完整的輸出重定向在用戶文件中(users):

$ who > users

執(zhí)行后浑玛,并沒有在終端輸出信息,這是因為輸出已被從默認(rèn)的標(biāo)準(zhǔn)輸出設(shè)備(終端)重定向到指定的文件噩咪。

你可以使用 cat 命令查看文件內(nèi)容:

$ cat users

_mbsetupuser console? Oct 31 17:35

laolan? ? console? Oct 31 17:35

laolan? ? ttys000? Dec? 1 11:33

輸出重定向會覆蓋文件內(nèi)容锄奢,請看下面的例子:

$ echo "W3Cschool教程:www.w3cschool.cn" > users

$ cat users

W3Cschool教程:www.w3cschool.cn

$

如果不希望文件內(nèi)容被覆蓋,可以使用 >> 追加到文件末尾剧腻,例如:

$ echo "W3Cschool教程:www.w3cschool.cn" >> users

$ cat users

W3Cschool教程:www.w3cschool.cn

W3Cschool教程:www.w3cschool.cn

$

輸入重定向

和輸出重定向一樣,Unix 命令也可以從文件獲取輸入涂屁,語法為:

command1 < file1

這樣书在,本來需要從鍵盤獲取輸入的命令會轉(zhuǎn)移到文件讀取內(nèi)容。

注意:輸出重定向是大于號(>)拆又,輸入重定向是小于號(<)儒旬。

實例

接著以上實例栏账,我們需要統(tǒng)計 users 文件的行數(shù),執(zhí)行以下命令:

$ wc -l users

? ? ? 2 users

也可以將輸入重定向到 users 文件:

$? wc -l < users

? ? ? 2

注意:上面兩個例子的結(jié)果不同:第一個例子,會輸出文件名栈源;第二個不會挡爵,因為它僅僅知道從標(biāo)準(zhǔn)輸入讀取內(nèi)容。

command1 < infile > outfile

同時替換輸入和輸出甚垦,執(zhí)行command1茶鹃,從文件infile讀取內(nèi)容,然后將輸出寫入到outfile中艰亮。

重定向深入講解

一般情況下闭翩,每個 Unix/Linux 命令運行時都會打開三個文件:

標(biāo)準(zhǔn)輸入文件(stdin):stdin的文件描述符為0,Unix程序默認(rèn)從stdin讀取數(shù)據(jù)迄埃。

標(biāo)準(zhǔn)輸出文件(stdout):stdout 的文件描述符為1疗韵,Unix程序默認(rèn)向stdout輸出數(shù)據(jù)。

標(biāo)準(zhǔn)錯誤文件(stderr):stderr的文件描述符為2侄非,Unix程序會向stderr流中寫入錯誤信息蕉汪。

默認(rèn)情況下,command > file 將 stdout 重定向到 file逞怨,command < file 將stdin 重定向到 file者疤。

如果希望 stderr 重定向到 file,可以這樣寫:

$ command 2 > file

如果希望 stderr 追加到 file 文件末尾骇钦,可以這樣寫:

$ command 2 >> file

2?表示標(biāo)準(zhǔn)錯誤文件(stderr)宛渐。

如果希望將 stdout 和 stderr 合并后重定向到 file,可以這樣寫:

$ command > file 2>&1

或者

$ command >> file 2>&1

如果希望對 stdin 和 stdout 都重定向眯搭,可以這樣寫:

$ command < file1 >file2

command 命令將 stdin 重定向到 file1窥翩,將 stdout 重定向到 file2。

Here Document

Here Document 是 Shell 中的一種特殊的重定向方式鳞仙,用來將輸入重定向到一個交互式 Shell 腳本或程序寇蚊。

它的基本的形式如下:

command << delimiter

? ? document

delimiter

它的作用是將兩個 delimiter 之間的內(nèi)容(document) 作為輸入傳遞給 command。

注意:

結(jié)尾的delimiter 一定要頂格寫棍好,前面不能有任何字符仗岸,后面也不能有任何字符,包括空格和 tab 縮進(jìn)借笙。

開始的delimiter前后的空格會被忽略掉扒怖。

實例

在命令行中通過 wc -l 命令計算 Here Document 的行數(shù):

$ wc -l << EOF

? ? 歡迎來到

? ? W3Cschool教程

? ? www.w3cschool.cn

EOF

3? ? ? ? ? # 輸出結(jié)果為 3 行

$

我們也可以將 Here Document 用在腳本中,例如:

#!/bin/bash

# author:W3Cschool教程

# url:www.w3cschool.cn

cat << EOF

歡迎來到

W3Cschool教程

www.w3cschool.cn

EOF

執(zhí)行以上腳本业稼,輸出結(jié)果:

歡迎來到

W3Cschool教程

www.w3cschool.cn

/dev/null 文件

如果希望執(zhí)行某個命令盗痒,但又不希望在屏幕上顯示輸出結(jié)果,那么可以將輸出重定向到 /dev/null:

$ command > /dev/null

/dev/null 是一個特殊的文件低散,寫入到它的內(nèi)容都會被丟棄俯邓;如果嘗試從該文件讀取內(nèi)容骡楼,那么什么也讀不到。但是 /dev/null 文件非常有用稽鞭,將命令的輸出重定向到它鸟整,會起到"禁止輸出"的效果。

如果希望屏蔽 stdout 和 stderr朦蕴,可以這樣寫:

$ command > /dev/null 2>&1

注意:0 是標(biāo)準(zhǔn)輸入(STDIN)篮条,1 是標(biāo)準(zhǔn)輸出(STDOUT),2 是標(biāo)準(zhǔn)錯誤輸出(STDERR)梦重。








【FOOTER】

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末兑燥,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子琴拧,更是在濱河造成了極大的恐慌降瞳,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,013評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蚓胸,死亡現(xiàn)場離奇詭異挣饥,居然都是意外死亡,警方通過查閱死者的電腦和手機沛膳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,205評論 2 382
  • 文/潘曉璐 我一進(jìn)店門扔枫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人锹安,你說我怎么就攤上這事短荐。” “怎么了叹哭?”我有些...
    開封第一講書人閱讀 152,370評論 0 342
  • 文/不壞的土叔 我叫張陵忍宋,是天一觀的道長。 經(jīng)常有香客問我风罩,道長糠排,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,168評論 1 278
  • 正文 為了忘掉前任超升,我火速辦了婚禮入宦,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘室琢。我一直安慰自己乾闰,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,153評論 5 371
  • 文/花漫 我一把揭開白布盈滴。 她就那樣靜靜地躺著汹忠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上宽菜,一...
    開封第一講書人閱讀 48,954評論 1 283
  • 那天,我揣著相機與錄音竿报,去河邊找鬼铅乡。 笑死,一個胖子當(dāng)著我的面吹牛烈菌,可吹牛的內(nèi)容都是我干的阵幸。 我是一名探鬼主播,決...
    沈念sama閱讀 38,271評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼芽世,長吁一口氣:“原來是場噩夢啊……” “哼挚赊!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起济瓢,我...
    開封第一講書人閱讀 36,916評論 0 259
  • 序言:老撾萬榮一對情侶失蹤荠割,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后旺矾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蔑鹦,經(jīng)...
    沈念sama閱讀 43,382評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,877評論 2 323
  • 正文 我和宋清朗相戀三年箕宙,在試婚紗的時候發(fā)現(xiàn)自己被綠了嚎朽。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 37,989評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡柬帕,死狀恐怖哟忍,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情陷寝,我是刑警寧澤锅很,帶...
    沈念sama閱讀 33,624評論 4 322
  • 正文 年R本政府宣布,位于F島的核電站盼铁,受9級特大地震影響粗蔚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜饶火,卻給世界環(huán)境...
    茶點故事閱讀 39,209評論 3 307
  • 文/蒙蒙 一鹏控、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧肤寝,春花似錦当辐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,199評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽厂榛。三九已至蛉签,卻和暖如春渊鞋,著一層夾襖步出監(jiān)牢的瞬間投队,已是汗流浹背畜伐。 一陣腳步聲響...
    開封第一講書人閱讀 31,418評論 1 260
  • 我被黑心中介騙來泰國打工吗讶, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留袖裕,地道東北人曹抬。 一個月前我還...
    沈念sama閱讀 45,401評論 2 352
  • 正文 我出身青樓,卻偏偏與公主長得像急鳄,于是被迫代替她去往敵國和親谤民。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,700評論 2 345

推薦閱讀更多精彩內(nèi)容