0

I am using the subprocess module to create some directories. However in some cases the same command might be creating directories in restricted directories. In such cases I get an output to the console: mkdir: cannot create directory 'location/to/directory': Permission denied

How to avoid this output to the console?

I have tried the following commands:

subprocess.run(["mkdir", "-p", f"{outdir}/archive/backup_{curr_date}/"],check=True,stdout=subprocess.DEVNULL)
subprocess.run(["mkdir", "-p", f"{outdir}/archive/backup_{curr_date}/"],check=True,stdout=subprocess.PIPE)
subprocess.run(["mkdir", "-p", f"{outdir}/archive/backup_{curr_date}/"],check=True,capture_output=True)
Vandit Goel
  • 620
  • 2
  • 9
  • 19
  • 3
    Why do you run subprocess to create a directory? Use [`os.mkdir`](https://docs.python.org/3/library/os.html#os.mkdir) for that. – zvone Jan 08 '23 at 14:40
  • 1
    As the output is an error it probably goes through stderr instead of stdout. – Michael Butscher Jan 08 '23 at 14:42
  • The stderr is None. And this does not raise an exception for some reason. – Vandit Goel Jan 08 '23 at 14:48
  • @zvone Not using `os.mkdir()` because I want to create intermediate directories. So the other option was to use `makedirs()` but then it raise `FileExistsError` but I want to capture the actual reason which was Permission Denied. – Vandit Goel Jan 08 '23 at 14:53
  • `os.makedirs` had a flag to not fail if it already exists. – zvone Jan 08 '23 at 15:52

1 Answers1

1

Better Approach

os.mkdirs is much better way to create a new directory.

Which can be used this way:

try:
    os.makedirs(f"{outdir}/archive/backup_{curr_date}/", exist_ok=True)
except PermissionError as e:
    print(e)

It will create a outdir as well if it doesn't exist.


Fix

mkdir: cannot create directory 'location/to/directory'

This is not standard output rather its error which gets printed on console. First of all, this error shouldn't be suppressed and handled properly. But in extreme case, if that's the required outcome then you should PIPE the stderr like this stderr=subprocess.PIPE

subprocess.run(["mkdir", "-p", f"{outdir}/archive/backup_{curr_date}/"], stderr=subprocess.PIPE)

A working example:

import subprocess

dir_path = "/usr/abc"

result = subprocess.run(["mkdir", "-p", dir_path], stderr=subprocess.PIPE)
error = result.stderr.decode()

if error:
    print(error)
# Output: mkdir: /usr/abc: Operation not permitted
Zaid Afzal
  • 362
  • 2
  • 7
  • I am actually working on a command line application using click. So in case I am creating a directory in a restricted location I want to Log the `mkdir: cannot create directory 'location/to/directory': Permission denied` error. Even if I do `subprocess.DEVNULL` to both stderr and stdout it still gets printed to the terminal. I don't understand why. – Vandit Goel Jan 08 '23 at 15:06
  • My only problem with `makedirs()` is it does not raise the right error in case of creating a directory in a restricted location. – Vandit Goel Jan 08 '23 at 15:08
  • 2
    os.makedirs() throws PermissionError as well if it tries to create a directory which process user doesn't have write access to. [Errno 1] Operation not permitted: {dir_name_here} – Zaid Afzal Jan 08 '23 at 15:13
  • See [this answer](https://stackoverflow.com/a/5032238/12299000). – kaya3 Jan 08 '23 at 15:14
  • @VanditGoel I have update my answer. Even with subprocess, you can capture the actual error in code instead of directly printing on console. Using subprocess.PIPE – Zaid Afzal Jan 08 '23 at 15:27