The os
module provides a unified interface to many operating
system functions.
Most of the functions in this module are implemented by platform-specific modules, such as posix
or nt
. The os
module automatically loads the right implementation module when it
is first imported.
The built-in open
function lets you create, open,
and modify files, as shown in Example 1-27. This module adds those extra functions you need to
rename and remove files.
Example 1-27. Using the os Module to Rename and Remove Files
File: os-example-3.py import os import string def replace(file, search_for, replace_with): # replace strings in a text file back = os.path.splitext(file)[0] + ".bak" temp = os.path.splitext(file)[0] + ".tmp" try: # remove old temp file, if any os.remove(temp) except os.error: pass fi = open(file) fo = open(temp, "w") for s in fi.readlines(): fo.write(string.replace(s, search_for, replace_with)) fi.close() fo.close() try: # remove old backup file, if any os.remove(back) except os.error: pass # rename original to backup... os.rename(file, back) # ...and temporary to original os.rename(temp, file) # # try it out! file = "samples/sample.txt" replace(file, "hello", "tjena") replace(file, "tjena", "hello")
The os
module also contains many functions that work on entire
directories.
The listdir
function returns a list of all
filenames in a given directory, as shown in Example 1-28. The current and parent directory
markers used on Unix and Windows (.
and
..
) are not included in this list.
The getcwd
and chdir
functions are used to get and set the current directory, as shown in Example 1-29.
The makedirs
and removedirs
functions are used to create and remove directory hierarchies, as shown in Example 1-30.
Note that removedirs
removes all empty
directories along the given path, starting with the last directory in
the given pathname. In contrast, the mkdir
and
rmdir
functions can only handle a single
directory level, as shown in Example 1-31.
To remove non-empty directories, you can use the
rmtree
function in the shutil
module.
The stat
function fetches information about an
existing file, as demonstrated in Example 1-32. It returns a 9-tuple which contains the size, inode
change timestamp, modification timestamp, and access privileges.
Example 1-32. Using the os Module to Get Information About a File
File: os-example-1.py import os import time file = "samples/sample.jpg" def dump(st): mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime = st print "- size:", size, "bytes" print "- owner:", uid, gid print "- created:", time.ctime(ctime) print "- last accessed:", time.ctime(atime) print "- last modified:", time.ctime(mtime) print "- mode:", oct(mode) print "- inode/dev:", ino, dev # # get stats for a filename st = os.stat(file) print "stat", file dump(st) print # # get stats for an open file fp = open(file) st = os.fstat(fp.fileno()) print "fstat", file dump(st)stat samples/sample.jpg
- size: 4762 bytes
- owner: 0 0
- created: Tue Sep 07 22:45:58 1999
- last accessed: Sun Sep 19 00:00:00 1999
- last modified: Sun May 19 01:42:16 1996
- mode: 0100666
- inode/dev: 0 2
fstat samples/sample.jpg
- size: 4762 bytes
- owner: 0 0
- created: Tue Sep 07 22:45:58 1999
- last accessed: Sun Sep 19 00:00:00 1999
- last modified: Sun May 19 01:42:16 1996
- mode: 0100666
- inode/dev: 0 0
Some fields don’t make sense on non-Unix platforms; for example, the
(inode
, dev
) tuple provides a unique identity for each file on Unix,
but may contain arbitrary data on other platforms.
The stat
module
contains a number of useful constants and helper functions for dealing
with the members of the stat tuple. Some of these are shown in the
examples that follow.
You can modify the mode and time fields using the
chmod
and utime
functions, as shown in Example 1-33.
Example 1-33. Using the os Module to Change a File’s Privileges and Timestamps
File: os-example-2.py import os import stat, time infile = "samples/sample.jpg" outfile = "out.jpg" # copy contents fi = open(infile, "rb") fo = open(outfile, "wb") while 1: s = fi.read(10000) if not s: break fo.write(s) fi.close() fo.close() # copy mode and timestamp st = os.stat(infile) os.chmod(outfile, stat.S_IMODE(st[stat.ST_MODE])) os.utime(outfile, (st[stat.ST_ATIME], st[stat.ST_MTIME])) print "original", "=>" print "mode", oct(stat.S_IMODE(st[stat.ST_MODE])) print "atime", time.ctime(st[stat.ST_ATIME]) print "mtime", time.ctime(st[stat.ST_MTIME]) print "copy", "=>" st = os.stat(outfile) print "mode", oct(stat.S_IMODE(st[stat.ST_MODE])) print "atime", time.ctime(st[stat.ST_ATIME]) print "mtime", time.ctime(st[stat.ST_MTIME])original =>
mode 0666
atime Thu Oct 14 15:15:50 1999
mtime Mon Nov 13 15:42:36 1995
copy =>
mode 0666
atime Thu Oct 14 15:15:50 1999
mtime Mon Nov 13 15:42:36 1995
The system
function runs a new command under the
current process, and waits for it to finish, as shown in Example 1-34.
Example 1-34. Using the os Module to Run an Operating System Command
File: os-example-8.py import os if os.name == "nt": command = "dir" else: command = "ls -l" os.system(command)-rwxrw-r-- 1 effbot effbot 76 Oct 9 14:17 README
-rwxrw-r-- 1 effbot effbot 1727 Oct 7 19:00 SimpleAsyncHTTP.py
-rwxrw-r-- 1 effbot effbot 314 Oct 7 20:29 aifc-example-1.py
-rwxrw-r-- 1 effbot effbot 259 Oct 7 20:38 anydbm-example-1.py
...
The command is run via the operating system’s standard shell, and
returns the shell’s exit status. Under Windows 95/98, the shell is
usually command.com
, whose exit status is always 0.
Warning
Since os.system
passes the command on to the
shell as is, it can be dangerous to use if you don’t check the
arguments carefully (consider running os.system("viewer %s" % file)
with the file variable set to
"sample.jpg; rm -rf $HOME"
). When
unsure, it’s usually better to use exec
or
spawn
instead (explained later).
The exec
function starts a new process, replacing
the current one (“go to process,” in other words). In
Example 1-35, note that the “goodbye” message is
never printed.
Python provides a whole bunch of exec
functions,
with slightly varying behaviors. Example 1-35 uses
execvp
, which searches for the program along the
standard path, passes the contents of the second argument tuple as
individual arguments to that program, and runs it with the current set
of environment variables. See the Python Library
Reference for more information on the other seven
ways to call this function.
Under Unix, you can call other programs from the current one by
combining exec
with two other functions,
fork
and wait
, as shown in Example 1-36. The fork
function
makes a copy of the current process, and the wait
function waits for a child
process to finish.
The fork
returns zero in the new process (the
return from fork
is the first thing that happens
in that process!), and a non-zero process identifier in the original
process. Or in other words, “not pid
”
is true only if we’re in the new process.
The fork
and wait
functions are not
available on Windows, but you can use the spawn
function instead, as shown in Example 1-37. Unfortunately, there’s no standard version of
spawn
that searches for an executable along the
path, so you have to do that yourself.
Example 1-37. Using the os Module to Run Another Program (Windows)
File: os-spawn-example-1.py import os import string def run(program, *args): # find executable for path in string.split(os.environ["PATH"], os.pathsep): file = os.path.join(path, program) + ".exe" try: return os.spawnv(os.P_WAIT, file, (file,) + args) except os.error: pass raise os.error, "cannot find executable" run("python", "hello.py") print "goodbye"hello again, and welcome to the show
goodbye
You can also use spawn
to run other programs in
the background. Example 1-38 adds an optional
mode
argument to the run
function; when set to os.P_NOWAIT
, the script
doesn’t wait for the other program to finish. The default flag value os.P_WAIT
tells
spawn
to wait until the new process is finished.
Other flags include os.P_OVERLAY
, which makes
spawn
behave like exec
, and
os.P_DETACH
, which runs the new process in
the background, detached from both console and keyboard.
Example 1-38. Using the os Module to Run Another Program in the Background (Windows)
File: os-spawn-example-2.py import os import string def run(program, *args, **kw): # find executable mode = kw.get("mode", os.P_WAIT) for path in string.split(os.environ["PATH"], os.pathsep): file = os.path.join(path, program) + ".exe" try: return os.spawnv(mode, file, (file,) + args) except os.error: pass raise os.error, "cannot find executable" run("python", "hello.py", mode=os.P_NOWAIT) print "goodbye"goodbye
hello again, and welcome to the show
Example 1-39 provides a spawn
method
that works on either platform.
Example 1-39. Using Either spawn or fork/exec to Run Another Program
File: os-spawn-example-3.py import os import string if os.name in ("nt", "dos"): exefile = ".exe" else: exefile = "" def spawn(program, *args): try: # possible 2.0 shortcut! return os.spawnvp(program, (program,) + args) except AttributeError: pass try: spawnv = os.spawnv except AttributeError: # assume it's unix pid = os.fork() if not pid: os.execvp(program, (program,) + args) return os.wait()[0] else: # got spawnv but no spawnp: go look for an executable for path in string.split(os.environ["PATH"], os.pathsep): file = os.path.join(path, program) + exefile try: return spawnv(os.P_WAIT, file, (file,) + args) except os.error: pass raise IOError, "cannot find executable" # # try it out! spawn("python", "hello.py") print "goodbye"hello again, and welcome to the show
goodbye
Example 1-39 first attempts to call a function named
spawnvp
. If that doesn’t exist (it doesn’t, in
2.0 and earlier), the function looks for a function named
spawnv
and searches the path all by itself. As a
last resort, it falls back on exec
and
fork
.
On Unix, you can also use fork
to turn the
current process into a background process (a “daemon”).
Basically, you need to fork off a copy of the current
process, and terminate the original process, as shown in Example 1-40.
It takes a bit more work to create a real daemon, however.
First, call setpgrp
to make the new process a
“process group leader.” Otherwise, signals sent to a (by
that time) unrelated process group might cause problems in your
daemon:
os.setpgrp()
It’s also a good idea to remove the user mode mask, to make sure files created by the daemon actually get the mode flags specified by the program:
os.umask(0)
Then, you should redirect the stdout/stderr
files, instead of just
closing them (if you don’t do this, you may get unexpected exceptions
the day some of your code tries to write something to the console via
stdout
or stderr
).
class NullDevice: def write(self, s): pass sys.stdin.close() sys.stdout = NullDevice() sys.stderr = NullDevice()
In other words, while Python’s print
and C’s
printf/fprintf
won’t crash your program if the
devices have been disconnected, sys.stdout.write()
happily throws an IOError
exception when the
application runs as a daemon. But your program works just fine when
running in the foreground...
By the way, the _exit
function used in the previous
examples terminates the current process. In contrast to
sys.exit
, this works also if the caller happens
to catch the SystemExit
exception, as shown in Example 1-41.
Get Python Standard Library now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.