1、執行命令列中的命令有兩種方法:在此以Linux常用的ls命令為例,
(1)os.system('ls -l')
(2)import subprocess
subprocess.call('ls -l'.split())
os.chkdir(path) 轉換到目錄path 下。
os.system('md a') 可以直接建立目錄。
os.name字串指示你正在使用的平台。比如對於Windows,它是'nt',而對於Linux/Unix使用者,它是'posix'。
● os.getcwd()函數得到當前工作目錄,即當前Python指令碼工作的目錄路徑。
● os.getenv()和os.putenv()函數分別用來讀取和設定環境變數。
● os.listdir()返回指定目錄下的所有檔案和目錄名。
● os.remove()函數用來刪除一個檔案。
● os.system()函數用來運行shell命令。
● os.linesep字串給出當前平台使用的行終止符。例如,Windows使用'\r\n',Linux使用'\n'而Mac使用'\r'。
● os.path.split()函數返回一個路徑的目錄名和檔案名稱。
>>> os.path.split('/home/swaroop/byte/code/poem.txt')
('/home/swaroop/byte/code', 'poem.txt')
● os.path.isfile()和os.path.isdir()函數分別檢驗給出的路徑是一個檔案還是目錄。類似地,os.path.exists()函數用來檢驗給出的路徑是否真地存在。
檔案重新導向
已有PY檔案new1.py ,在命令列下輸入:new1>new.txt 可以將new1啟動並執行結果輸出到檔案new.txt,這稱為流重新導向。
python可以做shell指令碼嗎? 首先介紹一個函數:
os.system(command)
這個函數可以調用shell運行命令列command並且返回它的傳回值。試一下在python的解譯器裡輸入os.system(”ls -l”),就可以看到”ls”列出了目前的目錄下的檔案。可以說,通過這個函數,python就擁有了shell的所有能力。呵呵。。不過,通常這條命令不 需要用到。因為shell常用的那些命令在python中通常有對應而且同樣簡潔的寫法。
shell中最常用的是ls命令,python對應的寫法是:os.listdir(dirname),這個函數返回字串列表,裡面是所有的檔案名稱,不過不包含”.”和”..”。如果要遍曆整個目錄的話就會比較複雜一點。我們等下再說吧。先在解譯器裡試一下:
>>> 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的解譯器裡直接運行觀看結果。
對應於cp命令的是:shutil.copy(src,dest),這個函數有兩個參數,參數src是指源檔案的名字,參數dest則是目標檔案或 者目標目錄的名字。 如果dest是一個目錄名,就會在那個目錄下建立一個相同名字的檔案。與shutil.copy函數相類似的是 shutil.copy2(src,dest),不過copy2還會複製最後存取時間和最後更新時間。
不過,shell的cp命令還可以複製目錄,python的shutil.copy卻不行,第一個參數只能是一個檔案。這怎麼辦?其 實,python還有個shutil.copytree(src,dst[,symlinks]) 。參數多了一個symlinks,它是一個布爾值,如果是True的話就建立符號連結。
移動或者重新命名檔案和目錄呢?估計被聰明的朋友猜到了,shutil.move(src,dst),呵呵。。與mv命令類似,如果src和dst在 同一個檔案系統上,shutil.move只是簡單改一下名字,如果src和dst在不同的檔案系統上,shutil.move會先把src複製到 dst,然後刪除src檔案。看到現在,大多數朋友應該已經對python的能力有點眉目了,接下來我就列個表,介紹一下其它的函數:
os.chdir(dirname)
把當前工作目錄切換到dirname下
os.getcwd()
返回當前的工作目錄路徑
os.chroot(dirname)
把dirname作為進程的根目錄。和*nix下的chroot命令類似
os.chmod(path,mode)
更改path的許可權位。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
具體它們是什麼含義,就不仔細說了,基本上就是R代表讀,W代表寫,X代表執行許可權。USR代表使用者,GRP代表組,OTH代表其它。
os.chown(path,uid,gid)
改變檔案的屬主。uid和gid為-1的時候不改變原來的屬主。
os.link(src,dst)
建立硬串連
os.mkdir(path,[mode])
建立目錄。mode的意義參見os.chmod(),預設是0777
os.makedirs(path,[mode])
和os.mkdir()類似,不過會先建立不存在的父目錄。
os.readlink(path)
返回path這個符號連結所指向的路徑
os.remove(path)
刪除檔案,不能用於刪除目錄
os.rmdir(path)
刪除檔案夾,不能用於刪除檔案
removedirs(path)
遞迴移除目錄。類似於rmdir()的工作,除了如果子目錄被成功地刪除,removedirs()嘗試接連地刪除每個在path中提及的父目錄,直到一個錯誤被掛起(這個錯誤被忽略,因為它通常意味父目錄不為空白。)例如,"os.removedirs(‘foo/bar/baz')"將首先刪除"'foo/bar/baz'"目錄,然後如果 "'foo/bar'"和"'foo'"為空白刪除它們。如果子目錄不能被成功地刪除掛起OSError。1.5.2版本中的新方法。
rename(src, dst)
重新命名檔案或目錄src為dst。如果dst是一個目錄,OSError將被掛起。在Unix上,如果dst存在並且是一個檔案,如果使用者有許可權它將被默默地刪除。在一些Unix風格的系統上如果src和dst是不同的檔案系統,這個操作可能失敗。如果成功,重新命名將是一個基本的操作(這是一個POSIX要求)。在Windows上,如果dst已經存在,甚至如果它是一個檔案,OSError將被掛起;當dst命名一個已存在的檔案時沒有辦法執行基本的重新命名。
renames(old, new)
遞迴重新命名目錄或檔案函數。類似於rename()的工作,除了所有中介層目錄的建立第一次試圖需要有效新的路徑名。重新命名後,目錄符合老的名稱最右邊路徑部分將被用removedirs()刪除。1.5.2版本中的新方法。
注意:如果你缺乏需要刪除子目錄或檔案的許可權,使用新的目錄結構重新命名時這個函數會失敗。
readlink(path)
返回一個代表符號連接點指向的路徑的字串。結果可以是絕對或相對路徑名的其中之一;如果是相對,它可以用os.path.join(os.path.dirname(path), result)轉換成一個絕對路徑。可用:Macintosh, Unix。
stat(path)
在給定的路徑上執行stat()系統調用。傳回值是一個對象,它的屬性對應stat的結構數,即:st_mode(保護塊),st_ino(索引節點數), st_dev(裝置),st_nlink(硬串連數),st_uid(所有者的使用者ID),st_gid(所有者的組ID),st_size(檔案大小,用位元組),st_atime(當前訪問的時間),st_mtime(當前內容修改的時間),st_ctime(平台依賴,在Unix上當前中繼資料改變的時間,在Windows上建立的時間):
>>> 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)
建立符號連結
tempnam([dir[, prefix]])
為建立一個臨時檔案合理的返回一個唯一的路徑名。這將是一個絕對路徑路徑,以dir目錄中可能的目錄項命名,或是一個通常的臨時檔案的位置,如果dir被忽略或為None。如果給定和不為None,prefix被用來給檔案名稱提供一個簡短的首碼。應用負責使用由tempnam()返回的路徑恰當地建立和管理檔案;不提供自動清除。在Unix上,環境變數TMPDIR覆蓋dir,在Windows上TMP被使用。這個函數的指定行為依賴於C庫的執行;some aspects are underspecified in system documentation.注意:tempnam()的用法是危險的對於符號串連攻擊;考慮用tmpfile()(14.1.2節)替代。可用:
Macintosh, Unix, Windows。
tmpnam()
為建立一個臨時檔案合理的返回一個唯一的路徑名。這將是一個絕對路徑路徑,以一個通常的臨時檔案的位置中可能的目錄項命名,應用負責使用由tempnam ()返回的路徑恰當地建立和管理檔案;不提供自動清除。注意:tempnam()的用法是危險的對於符號串連攻擊;考慮用tmpfile() (14.1.2節)替代。可用:Macintosh, Unix, Windows。這個函數大概在Windows上不被使用,不過:微軟tmpnam()的實現一直建立在當前驅動的根目錄中建立一個名字,它通常是一個臨時檔案粗略的位置(依賴於特權,你甚至用這個名稱不能開啟一個檔案)。
TMP_MAX
再使用這些名稱之前tmpnam()將產生的唯一的名稱的最大數目。
unlink(path)
刪除檔案path。同remove()相同;unlink()名稱是它的傳統的Unix名稱。可用:Macintosh, Unix, Windows。
utime(path, times)
設定由path指定的檔案的訪問和修改時間。如果times是None,那麼檔案的訪問和修改時間被設定為當前的時間。否則,times必須是一個二元組數,它的被用來設定訪問和修改時間的格式分別是(atime, mtime)。目錄能否由path指定依賴於作業系統是否作為一個檔案執行目錄(如,Windows就不是)。注意你這兒設定的精確的時間不能通過後來的 stat()調用返回,依賴於正式的你的作業系統紀錄的訪問和修改時間;參見stat()。2.0版本中的改變:增加times為None的支援。可用: Macintosh,
Unix, Windows。
walk(top[, topdown=True [, onerror=None]]),它os.listdir()明顯的區別就是,它能進行縱深遍曆,os.listdir()只能遍曆目前的目錄裡的所有子目錄和檔案。
在分類樹中walk()組建檔案名,通過由上而下或右下而上遍曆樹。這個樹中每個目錄的根在目錄top(包含top自身),它給出一個三元組(dirpath, dirnames, filenames)。
dirpath 是一個目錄的路徑字串。dirnames是一個dirpath的子目錄的名稱的列表(排除'.'和'..')。filenames是一個dirpath 中沒有目錄的檔案的名稱的列表。注意列表中的名稱包含無路徑的組件。擷取dirpath中檔案和目錄的完整路徑(以top開始),用 os.path.join(dirpath, name)。
如果選擇性參數topdown為true或沒有指定,它的子目錄三倍產生之前三倍的目錄被產生(目錄的產生從上而下)。如果topdown為false,三倍的目錄被產生在它的子目錄三倍產生之後(目錄產生由下而上)。
當topdown 為true,調用者能修改dirnames列表的原狀(可能用del或slice任務),walk()僅將遞迴名稱仍然在dirnames中的子目錄;這能被用來刪除尋找,利用指定的順序訪問,或者重新walk()之前告訴walk()關於調用者建立或重新命名的目錄。當topdown為false時修改 dirnames是無效的,因為在自底向上的模式中dirnames中的目錄在dirpath產生之前被產生。
os.listdir()調用預設的錯誤被忽略。如果選擇性參數onerror被指定,它應該是一個函數;它將被調用用一個參數,一個OSError執行個體。它能用walk繼續報告錯誤,或忽略walk掛起異常。注意檔案名稱是可用的作為異常對象的檔案名稱屬性。
注意:如果你傳遞一個相對的路徑名,在重新開始和walk()之間不改變當前的工作目錄。walk()從不改變當前的目錄,並且假定它的調用者也不改變。
注意:在支援符號串連的系統上,串連到出現在dirnames列表中的子目錄,但是walk()將不訪問它們(當跟隨符號串連時避免無窮大的迴圈是困難的)。訪問串連的目錄,你能用os.path.islink(path)來識別它們,並且各自直接調用walk(path)。
這個例子顯示開始目錄下的每個目錄中非目錄的檔案的位元組數,除了不尋找任意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]])
刪除檔案夾
介紹了這麼多,其實只要查一下os和shutil兩個模組的文檔就有了,呵呵。。真正編寫shell指令碼的時候還需要注意:
1.環境變數。python的環境變數儲存在os.environ這個字典裡,可以用普通字典的方法修改它,使用system啟動其它程式的時候會自動被繼承。比如:
os.environ[”fish”]=”nothing”
不過也要注意,環境變數的值只能是字串。和shell有些不同的是,python沒有export環境變數這個概念。為什麼沒有呢?因為python沒有必要有:-)
2.os.path這個模組裡包含了很多關於路徑名處理的函數。在shell裡路徑名處理好像不是很重要,但是在python裡經常需要用到。最常用的兩個是分離和合并目錄名和檔案名稱:
os.path.split(path) -> (dirname,basename)
這個函數會把一個路徑分離為兩部分,比如:os.path.split(”/foo/bar.dat”)會返回(”/foo”,”bar.dat”)
os.path.join(dirname,basename)
這個函數會把目錄名和檔案名稱組合成一個完整的路徑名,比如:os.path.join(”/foo”,”bar.dat”)會返回”/foo /bar.dat”。這個函數和os.path.split()剛好相反。
還有這些函數:
os.path.commonprefix(list)
返回list中,所有path共有的最長的路徑。
如:
>>> os.path.commonprefix(['/home/td','/home/td/ff','/home/td/fff'])
'/home/td'
os.path.lexists(path)
與os.path.exists(path)的不同是如果有損壞的連結會返回True
os.path.basename('/foo/bar.dat')
>>>bar.dat
os.path.dirname('/foo/bar.dat')
>>>/foo
os.path.realpath(path)
返回path的真實路徑,去除符號連結
os.path.relpath(path[, start])
返回一個“相關路徑”,目前的目錄或者可選的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指向的是同一個檔案,返回True
os.path.samestat(stat1, stat2)
如果 stat tuple stat1和stat2指向同一個檔案,返回真。stat tuple結構是由fstat()、lstat()、stat()產生的
os.path.abspath(path)
把path轉成絕對路徑,相當於normpath(join(os.getcwd(), path))
os.path.expanduser(path)
把path中包含的”~”和”~user”轉換成使用者目錄
os.path.expandvars(path)
接受環境變理的擴充,path中可以使用環境變數
如:
>>> 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)
根據環境變數的值替換path中包含的”$name”和”${name}”,比如環境變數FISH=nothing,那 os.path.expandvars(”$FISH/abc”)會返回”nothing/abc”
os.path.normpath(path)
去掉path中包含的”.”和”..”
os.path.splitext(path)
把path分離成基本名和副檔名。比如:os.path.splitext(”/foo/bar.tar.bz2″)返回(’/foo /bar.tar’, ‘.bz2′)。要注意它和os.path.split()的區別
3.在os模組有一個很好用的函數叫os.stat()沒有介紹,因為os.path模組裡包含了一組和它具有同樣功能的函數,但是名字更好記一點。
os.path.exists(path)
判斷檔案或者目錄是否存在
os.path.isfile(path)
判斷path所指向的是否是一個普通檔案,而不是目錄
os.path.isdir(path)
判斷path所指向的是否是一個目錄,而不是普通檔案
os.path.islink(path)
判斷path所指向的是否是一個符號連結
os.path.ismount(path)
判斷path所指向的是否是一個掛接點(mount point)
os.path.getatime(path)
返回path所指向的檔案或者目錄的最後存取時間。
os.path.getmtime(path)
返回path所指向的檔案或者目錄的最後修改時間
os.path.getctime(path)
返回path所指向的檔案的建立時間
os.path.getsize(path)
返回path所指向的檔案的大小
4.應用python編寫shell指令碼經常要用到os,shutil,glob(Regex的檔案名稱),tempfile(臨時文 件),pwd(操作/etc/passwd檔案),grp(操作/etc/group檔案),commands(取得一個命令的輸出)。前面兩個已經基本 上介紹完了,後面幾個很簡單,看一下文檔就可以了。
5.sys.argv是一個列表,儲存了python程式的命令列參數。其中sys.argv[0]是程式本身的名字。
不能光說不練,接下來我們就編寫一個用於複製檔案的簡單指令碼。前兩天叫我寫指令碼的同事有個幾萬個檔案的目錄,他想複製這些檔案到其它的目錄,又不能 直接複製目錄本身。他試了一下”cp src/* dest/”結果報了一個命令列太長的錯誤,讓我幫他寫一個指令碼。操起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版裡的文章——把一個檔案夾下的所有檔案重新命名成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+=1