I have a program, which can be used by a group and thus the output should have group writing permission by default, thus umask 002. Of course each user could do (umask 002 && cmd). But since this is cumbersome and error prone, I want to set it umask within the cmd. How can this be done? cmd has the possibility to spawn shell command.

It seems to be possible, as there is a built-in solution in python (see code #1 in https://www.geeksforgeeks.org/python-os-umask-method). Well, I have another language; but knowing how it is done in os of python might help (I'm stucked here https://hg.python.org/cpython/file/v2.7.3/Modules/posixmodule.c#l2677).

  • Please edit your question and tell the programming language you want to use. There is a system call umask which is called in the linked C file.
    – Bodo
    Commented May 19, 2022 at 7:41
  • @Bodo The language in cmd is idl, but is also allows to call c function (l3harrisgeospatial.com/docs/basiccexamples.html). If cmd would be a bash script, then it seems one could just use bash <<<"umask 0002; echo 'hello' > foo; ls -gG foo". Commented May 19, 2022 at 7:58
  • Please edit your question and add all requested information or clarification to the question, instead of using comments for this purpose. You should add clarification for IDL. To my knowledge, "interface definition language" is more known than "interactive data language". So is there any remaining question? There is a function umask, and you can call C functions from IDL.
    – Bodo
    Commented May 19, 2022 at 8:10

2 Answers 2


Do that (umask 002 && cmd) for them.

Make a script that sets the umask, and only then starts the actual program. Then, put the wrapper script somewhere in PATH before the actual command, or rename the program itself and put the wrapper script in its place. (Make sure to call the renamed program from the script, though.)

E.g. if the program is /usr/bin/foo, and you have /usr/local/bin first in PATH, create /usr/local/bin/foo that looks like this:

umask 002 &&
exec /usr/bin/foo "$@"

(the "$@" passes any and all command line arguments to the program itself.)

Or rename /usr/bin/foo to /usr/bin/foo.orig, install the script as /usr/bin/foo and have it run /usr/bin/foo.orig.

Of course you could modify the program itself, but using a wrapper works regardless of how the program was implemented. Renaming and replacing the script can be an issue with upgrades though, as the new version might clobber your script, so using another directory may be better in that. (Though there's things like dpkg-divert on Debian that can be used to tell the package manager to put the file somewhere else.)

Note that this is easy since we're just starting the program in question. Forcing a change to the umask of an already running process from the outside would be a whole another issue, and impossible with standard tools.

(On Linux, you could attach to the program with gdb, and make it do the umask() system call without the actual program knowing. But that's hacky and only works if debugging isn't restricted with kernel.yama.ptrace_scope. It probably is in modern systems.)


So cmd has to call umask (from "libc.so.6").


  • bash: If cmd is a bash script, it could be just moved inside the cmd script:
umask 2
  • Python: The built-in os.umask can be used:
import os
  • Python: Reimplementation to demonstrate the c-library call (unix)
from ctypes import CDLL
libc = CDLL("libc.so.6")
  • idl:
print, call_external('libc.so.6', 'umask', '0002'O, /all_value, /auto_glue), format='(O)'

where O indicates octal format.

print, call_external('libc.so.6', 'umask', 0, 0), format='(O)'

That works, but it behaves strange in idl, which is another story. (One would expect call_external('libc.so.6', 'umask', 2, /value) would be required. The number passed to umask seems to be the number of args. And when umask was originally 0022, the first call returns 18!?).

  • 1
    re. 0022 vs. 18, the C convention is that numbers starting with zeroes are octal, so 022 is 2*8+2 = 18 in decimal. People don't use octal much these days, but it is used for permission bits since the digits line up nicely with the three-bit rwx groups. (The shell's umask command always takes the argument in octal, but you'd need e.g. umask(022) in C and os.umask(0o022) in Python to get that umask. Doesn't matter for ones that look like 00x, of course.)
    – ilkkachu
    Commented May 19, 2022 at 11:01
  • I don't know anything about idl, but you may want to check that that call_external('libc.so.6', 'umask', 0, 0) doesn't set the umask to just zero, giving write permission to everyone.
    – ilkkachu
    Commented May 19, 2022 at 11:01
  • @ilkkachu "octal" very good hint! Python also has the oct function. And in idl print, '22'O. Commented May 19, 2022 at 11:44
  • 1
    with printf formats, it's %o to print in octal, so e.g. printf("0%o\n", 18) in C or 18 % "0%o" in Python to get 022.
    – ilkkachu
    Commented May 19, 2022 at 12:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .