I am looking for a way to programmatically maintain a consistent umask in the files /etc/profile
and /etc/bashrc
. They have an entry such as follows:
if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then
umask 002
else
umask 022
fi
I would like to programmatically check for the first if
statement above. If found, check to verify the next line is a umask (and not a comment) and if so, set it back to my standard umask if it has deviated from it.
Why would comments appear in the middle of the if
command? There are none in your example. You can simplify this process greatly by having the code identically formatted anywhere you need to check for its presence. If you can do that, here's a Python script that will do what you're asking. Make sure the code text between the triple quotes is exactly the same at is appears in the files you want to check (although in this case it really doesn't cause any problems if the code appears more than once in a script):
snippet = '''
if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then
umask 002
else
umask 022
fi
'''
with open('/etc/profile','r+') as f:
if snippet not in f.read():
f.write(snippet)
with open('/etc/bashrc','r+') as f:
if snippet not in f.read():
f.write(snippet)
Because the write locations are root-owned you would need to use sudo
when invoking the script: sudo python myscript.py
or sudo python3 myscript.py
. The script checks if /etc/bashrc
and /etc/profile
contain the block of text defined in snippet
and if not it is appended to the file(s).
Is this even worth doing?
Since you express concerns that the content of /etc/bashrc
and /etc/profile
might get changed I have to wonder who you think would be doing those changes. If it's the system itself, well the umask values you want to use are the defaults anyway so I can't see the system changing those to anything else. On the other hand, if you've got a gremlin or another sudoer
who fiddles with those files...
It's important to realize that a test which tells you the code text is already in the script tells you nothing about whether that code will be executed. It's very easy to make some subtle changes that will make your code not execute despite it being in the script.
Here's one where the code only executes if false = true
(i.e., never):
if false; then
if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then
umask 002
else
umask 022
fi
fi
This one wraps the code in a HEREDOC string which is never called.
: <<'no-umask-4u'
if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then
umask 002
else
umask 022
fi
no-umask-4u
This one simply changes the umask after your code executes (very simple example here):
if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then
umask 002
else
umask 022
fi
umask 077
Now what? In all of the above scenarios any programmatic test for the presence of your code text in the scripts will pass even though the code will never actually be executed (or in the case of the last one it executes but is subsequently overridden).
I realize I could just copy the entire file but would rather not disturb other changes that may have been made.
Generating a sha1 hash of the file and checking to see if it ever changes might be worth considering (it would certainly be more robust than a simple check if the code is in the file somewhere). I am curious what would be the source of the "other changes" you're concerned about.
/etc/profile.d
so that they are not overwritten by changes to/etc/profile
?~/.bashrc
and/or~/.profile
files or, if you want it to be applied to new users as well, to change the files in/etc/skel
. If you explain what your final objective is, we should be able to give a better solution (messing with the standard files in/etc
is very rarely the right approach)./etc/profile.d
or user-specific ones in the relevant user's $HOME directories.