While the defaults we saw in the previous section for newly-created files are sensible in many situations, they're not ideal in others. In particular, note that every other user on the system has permission to read the file, if they can get to it or name it. This isn't appropriate for files with sensitive information in them, such as passwords, private keys, or confidential user data. In such a situation, we don't want all the files we create to be readable by every user on the system, especially for the system users running processes for unauthenticated network services, such as a web server! How can we arrange for Bash to lock the files down?
When Bash creates files for redirected output, it starts with a permissions string of rw-rw-rw-, or in numeric notation, 666: with those permissions, all the system's users could read or write the file. Before it creates the file, however, it checks the umask value of the process to find out which of those permissions it should not apply to the created file. This value therefore masks permissions bits. The bash program and many other system programs, such as touch, use umask to decide the default permissions for created files.
You can check the current umask value for your Bash shell with the umask command. By default, it prints in the numeric format. You can add the -S option to print the same value in string or symbolic form, if you find it easier to read:
$ umask 0022 $ umask -S u=rwx,g=rx,o=rx
The value we see here, 0022, is a common value for users who are not root. Note the extra zero at the start, a common prefix to signal an octal number. We can break down the other three digits like so:
- 0: Don't strip any of the owner's privileges from the created file.
- 2: Strip write permission for groups from the created file, but leave read and execute permissions intact.
- 2: Strip write permission for all other users from the created file, but leave read and execute permissions intact.
We can change the umask value for the current running shell by providing it as an argument, in either numeric or symbolic format. To prevent users besides the file owner and group from being able to read the files, we might use a umask of 027:
$ umask 027 $ cat secrets > secret $ ls -l secret -rw-r----- 1 bashuser bashuser 1 2018-07-28 22:33:48 secret
In this case, other users – whose permissions are described by the last three flags in the permissions string – end up with no permissions for this file. If a user who is neither bashuser nor in the bashuser group tried to read the file, the kernel would refuse access, with Bash raising a "Permission denied" error.
By contrast, with an "empty" umask of 0000, Bash creates new files that are readable and writable for everyone:
$ umask 000 $ cat announcements > public $ ls -l public -rw-rw-rw- 1 bashuser bashuser 1 2018-07-28 22:36:08 public
If you're creating secret files during a shell session, consider switching to umask 077 to make new files readable only by you; similarly, when you are writing a new script, consider declaring an appropriate umask near the top.
Note that many other programs besides bash will also use umask for file creation, but not all of them do, and the umask doesn't prevent them from changing the permissions of the file after it's created. If you are using a new program for sensitive data, always check the permissions of any files it creates carefully.