I am trying to understand what is the motivation behind using Python\'s library functions for executing OS-specific tasks such as creating files/directories, changing file attri
There are four strong cases for preferring Python's more-specific methods in the os module over using os.system or the subprocess module when executing a command:
os
module are available in multiple platforms while many shell commands are os-specific.os
module.You're actually executing a redundant "middle-man" on your way to the eventual system calls (chmod
in your example). This middle man is a new process or sub-shell.
From os.system:
Execute the command (a string) in a subshell ...
And subprocess is just a module to spawn new processes.
You can do what you need without spawning these processes.
The os module's aim is to provide generic operating-system services and it's description starts with:
This module provides a portable way of using operating system dependent functionality.
You can use os.listdir on both windows and unix. Trying to use os.system
/ subprocess
for this functionality will force you to maintain two calls (for ls
/ dir
) and check what operating system you're on. This is not as portable and will cause even more frustration later on (see Handling Output).
Suppose you want to list the files in a directory.
If you're using os.system("ls")
/ subprocess.call(['ls'])
, you can only get the process's output back, which is basically a big string with the file names.
How can you tell a file with a space in it's name from two files?
What if you have no permission to list the files?
How should you map the data to python objects?
These are only off the top of my head, and while there are solutions to these problems - why solve again a problem that was solved for you?
This is an example of following the Don't Repeat Yourself principle (Often reffered to as "DRY") by not repeating an implementation that already exists and is freely available for you.
os.system
and subprocess
are powerful. It's good when you need this power, but it's dangerous when you don't. When you use os.listdir
, you know it can not do anything else other then list files or raise an error. When you use os.system
or subprocess
to achieve the same behaviour you can potentially end up doing something you did not mean to do.
Injection Safety (see shell injection examples):
If you use input from the user as a new command you've basically given him a shell. This is much like SQL injection providing a shell in the DB for the user.
An example would be a command of the form:
# ... read some user input
os.system(user_input + " some continutation")
This can be easily exploited to run any arbitrary code using the input: NASTY COMMAND;#
to create the eventual:
os.system("NASTY COMMAND; # some continuation")
There are many such commands that can put your system at risk.