一、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包
apt-get?install?python2.7? 安裝2.7版本的Python
之后進(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
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ù)及描述
比較兩個字典元素图贸。
計算字典元素個數(shù)蹂季,即鍵的總數(shù)。
輸出字典可打印的字符串表示疏日。
返回輸入的變量類型偿洁,如果變量是字典就返回字典類型。
Python字典包含了以下內(nèi)置函數(shù):
序號函數(shù)及描述
刪除字典內(nèi)所有元素
返回一個字典的淺復(fù)制
創(chuàng)建一個新字典沟优,以序列seq中元素做字典的鍵涕滋,val為字典所有鍵對應(yīng)的初始值
4radiansdict.get(key, default=None)
返回指定鍵的值,如果值不在字典中返回default值
如果鍵在字典dict里返回true净神,否則返回false
以列表返回可遍歷的(鍵, 值) 元組數(shù)組
以列表返回一個字典所有的鍵
8radiansdict.setdefault(key, default=None)
和get()類似, 但如果鍵不已經(jīng)存在于字典中何吝,將會添加鍵并將值設(shè)為default
把字典dict2的鍵/值對更新到dict里
以列表返回字典中的所有值
六、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>
4課時
實驗課
主要內(nèi)容
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/
注:建議安裝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】