Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use os.umask() in Python

I'm trying to set a umask using the os module. Please note my normal umask set in my ~/.profile is umask 0027.

In a bash shell,

umask 0022

will allow a file to be created with permissions

-rw-r--r--

However, when us import the os module and do this:

os.umask(0022)
[do some other code here that creates a file]

I get permissions of

----------

First, how do I make os.umask(mask) behave like umask in the shell?

Second, what is the logic between the difference of the two?

Note: I tried converting the 0022 to decimal in case it is expecting a decimal by doing:

os.umask(18)

but it gave permissions of

-----w--w-

Also note, I tried

os.umask(00022)

and

os.mask(0o0022)

Which didn't work either.

like image 510
narnie Avatar asked Apr 24 '12 02:04

narnie


People also ask

What is OS umask Python?

umask() method in Python is used to set the current numeric umask value and get the previous umask value. umask stands for user file-creation mode mask. This is used to determine the file permission for newly created files or directories. Syntax: os.umask(mask)

How do I use the umask command?

The Umask Command Syntaxumask [-p] [-S] [mode] The user file-creation mask is set to mode. If mode begins with a digit, it is interpreted as an octal number; otherwise it is interpreted as a symbolic mode mask similar to that accepted by chmod(1). If mode is omitted, the current value of the mask is printed.

How do I check file permissions in Python?

os. stat is the right way to get more general info about a file, including permissions per user, group, and others. The st_mode attribute of the object that os. stat returns has the permission bits for the file.

Why is umask 0022?

umask 0022 would make the new mask 0644 (0666-0022=0644) meaning that group and others have read (no write or execute) permissions. The "extra" digit (the first number = 0), specifies that there are no special modes. If mode begins with a digit it will be interpreted as octal otherwise its meant to be symbolic.


2 Answers

Misunderstanding of umask, I think. The umask sets the default denials, not the default permissions. So

import os
oldmask = os.umask (0o022)
fh1 = os.open ("qq1.junk", os.O_CREAT, 0o777)
fh2 = os.open ("qq2.junk", os.O_CREAT, 0o022)
os.umask (oldmask)
os.close (fh1)
os.close (fh2)

should indeed produce files as follows:

-rwxr-xr-x 1 pax pax 0 Apr 24 11:11 qq1.junk
---------- 1 pax pax 0 Apr 24 11:11 qq2.junk

The umask 022 removes write access for group and others, which is exactly the behaviour we see there. I find it helps to go back to the binary that the octal numbers represent:

 usr grp others 
-rwx rwx rwx is represented in octal as 0777, requested for qq1.junk
-000 010 010 umask of 022 removes any permission where there is a 1
-rwx r-x r-x is the result achieved requesting 0777 with umask of 022

---- -w- -w- is represented in octal as 0022, requested for qq2.junk
-000 010 010 umask of 022 removes any permission where there is a 1
---- --- --- is the result achieved requesting 0022 with umask of 022

The program is behaving as you asked it to, not necessarily as you thought it should. Common situation, that, with computers :-)

like image 164
JimH44 Avatar answered Sep 22 '22 12:09

JimH44


You'll probably need to show us the code that constitutes:

[do some other code here that creates a file]

The code you have works fine on my system:

import os
oldmask = os.umask (022)
fh1 = os.open ("qq1.junk", os.O_CREAT, 0777)
fh2 = os.open ("qq2.junk", os.O_CREAT, 0022)
os.umask (oldmask)
os.close (fh1)
os.close (fh2)

producing files as follows:

-rwxr-xr-x 1 pax pax 0 Apr 24 11:11 qq1.junk
---------- 1 pax pax 0 Apr 24 11:11 qq2.junk

You should also note the restoration of the old umask value which minimises the impact of changing it to the local operation.

As you can see from the results above, you also need to be aware that the umask value is "subtracted" from the mode you're using to create the file and we don't know what that mode is in your particular case.

That's evident even in your bash sample since a umask value of 022 when creating a file of mode 777 would result in r-xr-xr-x, not rw-r--r-- as you have it.


Based on your comments below where you indicate you're using open rather than os.open, a cursory glance of the Python source seems to indicate that this translates to a C fopen call which uses 0666 as the initial mode. This is supported by the slightly modified code:

import os
oldmask = os.umask (022)
fh3 = open ("qq3.junk", "w")
os.umask (0)
fh4 = open ("qq4.junk", "w")
os.umask (oldmask)
fh3.close()
fh4.close()

which gives us:

-rw-r--r-- 1 pax pax 0 Apr 24 11:44 qq3.junk
-rw-rw-rw- 1 pax pax 0 Apr 24 11:44 qq4.junk

So I'm not entirely certain why you're getting 0000 permissions in your case.

It would be worth seeing what the results are when you run that above program in your environment. If it's the same as I get then the problem may well lie somewhere else.

like image 37
paxdiablo Avatar answered Sep 21 '22 12:09

paxdiablo