I am writing a package for something that requires an environment variable to be set in order to execute properly. Should the install step of a package manager modify a user's environment, or simply prompt the user to do so themselves? My intuition would be the latter, but I can see arguments for the former.
6 Answers
Should the install step of a package manager modify a user's environment, or simply prompt the user to do so themselves?
Neither. Package installers should never touch anything in a home directory for an account the package doesn't own. Packages should also configure themselves so that if they're installed, they're usable without any special effort on the user's part. (There are exceptional cases where you don't want to do this, but they're few and far between.)
Unixy environments have a place to put configuration files that are read whenever a user starts a login shell. For the Bourne and C shells, you can insert your configuration into /etc/profile
and /etc/csh.cshrc
respectively. (Don't forget to remove it when you uninstall.)
Many systems also support doing this using individual files, which makes it easier to add and remove bits of configuration without having to drop text into some arbitrary place in one file. (It also gives you all of the control and accountability benefits you get from a package manager.) Some distributions will configure /etc/profile
read all files matching /etc/profile.d/*.sh
.
-
1Historically,
rc
in a script name derives from CTSSruncom
(Run Commands), but has since broadened in scope to include other meanings. Commented May 27, 2014 at 22:02 -
1
-
1Hate to keep picking, but
profile.d
isn't built into bash, it's a hook commonly provided from (usually the distro's base)/etc/profile
. ;) Commented May 27, 2014 at 22:56 -
1@JeffreyHantin: True enough, although there will be no criticism of my use of the word "Unixy." :-)– BlrflCommented May 27, 2014 at 23:16
It's never acceptable to modify a user's /home
structure from the package manager unless that modification is the entire point.
The main approaches to this are:
- Notify the user they need to configure it.
- Supply defaults so it's not needed
- Package a launcher script that sets the values appropriately
- (If the distro supports it) Drop a file exporting the environment variable inside
/etc/profile.d
. On some linux systems, all scripts in this directory are sourced by the default shell setup, so you can safely set the variable there.
Question Should the install step of a package manager modify a user's environment?
Answer No. It's a bad idea to modify a user's data, in this case the .bashrc file. User's data should be considered sacred by a package manager?
Question Should the install step of a package manager simply prompt the user to do so themselves?
Answer This is a lot more palatable solution but still not ideal.
I think you should create a wrapper shell script where you can set the necessary environment variables and them run the executable after that.
-
I've considered this idea too. The project is young and will get to the point where this shouldn't be necessary. Commented May 27, 2014 at 19:37
-
@GlenH7 I updated my response. Hopefully the updated response is more of answer you are looking for.– R SahuCommented May 27, 2014 at 23:20
-
@GlenH7: This question is essentially an XY problem: meta.stackexchange.com/questions/66377/what-is-the-xy-problem, where the need for environment variables is the true problem to be solved. Commented May 27, 2014 at 23:21
-
Furthermore, this answer's suggestion to create a wrapper script is the only answer that will work for all shells. Commented May 27, 2014 at 23:22
-
1@MattThomason that realization is what prompted me to actually ask the question (; Commented May 28, 2014 at 4:47
You're missing the forest for the trees. Obviously it's more convenient to perform the environment change for the user, but it's also more risky and somewhat invasive. You should combine the best of both worlds by asking the user whether the installer should modify their .bashrc
, and otherwise give instructions how they should do it themselves.
-
Thanks for the advice. I've never written a public package before and just want to make sure I don't do something taboo. Commented May 27, 2014 at 19:37
-
This is how the google cloud SDK handles this today. It asks if you want to modify your startup files.– jmqCommented May 27, 2014 at 22:37
You're assuming that "user" is singular. What happens if I have thousands of users on this system?
You're assuming that you can even find the home directory of the user. If users are managed through e.g. LDAP you may not even be allowed to get a list of all valid users. The home directories may not be in /home; they may be dynamically mounted from the network. The user's home directory may be encrypted and the key inaccessible while they are not logged in.
There is no way to do this reliably in every possible situation. Use the distro's mechanism for setting environment variables for users as they log in or spawn shells. If that doesn't work, write a wrapper. (The wrapper can also be a binary if necessary, to address the argument in comments).
Setting a global variable in a package is acceptable if it's a one defined by your own project(and that means the project's name is part of the variable's name!). Even then, you shouldn't touch the user's .bashrc
file - instead you should add a script to /etc/profile.d.
.bashrc
, I think.bash
? There are many alternative shells available with a wide variety of startup files. I seriously suggest finding some alternative solution here.tomcat
, which needs several environment variables to function correctly; they're all set by a startup script that is run instead of running its binary directly.