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.

  • 7
    Can you make that something behave better, removing the dependency on the environment variable (e.g., using a config file instead)? That would be preferable to packaging hacks or mucking with .bashrc, I think. – user7043 May 27 '14 at 19:11
  • Sure, but let's say for the purpose of this question that modifying the application is not an option. – David Cowden May 27 '14 at 19:12
  • 1
    What if the user isn't running bash? There are many alternative shells available with a wide variety of startup files. I seriously suggest finding some alternative solution here. – Jules May 28 '14 at 5:20
  • 10
    So write a wrapper around it. See, for instance, 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. – Jules May 28 '14 at 5:55
  • 1
    @Vality I know. Jules' proposal has been suggested already. I'm being facetious--making fun of the circular logic involved to first argue that I should have a shell agnostic solution then proceed to suggest I use a shell script as the solution. It's a joke (; – David Cowden May 28 '14 at 10:38

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.

|improve this answer|||||
  • 1
    Historically, rc in a script name derives from CTSS runcom (Run Commands), but has since broadened in scope to include other meanings. – Jeffrey Hantin May 27 '14 at 22:02
  • 1
    @JeffreyHantin: Touché. Removed. – Blrfl May 27 '14 at 22:22
  • 1
    Hate 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. ;) – Jeffrey Hantin May 27 '14 at 22:56
  • 1
    @JeffreyHantin: True enough, although there will be no criticism of my use of the word "Unixy." :-) – Blrfl May 27 '14 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.
|improve this answer|||||

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.

|improve this answer|||||
  • I've considered this idea too. The project is young and will get to the point where this shouldn't be necessary. – David Cowden May 27 '14 at 19:37
  • @GlenH7 I updated my response. Hopefully the updated response is more of answer you are looking for. – R Sahu May 27 '14 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. – whatsisname May 27 '14 at 23:21
  • Furthermore, this answer's suggestion to create a wrapper script is the only answer that will work for all shells. – whatsisname May 27 '14 at 23:22
  • 1
    @MattThomason that realization is what prompted me to actually ask the question (; – David Cowden May 28 '14 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.

|improve this answer|||||
  • Thanks for the advice. I've never written a public package before and just want to make sure I don't do something taboo. – David Cowden May 27 '14 at 19:37
  • This is how the google cloud SDK handles this today. It asks if you want to modify your startup files. – jmq May 27 '14 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).

|improve this answer|||||

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.

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.