Pythonで学ぶ「詳解 UNIXプログラミング」(その4) 第4章 ファイルとディレクトリ
4.1 指定したファイルの種類を出力する
import sys, os, stat for filename in sys.argv[1:]: print "{0}:".format(filename), try: st = os.lstat(filename) except Exception, e: sys.exit("lstat error") mode = st[stat.ST_MODE] if stat.S_ISREG(mode): print "regular" elif stat.S_ISDIR(mode): print "directory" elif stat.S_ISCHR(mode): print "character special" elif stat.S_ISLNK(mode): print "symbolic link" elif stat.S_ISSOCK(mode): print "socket" else: print "** unknown mode **"
stat()
関数はos
モジュールで定義されているが、stat
構造体から値を読み取るための関数はstat
モジュールに定義されている。
4.2 ファイルにアクセス可能かチェックする
import sys, os if len(sys.argv) != 2: sys.exit("usage: python scr4.2.py filename") if os.access(sys.argv[1], os.R_OK): print "read access OK" else: sys.exit("access error for {0}".format(sys.argv[1])) try: open(sys.argv[0]) except Exception: sys.exit("open error for {0}".format(sys.argv[1])) print "open for reading OK"
4.3 umask関数の使用例
import os, stat open("spam", "w") os.umask(stat.S_IRGRP | stat.S_IWGRP | stat.S_IROTH | stat.S_IWOTH) open("ham", "w")
作成されたファイル spam
とham
は異なるパーミッションとなる。
4.4 chmod関数の使用例
import sys, os, stat if len(sys.argv) != 2: sys.exit("usage: python scr4.4.py filename") # turn on set-group-ID and turn off group-execute st = os.stat(sys.argv[1]) os.chmod(sys.argv[1], (st.st_mode & ~stat.S_IXGRP) | stat.S_ISGID)
stat構造体は、st.st_mode
のように属性値としてメンバにアクセスすることもできる。
4.5 ファイルをオープンし、アンリンクする
import os, time f = open("spam", "w") os.unlink("spam") print "file unlinked" time.sleep(15) print "done"
4.6 utime()関数の例
import sys, os for filename in sys.argv[1:]: st = os.stat(filename) open(filename, "w") os.utime(filename, (st.st_atime, st.st_mtime))
4.7 ファイルの種類を数えながら、再帰的にディレクトリ構造を辿る
import sys, os, stat if len(sys.argv) != 2: sys.exit("usage: python scr4.7.py <starting-pathname>") total = nreg = ndir = nblk = nchr = nfifo = nslink = nsock = 0 def calc(root, fname): global total, nreg, ndir, nblk, nchr, nfifo, nslink, nsock st = os.lstat(os.path.join(root, fname)) mode = stat.S_IFMT(st.st_mode) if mode == stat.S_IFREG: nreg += 1 elif mode == stat.S_IFBLK: nblk += 1 elif mode == stat.S_IFCHR: nchr += 1 elif mode == stat.S_IFIFO: nfifo += 1 elif mode == stat.S_IFLNK: nslink += 1 elif mode == stat.S_IFSOCK: nsock += 1 elif mode == stat.S_IFDIR: ndir += 1 for root, dirs, files in os.walk(sys.argv[1]): total += len(dirs) + len(files) for d in dirs: calc(root, d) for f in files: calc(root, f) print total print "regular file:", nreg, nreg*100.0/total print "directories:", ndir, ndir*100.0/total print "block special:", nblk, nblk*100.0/total print "char special:", nchr, nchr*100.0/total print "FIFOs:", nfifo, nfifo*100.0/total print "symbolic links:", nslink, nslink*100.0/total print "sockets:", nsock, nsock*100.0/total
Pythonで再帰的にディレクトリ構造を辿る時は、os.walk()
を使用する。ディレクトリにファイルがないとZeroDivisionError
が発生してしまうが、大目に見ていただきたい。
4.8 chdir()の例
import os os.chdir("/tmp") print "chdir to /tmp succeeded."
4.9 getcwd()の例
import os os.chdir("/tmp") print "cwd =", os.getcwd()
4.10 st_devとst_rdevを出力する
import os, sys, stat for filename in sys.argv[1:]: st = os.lstat(filename) print "dev = {0}/{1}".format(os.major(st.st_dev), os.minor(st.st_dev)) if stat.S_ISCHR(st.st_mode) or stat.S_ISBLK(st.st_mode): print " ({0}) rdev = {1}/{2}".format( "character" if stat.S_ISCHR(st.st_mode) else "block", os.major(st.st_rdev), os.minor(st.st_rdev))