Trying to convert the following commands to atomic one-liner… possible?

echo foo | sudo -u sun tee bar.private
chmod 600 bar.private
  • What you are trying to accomplish?
    – ThoriumBR
    Mar 22, 2022 at 11:28
  • 2
    What you are looking for is umask
    – MechMK1
    Mar 22, 2022 at 11:30
  • @ThoriumBR Trying to create a file as given user and set its permissions in one atomic operation (in other words, I don’t want file to be ever readable by other users).
    – sunknudsen
    Mar 22, 2022 at 11:58
  • 1
    umask is confined to the current shell. You can set umask in one terminal, do whatever you want, close the terminal, done. No need to "reset umask to default", it will always be default. To change umask for all shells you need to put it on ~/.bash_profile (if you use bash as shell) so every shell will have the changed umask.
    – ThoriumBR
    Mar 22, 2022 at 12:08
  • 2
    @ThoriumBR, though if you create the file with loose permissions at first, an attacker could in theory open it just after it's created, and if kept open, the fd to the file could still be used to read the file after the permissions were changed.
    – ilkkachu
    Mar 22, 2022 at 15:06

1 Answer 1


Permissions of newly-created files are modified by the process umask, which works in inverse: the bits set in the umask will be cleared in the resulting permissions. So setting the umask to 0077, would make most utilities create files with permissions 0600.

By default, sudo inherits a stricter umask from the environment it's started in, so you could do something like this:

echo foo | (umask 0077; sudo -u sun tee bar.private)

and the file would be created with permissions 0600.

What sudo actually does, is that it does a bitwise and of the umask in the environment, and the umask set in the configuration file (umask option, defaulting to 0022). So by default you can't have the tee run with an umask of 0000, it'll turn to 0022 instead. But we're making it stricter here, and that works.

Of course, it's possible that the configuration sets the umask to something else, perhaps even with umask_override, which might make it looser, and in addition there might be some PAM module to also modify it. In that case, you could have sudo run a shell that sets the umask and then runs the command:

echo foo | sudo -u sun sh -c 'umask 077; tee bar.private'
  • Brilliant, thanks!
    – sunknudsen
    Mar 22, 2022 at 16:10

You must log in to answer this question.

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