- 論壇徽章:
- 0
|
Python中應(yīng)用shell腳本
日期:2011-12-28 來源: constantina 分享至:
os.chkdir(path) 轉(zhuǎn)換到目錄path 下。
os.system('md a') 可以直接創(chuàng)建目錄。
os.name字符串指示你正在使用的平臺(tái)。比如對(duì)于Windows,它是'nt',而對(duì)于Linux/Unix用戶,它是'posix'。
● os.getcwd()函數(shù)得到當(dāng)前工作目錄,即當(dāng)前Python腳本工作的目錄路徑。
● os.getenv()和os.putenv()函數(shù)分別用來讀取和設(shè)置環(huán)境變量。
● os.listdir()返回指定目錄下的所有文件和目錄名。
● os.remove()函數(shù)用來刪除一個(gè)文件。
● os.system()函數(shù)用來運(yùn)行shell命令。
● os.linesep字符串給出當(dāng)前平臺(tái)使用的行終止符。例如,Windows使用'\r\n',Linux使用'\n'而Mac使用'\r'。
● os.path.split()函數(shù)返回一個(gè)路徑的目錄名和文件名。
>>> os.path.split('/home/swaroop/byte/code/poem.txt')
('/home/swaroop/byte/code', 'poem.txt')
● os.path.isfile()和os.path.isdir()函數(shù)分別檢驗(yàn)給出的路徑是一個(gè)文件還是目錄。類似地,os.path.exists()函數(shù)用來檢驗(yàn)給出的路徑是否真地存在。
文件重定向
已有PY文件new1.py ,在命令行下輸入:new1>new.txt 可以將new1運(yùn)行的結(jié)果輸出到文件new.txt,這稱為流重定向。
python可以做shell腳本嗎? 首先介紹一個(gè)函數(shù):
os.system(command)
這個(gè)函數(shù)可以調(diào)用shell運(yùn)行命令行command并且返回它的返回值。試一下在python的解釋器里輸入os.system(”ls -l”),就可以看到”ls”列出了當(dāng)前目錄下的文件。可以說,通過這個(gè)函數(shù),python就擁有了shell的所有能力。呵呵。。不過,通常這條命令不 需要用到。因?yàn)閟hell常用的那些命令在python中通常有對(duì)應(yīng)而且同樣簡(jiǎn)潔的寫法。
shell中最常用的是ls命令,python對(duì)應(yīng)的寫法是:os.listdir(dirname),這個(gè)函數(shù)返回字符串列表,里面是所有的文件名,不過不包含”.”和”..”。如果要遍歷整個(gè)目錄的話就會(huì)比較復(fù)雜一點(diǎn)。我們等下再說吧。先在解釋器里試一下:
>>> os.listdir(”/”)
[’tmp’, ‘misc’, ‘opt’, ‘root’, ‘.autorelabel’, ’sbin’, ’srv’, ‘.autofsck’, ‘mnt’, ‘usr’, ‘var’, ‘etc’, ’selinux’, ‘lib’, ‘net’, ‘lost+found’, ’sys’, ‘media’, ‘dev’, ‘proc’, ‘boot’, ‘home’, ‘bin’]
就像這樣,接下去所有命令都可以在python的解釋器里直接運(yùn)行觀看結(jié)果。
對(duì)應(yīng)于cp命令的是:shutil.copy(src,dest),這個(gè)函數(shù)有兩個(gè)參數(shù),參數(shù)src是指源文件的名字,參數(shù)dest則是目標(biāo)文件或 者目標(biāo)目錄的名字。 如果dest是一個(gè)目錄名,就會(huì)在那個(gè)目錄下創(chuàng)建一個(gè)相同名字的文件。與shutil.copy函數(shù)相類似的是 shutil.copy2(src,dest),不過copy2還會(huì)復(fù)制最后存取時(shí)間和最后更新時(shí)間。
不過,shell的cp命令還可以復(fù)制目錄,python的shutil.copy卻不行,第一個(gè)參數(shù)只能是一個(gè)文件。這怎么辦?其 實(shí),python還有個(gè)shutil.copytree(src,dst[,symlinks]) 。參數(shù)多了一個(gè)symlinks,它是一個(gè)布爾值,如果是True的話就創(chuàng)建符號(hào)鏈接。
移動(dòng)或者重命名文件和目錄呢?估計(jì)被聰明的朋友猜到了,shutil.move(src,dst),呵呵。。與mv命令類似,如果src和dst在 同一個(gè)文件系統(tǒng)上,shutil.move只是簡(jiǎn)單改一下名字,如果src和dst在不同的文件系統(tǒng)上,shutil.move會(huì)先把src復(fù)制到 dst,然后刪除src文件?吹浆F(xiàn)在,大多數(shù)朋友應(yīng)該已經(jīng)對(duì)python的能力有點(diǎn)眉目了,接下來我就列個(gè)表,介紹一下其它的函數(shù):
os.chdir(dirname)
把當(dāng)前工作目錄切換到dirname下
os.getcwd()
返回當(dāng)前的工作目錄路徑
os.chroot(dirname)
把dirname作為進(jìn)程的根目錄。和*nix下的chroot命令類似
os.chmod(path,mode)
更改path的權(quán)限位。mode可以是以下值(使用or)的組合:
os.S_ISUID
os.S_ISGID
os.S_ENFMT
os.S_ISVTX
os.S_IREAD
os.S_IWRITE
os.S_IEXEC
os.S_IRWXU
os.S_IRUSR
os.S_IWUSR
os.S_IXUSR
os.S_IRWXG
os.S_IRGRP
os.S_IWGRP
os.S_IXGRP
os.S_IRWXO
os.S_IROTH
os.S_IWOTH
os.S_IXOTH
具體它們是什么含義,就不仔細(xì)說了,基本上就是R代表讀,W代表寫,X代表執(zhí)行權(quán)限。USR代表用戶,GRP代表組,OTH代表其它。
os.chown(path,uid,gid)
改變文件的屬主。uid和gid為-1的時(shí)候不改變?cè)瓉淼膶僦鳌?br />
os.link(src,dst)
創(chuàng)建硬連接
os.mkdir(path,[mode])
創(chuàng)建目錄。mode的意義參見os.chmod(),默認(rèn)是0777
os.makedirs(path,[mode])
和os.mkdir()類似,不過會(huì)先創(chuàng)建不存在的父目錄。
os.readlink(path)
返回path這個(gè)符號(hào)鏈接所指向的路徑
os.remove(path)
刪除文件,不能用于刪除目錄
os.rmdir(path)
刪除文件夾,不能用于刪除文件
removedirs(path)
遞歸移除目錄。類似于rmdir()的工作,除了如果子目錄被成功地刪除,removedirs()嘗試接連地刪除每個(gè)在path中提及的父目錄,直到一個(gè)錯(cuò)誤被掛起(這個(gè)錯(cuò)誤被忽略,因?yàn)樗ǔR馕陡改夸洸粸榭。)例如?quot;os.removedirs(‘foo/bar/baz')"將首先刪除"'foo/bar/baz'"目錄,然后如果 "'foo/bar'"和"'foo'"為空刪除它們。如果子目錄不能被成功地刪除掛起OSError。1.5.2版本中的新方法。
rename(src, dst)
重命名文件或目錄src為dst。如果dst是一個(gè)目錄,OSError將被掛起。在Unix上,如果dst存在并且是一個(gè)文件,如果用戶有權(quán)限它將被默默地刪除。在一些Unix風(fēng)格的系統(tǒng)上如果src和dst是不同的文件系統(tǒng),這個(gè)操作可能失敗。如果成功,重命名將是一個(gè)基本的操作(這是一個(gè)POSIX要求)。在Windows上,如果dst已經(jīng)存在,甚至如果它是一個(gè)文件,OSError將被掛起;當(dāng)dst命名一個(gè)已存在的文件時(shí)沒有辦法執(zhí)行基本的重命名。
renames(old, new)
遞歸重命名目錄或文件函數(shù)。類似于rename()的工作,除了所有中間層目錄的創(chuàng)建第一次試圖需要有效的新的路徑名。重命名后,目錄符合老的名稱最右邊路徑部分將被用removedirs()刪除。1.5.2版本中的新方法。
注意:如果你缺乏需要?jiǎng)h除子目錄或文件的權(quán)限,使用新的目錄結(jié)構(gòu)重命名時(shí)這個(gè)函數(shù)會(huì)失敗。
readlink(path)
返回一個(gè)代表符號(hào)連接點(diǎn)指向的路徑的字符串。結(jié)果可以是絕對(duì)或相對(duì)路徑名的其中之一;如果是相對(duì),它可以用os.path.join(os.path.dirname(path), result)轉(zhuǎn)換成一個(gè)絕對(duì)路徑?捎茫篗acintosh, Unix。
stat(path)
在給定的路徑上執(zhí)行stat()系統(tǒng)調(diào)用。返回值是一個(gè)對(duì)象,它的屬性對(duì)應(yīng)stat的結(jié)構(gòu)數(shù),即:st_mode(保護(hù)塊),st_ino(索引節(jié)點(diǎn)數(shù)), st_dev(設(shè)備),st_nlink(硬連接數(shù)),st_uid(所有者的用戶ID),st_gid(所有者的組ID),st_size(文件大小,用字節(jié)),st_atime(當(dāng)前訪問的時(shí)間),st_mtime(當(dāng)前內(nèi)容修改的時(shí)間),st_ctime(平臺(tái)依賴,在Unix上當(dāng)前元數(shù)據(jù)改變的時(shí)間,在Windows上創(chuàng)建的時(shí)間):
>>> import os
>>> statinfo = os.stat('somefile.txt')
>>> statinfo
(33188, 422511L, 769L, 1, 1032, 100, 926L, 1105022698,1105022732, 1105022732)
>>> statinfo.st_size
926L
os.symlink(src,dst)
創(chuàng)建符號(hào)鏈接
tempnam([dir[, prefix]])
為創(chuàng)建一個(gè)臨時(shí)文件合理的返回一個(gè)唯一的路徑名。這將是一個(gè)絕對(duì)路徑路徑,以dir目錄中可能的目錄項(xiàng)命名,或是一個(gè)通常的臨時(shí)文件的位置,如果dir被忽略或?yàn)镹one。如果給定和不為None,prefix被用來給文件名提供一個(gè)簡(jiǎn)短的前綴。應(yīng)用負(fù)責(zé)使用由tempnam()返回的路徑恰當(dāng)?shù)貏?chuàng)建和管理文件;不提供自動(dòng)清除。在Unix上,環(huán)境變量TMPDIR覆蓋dir,在Windows上TMP被使用。這個(gè)函數(shù)的指定行為依賴于C庫的執(zhí)行;some aspects are underspecified in system documentation.注意:tempnam()的用法是危險(xiǎn)的對(duì)于符號(hào)連接攻擊;考慮用tmpfile()(14.1.2節(jié))替代?捎茫 Macintosh, Unix, Windows。
tmpnam()
為創(chuàng)建一個(gè)臨時(shí)文件合理的返回一個(gè)唯一的路徑名。這將是一個(gè)絕對(duì)路徑路徑,以一個(gè)通常的臨時(shí)文件的位置中可能的目錄項(xiàng)命名,應(yīng)用負(fù)責(zé)使用由tempnam ()返回的路徑恰當(dāng)?shù)貏?chuàng)建和管理文件;不提供自動(dòng)清除。注意:tempnam()的用法是危險(xiǎn)的對(duì)于符號(hào)連接攻擊;考慮用tmpfile() (14.1.2節(jié))替代?捎茫篗acintosh, Unix, Windows。這個(gè)函數(shù)大概在Windows上不被使用,不過:微軟tmpnam()的實(shí)現(xiàn)一直創(chuàng)建在當(dāng)前驅(qū)動(dòng)的根目錄中創(chuàng)建一個(gè)名字,它通常是一個(gè)臨時(shí)文件粗略的位置(依賴于特權(quán),你甚至用這個(gè)名稱不能打開一個(gè)文件)。
TMP_MAX
再使用這些名稱之前tmpnam()將生成的唯一的名稱的最大數(shù)目。
unlink(path)
刪除文件path。同remove()相同;unlink()名稱是它的傳統(tǒng)的Unix名稱?捎茫篗acintosh, Unix, Windows。
utime(path, times)
設(shè)置由path指定的文件的訪問和date.html' target='_blank'>修改時(shí)間。如果times是None,那么文件的訪問和修改時(shí)間被設(shè)置為當(dāng)前的時(shí)間。否則,times必須是一個(gè)二元組數(shù),它的被用來設(shè)置訪問和修改時(shí)間的格式分別是(atime, mtime)。目錄能否由path指定依賴于操作系統(tǒng)是否作為一個(gè)文件執(zhí)行目錄(如,Windows就不是)。注意你這兒設(shè)置的精確的時(shí)間不能通過后來的 stat()調(diào)用返回,依賴于正式的你的操作系統(tǒng)紀(jì)錄的訪問和修改時(shí)間;參見stat()。2.0版本中的改變:增加times為None的支持。可用: Macintosh, Unix, Windows。
walk(top[, topdown=True [, onerror=None]]),它os.listdir()明顯的區(qū)別就是,它能進(jìn)行縱深遍歷,os.listdir()只能遍歷當(dāng)前目錄里的所有子目錄和文件。
在目錄樹中walk()生成文件名,通過由上而下或右下而上遍歷樹。這個(gè)樹中每個(gè)目錄的根在目錄top(包含top自身),它給出一個(gè)三元組(dirpath, dirnames, filenames)。
dirpath 是一個(gè)目錄的路徑字符串。dirnames是一個(gè)dirpath的子目錄的名稱的列表(排除'.'和'..')。filenames是一個(gè)dirpath 中沒有目錄的文件的名稱的列表。注意列表中的名稱包含無路徑的組件。獲取dirpath中文件和目錄的完整路徑(以top開始),用 os.path.join(dirpath, name)。
如果可選參數(shù)topdown為true或沒有指定,它的子目錄三倍生成之前三倍的目錄被生成(目錄的生成從上而下)。如果topdown為false,三倍的目錄被生成在它的子目錄三倍生成之后(目錄生成由下而上)。
當(dāng)topdown 為true,調(diào)用者能修改dirnames列表的原狀(可能用del或slice任務(wù)),walk()僅將遞歸名稱仍然在dirnames中的子目錄;這能被用來刪除查找,利用指定的順序訪問,或者重新walk()之前告訴walk()關(guān)于調(diào)用者創(chuàng)建或重命名的目錄。當(dāng)topdown為false時(shí)修改 dirnames是無效的,因?yàn)樵谧缘紫蛏系哪J街衐irnames中的目錄在dirpath生成之前被生成。
os.listdir()調(diào)用缺省的錯(cuò)誤被忽略。如果可選參數(shù)onerror被指定,它應(yīng)該是一個(gè)函數(shù);它將被調(diào)用用一個(gè)參數(shù),一個(gè)OSError實(shí)例。它能用walk繼續(xù)報(bào)告錯(cuò)誤,或忽略walk掛起異常。注意文件名是可用的作為異常對(duì)象的文件名屬性。
注意:如果你傳遞一個(gè)相對(duì)的路徑名,在重新開始和walk()之間不改變當(dāng)前的工作目錄。walk()從不改變當(dāng)前的目錄,并且假定它的調(diào)用者也不改變。
注意:在支持符號(hào)連接的系統(tǒng)上,連接到出現(xiàn)在dirnames列表中的子目錄,但是walk()將不訪問它們(當(dāng)跟隨符號(hào)連接時(shí)避免無窮大的循環(huán)是困難的)。訪問連接的目錄,你能用os.path.islink(path)來識(shí)別它們,并且各自直接調(diào)用walk(path)。
這個(gè)例子顯示開始目錄下的每個(gè)目錄中非目錄的文件的字節(jié)數(shù),除了不查找任意CVS子目錄下的:
import os
from os.path import join, getsize
for root, dirs, files in os.walk('python/Lib/email'):
print root, "consumes",
print sum(getsize(join(root, name)) for name in files),
print "bytes in", len(files), "non-directory files"
if 'CVS' in dirs:
dirs.remove('CVS') # don't visit CVS directories
下面的例子中,從下到上遍歷樹等于:rmdir()目錄為空之前不允許刪除目錄:
# Delete everything reachable from the directory named in 'top',
# assuming there are no symbolic links.
# CAUTION: This is dangerous! For example, if top == '/', it
# could delete all your disk files.
import os
for root, dirs, files in os.walk(top, topdown=False):
for name in files:
os.remove(os.path.join(root, name))
for name in dirs:
os.rmdir(os.path.join(root, name))
New in version 2.3.
shutil.rmtree(path[,ignore_errors[,onerror]])
刪除文件夾
介紹了這么多,其實(shí)只要查一下os和shutil兩個(gè)模塊的文檔就有了,呵呵。。真正編寫shell腳本的時(shí)候還需要注意:
1.環(huán)境變量。python的環(huán)境變量保存在os.environ這個(gè)字典里,可以用普通字典的方法修改它,使用system啟動(dòng)其它程序的時(shí)候會(huì)自動(dòng)被繼承。比如:
os.environ[”fish”]=”nothing”
不過也要注意,環(huán)境變量的值只能是字符串。和shell有些不同的是,python沒有export環(huán)境變量這個(gè)概念。為什么沒有呢?因?yàn)閜ython沒有必要有
2.os.path這個(gè)模塊里包含了很多關(guān)于路徑名處理的函數(shù)。在shell里路徑名處理好像不是很重要,但是在python里經(jīng)常需要用到。最常用的兩個(gè)是分離和合并目錄名和文件名:
os.path.split(path) -> (dirname,basename)
這個(gè)函數(shù)會(huì)把一個(gè)路徑分離為兩部分,比如:os.path.split(”/foo/bar.dat”)會(huì)返回(”/foo”,”bar.dat”)
os.path.join(dirname,basename)
這個(gè)函數(shù)會(huì)把目錄名和文件名組合成一個(gè)完整的路徑名,比如:os.path.join(”/foo”,”bar.dat”)會(huì)返回”/foo /bar.dat”。這個(gè)函數(shù)和os.path.split()剛好相反。
還有這些函數(shù):
os.path.commonprefix(list)
返回list中,所有path共有的最長(zhǎng)的路徑。
如:
>>> os.path.commonprefix(['/home/td','/home/td/ff','/home/td/fff'])
'/home/td'
os.path.lexists(path)
與os.path.exists(path)的不同是如果有損壞的鏈接會(huì)返回True
os.path.basename('/foo/bar.dat')
>>>bar.dat
os.path.dirname('/foo/bar.dat')
>>>/foo
os.path.realpath(path)
返回path的真實(shí)路徑,去除符號(hào)鏈接
os.path.relpath(path[, start])
返回一個(gè)“相關(guān)路徑”,當(dāng)前目錄或者可選的start
Return a relative filepath to path either from the current directory or from an optional start point.
如:
>>> os.path.relpath('/home/jimin','/usr/lib/')
'http://www.cnblogs.com/home/jimin'
os.path.samefile(path1, path2)
如果path1與path2是相同的文件或目錄,返回真
os.path.sameopenfile(fp1, fp2)
如果fp1和fp2指向的是同一個(gè)文件,返回True
os.path.samestat(stat1, stat2)
如果 stat tuple stat1和stat2指向同一個(gè)文件,返回真。stat tuple結(jié)構(gòu)是由fstat()、lstat()、stat()產(chǎn)生的
os.path.abspath(path)
把path轉(zhuǎn)成絕對(duì)路徑,相當(dāng)于normpath(join(os.getcwd(), path))
os.path.expanduser(path)
把path中包含的”~”和”~user”轉(zhuǎn)換成用戶目錄
os.path.expandvars(path)
接受環(huán)境變理的擴(kuò)展,path中可以使用環(huán)境變量
如:
>>> os.path.expandvars('$PATH')
'/usr/lib64/qt-3.3/bin:/usr/kerberos/bin:/usr/lib64/ccache:/usr/local/bin:/usr/bin:/bin:/usr/local
/sbin:/usr/sbin:/sbin:/home/jimin/bin'
>>> os.path.expandvars('$HOME')
'/home/jimin'
os.path.expandvars(path)
根據(jù)環(huán)境變量的值替換path中包含的”$name”和”${name}”,比如環(huán)境變量FISH=nothing,那 os.path.expandvars(”$FISH/abc”)會(huì)返回”nothing/abc”
os.path.normpath(path)
去掉path中包含的”.”和”..”
os.path.splitext(path)
把path分離成基本名和擴(kuò)展名。比如:os.path.splitext(”/foo/bar.tar.bz2″)返回(’/foo /bar.tar’, ‘.bz2′)。要注意它和os.path.split()的區(qū)別
3.在os模塊有一個(gè)很好用的函數(shù)叫os.stat()沒有介紹,因?yàn)閛s.path模塊里包含了一組和它具有同樣功能的函數(shù),但是名字更好記一點(diǎn)。
os.path.exists(path)
判斷文件或者目錄是否存在
os.path.isfile(path)
判斷path所指向的是否是一個(gè)普通文件,而不是目錄
os.path.isdir(path)
判斷path所指向的是否是一個(gè)目錄,而不是普通文件
os.path.islink(path)
判斷path所指向的是否是一個(gè)符號(hào)鏈接
os.path.ismount(path)
判斷path所指向的是否是一個(gè)掛接點(diǎn)(mount point)
os.path.getatime(path)
返回path所指向的文件或者目錄的最后存取時(shí)間。
os.path.getmtime(path)
返回path所指向的文件或者目錄的最后修改時(shí)間
os.path.getctime(path)
返回path所指向的文件的創(chuàng)建時(shí)間
os.path.getsize(path)
返回path所指向的文件的大小
4.應(yīng)用python編寫shell腳本經(jīng)常要用到os,shutil,glob(正則表達(dá)式的文件名),tempfile(臨時(shí)文 件),pwd(操作/etc/passwd文件),grp(操作/etc/group文件),commands(取得一個(gè)命令的輸出)。前面兩個(gè)已經(jīng)基本 上介紹完了,后面幾個(gè)很簡(jiǎn)單,看一下文檔就可以了。
5.sys.argv是一個(gè)列表,保存了python程序的命令行參數(shù)。其中sys.argv[0]是程序本身的名字。
不能光說不練,接下來我們就編寫一個(gè)用于復(fù)制文件的簡(jiǎn)單腳本。前兩天叫我寫腳本的同事有個(gè)幾萬個(gè)文件的目錄,他想復(fù)制這些文件到其它的目錄,又不能 直接復(fù)制目錄本身。他試了一下”cp src/* dest/”結(jié)果報(bào)了一個(gè)命令行太長(zhǎng)的錯(cuò)誤,讓我?guī)退麑懸粋(gè)腳本。操起python來:
import sys,os.path,shutil
for f in os.listdir(sys.argv[1]):
shutil.copy(os.path.join(sys.argv[1],f),sys.argv[2])
再試一下linuxapp版里的帖子——把一個(gè)文件夾下的所有文件重命名成10001~10999?梢赃@樣寫:
import os.path,sys
dirname=sys.argv[1]
i=10001
for f in os.listdir(dirname):
src=os.path.join(dirname,f)
if os.path.isdir(src):
continue
os.rename(src,str(i))
i+=1http://www.linuxso.com/shell/14938.html |
|