Background: When installing the bash programmable completion, it did put stuff in /etc/profile.d to be run when starting a shell. The issue I am raising here is, what should the function of /etc/profile.d be? And secondly, should there be an additional /etc/bashrc.d added? My suggestion is to let /etc/profile.d be a place to put things which should (always) be run when opening a login shell (an only then). This makes a good place to put environment setup code etc. (It may however be that the functionallity of /etc/env.d is the very same, I am not sure. It seems to be restrictid to environment only, which is not my feeling of /etc/profile.d.) To my knowledge, this conforms to how things are arranged in Mandrake and RedHat also, and it is never wrong to try to standardize things between distros. Closely related to this is the location of things which should be run in *every* shell, not only login ones. On a per user basis, this is ~/.bashrc, but it does not seem to exist any global equivalent. What about /etc/bashrc? It's a pity this is not sourced by bash per default though. Easiest fix is to add # Source global definitions if [ -f /etc/bashrc ]; then . /etc/bashrc fi to /etc/skel/.bashrc. Then of course also letting /etc/bashrc source the things in /etc/bashrc.d in a manner similar to /etc/profile.d. Below follows (part of) my mail to Thilo about this for reference. Regards /Joakim > Hello Thilo! --snip-- > The placement of bash-completion in /etc/profile.d. Is this a good > thing? The reason I am objecting is that I think that profile should be > run only on login shells. Ok, as I use kdm to login, actually my > /etc/profile was not run at all. After reading a lot of different > suggestions how to run /etc/profile when starting with kdm, which does > not use a login shell, I settled for the nice solution to add -login to > the shell of /usr/kde/3/bin/startkde (made a quick try doing the same > thing with Xsession, but it didn't work). Any thoughts about the proper > solution here? > > Ok, back to bash-completion. The thing is, other distros use > /etc/profile.d as an extension to /etc/profile, (at least Mandrake and > RedHat). Which I personally think is a good thing. All you have to do if > you add a new program, which needs an environment, is to add a small > file to /etc/profile.d and it will be run from /etc/profile by e.g > (taken from Mandrake 8.1): > > # Source all sh files in /etc/profile.d/ > for i in /etc/profile.d/*.sh ; do > if [ -x $i ]; then > . $i > fi > done > unset i > > I've already fixed this for me, so therefore I naturally stumbled on the > /etc/profile.d/bash-completion, as needs to be run in *every* shell, so > it shouldn't be run from /etc/profile but rather from e.g. /etc/bashrc. > Alas, /etc/bashrc is never run at all, less you put some lines in your > $HOME/.bashrc. E.g: > > # Source global definitions > if [ -f /etc/bashrc ]; then > . /etc/bashrc > fi > > So to wrap it up, I've added my own directory /etc/bashrc.d, where I put > bash-completion, to by run by /etc/bashrc (from $HOME/.bashrc). > > Ok, lots of personal felings here, so I am not offended if you're point > of view is not at all like mine. Sticking to the same use for > /etc/profile.d as RedHat and Mandrake seems in my eyes to be a good > thing though.
An additional issue would of course then be where to put things which optionally could be run at startup, to be sourced on a per user basis from their .bashrc or .bash_profile. Like the bash_completion stuff e.g. (if not all users want it).
I am not in favour of just adding stuff to startup without the user knowing about it. This could be a serious security risk, and should be up to, and only up to the admin, or the user (he can add to .bash_profile or whatever).
As a reply to Martins comment: No, I am not talking about letting users add stuff to /etc/profile.d and /etc/bashrc.d. I am talking about a place for root and root only to place startup routines. I am missing this functionality at the moment. Individual users should put their startup things in ~/.bash_profile and ~/.bashrc.
We did discuss this, and currently it seems the general feeling is that we do not support this officially. You can still add this yourself, and as your /etc/profile will not be overwritten, you wont have to worry. I will take it to the other developers again for discussion, but like I said, many voted against last time due to not wanting to create such an meganism, as ebuilds could then just drop stuff there, and generally cause a security risk.
> due to not wanting to create such an meganism, as ebuilds could then > just drop stuff there, and generally cause a security risk. Pardon my ignorance, but how in the world can this be a security risk? You (as the user) are already running on a machine controlled by the root user, who has COMPLETE control of the kernel and *anything* running on the macihne, for $DEITY's sake. As only the root user can install things in /etc/profile.d (or whatever), security cannot be compromised. If you're arguing that scripts added to /etc/profile.d could add scripts with unsafe content, say a script containing the following export PATH=$PATH:/home/luser/bin where luser isn't you (or some such), then I would argue that /etc/env.d poses just as great a security risk since any random package could do the exact same thing with an /etc/env.d "script". In either case, it's the *packager's* job to ensure that nothing dangerous gets added to /etc/profile.d or /etc/env.d, just as it is the packager's job to ensure (sort of) the package does add backdoors/etc. to the system. Security aside, I (as a regular user) *would* want to be able to choose which profile scripts were run for me automatically startup, so why not just do something like: /etc/profile: ...yadayada... PROFILES=$HOME/.my_profiles if [ -f $PROFILES ]; do cat $PROFILES | while read PROFILE do source /etc/profile.d/$PROFILE.sh done; fi ...yaddayadda... (sorry if the formatting didn't come out right). Of course, to accompany this one would want an "add-profile" and a "del-profile" script, which would add/remove appropriate lines to $HOME/.my_profiles. This way, the user has complete control over which profiles are added to his/her startup. Also the script should perhaps be a bit more robust (ie. check if /etc/profile.d/$PROFILE.sh exists before trying to source it, etc.), but it's not rocket science. Any *good* arguments against this? Btw, I do not consider the fact that packages can drop random stuff in /etc/profile.d a good argument. Packages could just as easily drop random stuff in /etc, /usr/bin, /usr/lib or anywhere in the filesystem. Again, it's the package maintainers responsibility that this does not happen. (Sorry if this comes off as a flame, it's not meant to be, but I just got tired of hearing this argument.)
> *packager's* job to ensure that nothing dangerous gets added to > /etc/profile.d or /etc/env.d, just as it is the packager's job > to ensure (sort of) the package does add backdoors/etc. to the > system. Sorry, that should of course say: [...] the package DOESN'T add backdoors/etc. [...] :)
Thank you Bardur! At least someone got it right. Let's hope that people drop that stupid security argument now. > Security aside, I (as a regular user) *would* want to be able to choose which > profile scripts were run for me automatically startup, so why not just do > something like: ... Quite ok idea, but I am not really in for that solution, it seems a bit overkill for the single user, but maybe not. (Why not just add the /etc/profile.x/stuff directly to your ~/.bash_profile instead of hiding the functionality and going over /etc/profile?) Ok, trying to make my point clearer: There is a need for *two* ways to run scripts, a) by root, installed by root, for *all* users (yes I think anyone beeing root for say 100's of users wants this). b) by individual users, added by individual users. What I was looking for was to standardize the type (a) and my suggestion was to follow the Red Hat and derivates (no I don't know how SUSE etc does this) and have an /etc/profile.d where everything in it gets run. Additionally and messing up with this is the need for type (b), which of course also must exist so let us think about that one too. For the local user there must be a common place where scripts reside (root writeable only!!!) that people can link to or directly run from. As things here are optional, why not do something like the /etc/init.d and /etc/runlevel linkage thing here. Wrapping this up a bit, I think we should have: i) a place to put startup scripts (by the emerge install) say /etc/startup_scripts or whatever (*please* don't name this /etc/profile.d as this breaks name convention for all users comming from the Red Hat / Mandrake world). ii) a place where root (*only*) can put links to /etc/startup_scripts for the things that *all* users should run on login, I'd call this /etc/profile.d, but you may argue with that. iii) if we really wan't to tell the local user how to do things (this is optional in my opinon) we could urge (i.e. put in /etc/skel) a local directory $HOME/.etc/profile.d or something which contains links to /etc/startup_scripts and is sourced by $HOME/.bash_profile or similar. (Or your solution Bardur.) Extending the idea one could of course also have /etc/shutdown_scripts and machinery to add things automagically. In brief, learn from /etc/init.d et al. The *important* issue here: If we don't standardize this early, every root and every user out there will build it's own solution, and I don't think that is a good thing (it will certainly give trouble for people putting together ebuilds). /Joakim
> it seems a bit overkill for the single user, but maybe not. > (Why not just add the /etc/profile.x/stuff directly to your > ~/.bash_profile instead of hiding the functionality and going > over /etc/profile?) In the case of a single user, we *are* talking overkill, but I have co-managed a network of about 50-100 workstations (with ~400 users in total), and the fact that almost every single person has a different ~/.bash_profile (or ~/.tcshrc since tcsh seems to be preferred here) can be a royal PITA and can lead to all sorts of strange behaviour. Just think how much easier things would be -- both for the users and the system administrators -- if we could do away with the user's need to modify ~/.bash_profile himself/herself and just tell them to run env-add package (s/env-add/yourpreferrednamehere/) to get all the needed environment (and shell functions/aliases/etc.) changes for a given package. I cannot really see any drawbacks to this, but maybe someone would care to enlighten me? That said, it wood be a good thing if there were at least a standard *location* for putting these package-dependent "environment scripts", so that users could just add, e.g. . /etc/profile.d/packagename.sh to his/her ~/.bash_profile. This still leaves something to be desired, but the fact that the *location* is standard means that these sorts of things don't just get scattered in random subdirectories in the packages' docdirs (which might even vary with version numbers). Btw, my main motivation for this functionality is an ebuild for the Aegis package (see bug #5807 for details). If some of the "official" Gentoo people would comment on their preferred solution, I could very likely be convinced to code up the necessary scripts to implement it. (I realize that this will not require massive coding, but if the problem is really just the lack of time to actually implement something, then consider me voluteered :))
> and the fact that almost every single person has a different ~/.bash_profile > (or ~/.tcshrc since tcsh seems to be preferred here) can be a royal PITA You'r totaly right there, esp. when some users run tcsh, some run bash and some run zsh, each with it's own little quirks. (Note that tcsh equiv. of .bash_profile is .login) > I cannot really see any drawbacks to this, but maybe someone would care to > enlighten me? The only thing I am afraid of is loosing control as an individual user, but if care is taken so that the mechanism stays simple and clear I don't see any problems. But I *do* want to keep it simple and not hidden under loads of layers of scripts and GUIs etc., there is a reason I am running Gentoo and not Mandrake anymore. The more I think about it, the more I realize that the rc scripts of /etc/init.d et al. is the way to go. Just do something similar for the login environment and the shells in use. a) enforced by root and b) for the individual user. Care must be taken not to mess up with the different kinds of shells on the market though.
<joke> Ok, guess I should respond again and try and say something stunning </joke> I thought about this some more, and yes, why it is not implemented is due to many reasons. Some have been mentioned, others not. Main thing .. I do not want to dictate something to everybody; simplicity; security (please do not argue this one for now, as not entirely my point). But I must agree .. we need to either: 1) Get a standard going 2) Or just plain refuse As I do not think you should entirely throw away user input (except maybe if explicitly to make things easier [ and usually more annoying for guru ] for newbies .... we are not a newbie distro after all ... ), I think we are past the "try to ignore and hope it goes away stage" :P It have not, and there has been valid points as to why, so here goes .... I am going to *suggest* an easy simple way to do this, and want some comments. Please keep it simple, secure (yeah, some will moan if too automated), and practical. I will then leave you guys to comment for the next few days, and if you so wish, call me a "arogant bastard", "selfish pig" or the like if you so wish =) *g* --------------------------cut------------------------------------------- # Global (enabled by sys admin) for x in /etc/profile.d/* do # sys admin must set it executeble to be used if [ -x $x -a -f $x ] ; then # if .sh, then it should be sourced if [ "${x##*.}" == "sh.env" ] ; then source $x elif [ "${x##*.}" == "sh" ] ; then # else execute it exec $x fi fi done # Private (enabled by user) for x in $HOME/.profile.d/* do local realx="$x" if [ -L $x ] ; then realx="`readlink $x`" if # only use it if not enabled globally by sys admin # also, if the user have it in his ~/.profile.d/, we presume # he put it there, and not a ebuild if [ "${realx%/*}" == "/etc/profile.d" -a ! -x $realx -a -f $realx ] || \ [ "${realx%/*}" != "/etc/profile.d" -a -f $realx ] ; then # source it if [ "${x##*.}" == "sh.env" ] ; then source $realx # execute it elif [ "${x##*.}" == "sh" ] ; then exec $realx fi fi done --------------------------cut------------------------------------------- This should go (my opinion) into ~/.bash_profile, as you mostly only want it if the user login ... or at least the global stuff, commented by default. The sys admin can then enable it at system install by editing the /etc/skel/.* files if he so wish, or the user can do afterwards. I also think a README in /etc/profile.d/ explaining the whole mess should work =) We use .sh for script that should be executed, then the zsh/tcsh guys can add thier own .csh* or whatever. .sh.env is for stuff that should be sourced. A global script can only be "enabled" if it is executable, else ignored. If in ~/.profile.d/ it *should* be added by the user, thus we alway use them if not used by global. Adding scripts can be added if really needed, but then should follow rc-update and co behaviour and output preferred. This is a quick job of putting my thoughts into code, so may have some syntax/logic errors ;-)
A few quick comments: 1) The script logic is basically sound, but I cannot see any need to "exec" anything. The exec'd program/script isn't going to be able to anything to the user's environment (variables+aliases+...) anyway, is it? Of course, it could create files (for the user) or do something of that nature, but so could any script that were sourced. I really cannot see any good uses for this, so in the name of simplicity it should probably be left out. 2) Just a question of style I guess, but I would probably go for a for x in /etc/profile.d/*.sh loop instead of a for x in /etc/profile.d/* and checking each file name individually. 3) There is still a question of the ordering of the "sourcing". If a normal shell glob is used, the files would be processed in lexicographical order, meaining that specific priorities could be given through using names of the form "NNsomepackage.sh", "NNotherpackage.sh", etc. This should probably be sufficient, but it should probably decided - as a matter of policy - if "NNpackage.sh" names are to be used (as in /etc/env.d), or plain "package.sh" names should be used. 4) I do take issue with the following: > This should go (my opinion) into ~/.bash_profile, as you mostly only > want it if the user login [...] The sys admin can then enable it at > system install by editing the /etc/skel/.* files if he so wish, or > the user can do afterwards. The problem with this approach is, that it is exactly what we are trying to avoid. I touched on a couple of issues with it in my previous post, but basically it will create a MESS of the user's ~/.xxx_profile files: *) Different versions of these scripts will be copied to users which are created at different times *) The profile.d feature CANNOT be enabled this retroactively (ie. for users that have already been created). It would require manual/automatic editing of each and every user that has been created. This is a laborious/dangerous undertaking at best. *) Changes to these scripts WILL NOT and CANNOT be propagated to users' ~/.xxx_profile files automatically. This would mean, that if Gentoo policy regarding the /etc/profile.d directory were to change, there would be NO GOING BACK. [Can you tell, that I administer lots of users...? :) I've been through similar stuff before, and let me tell you: it wasn't fun.] Therefore these scripts absolutely *MUST* go in /etc/profile (bash's global profile). If it is commented out by default, that's fine. The main point is not whether /etc/profile.d/ scripts get run by default after a system install, but whether there *is* a standard mechanism, that the system administrator can enable if necessary.
More comments: Ok. Basically what Martin suggests is what I had in mind at the first place. I do see a problem with this one though, which Bardur touches, and that is that it does not contain any place where to put scripts which are *not* to be sourced. If we are to leave things up to individual users to source foo.sh there must be a place where the packager can put foo.sh once and for all when root does the ebuild, regardless if we wish to use it or not, just that it is installed. So, (sorry for repeating myself, flame me for this,) my suggestion is to have three places to put things. 1. A place where the ebuild put the script, say /etc/scripts.d (root write only), which do nothing but lay around. 2. A place where things are sourced at login from /etc/profile, say /etc/profile.d which contains links to the directory /etc/scripts.d (think /etc/init.d and /etc/runlevels/foo here). This is where root put links for the scripts that everybody is to run at login. 3. A place for the common user (enforced or not, I don't really care personally) to put links to /etc/scripts.d, say $HOME/.profile.d sourced from $HOME/.profile (or optionally from /etc/profile, but I do prefer the first one). The first place is the most important one to standardize, as it is to be used by the packager. The second place is important to standardize only if we wish to standardize /etc/profile in some sence. I think it is a good thing though. The third place I cannot really see why it needs to be enforced by the distro, if we have the other two, it is easy for the local maintainer to set it up anyway he/she likes it. Bardur takes this, as I see it, one step further and asks for machinery to automize the putting of things (i.e. links to the first place) in the third place (and probably the second also). Sure, why not, as long as I am not forced to use it if I don't want to. (I am not forced to use rc-update add blaha neither if I don't want to, but, the point is, it is quite nice to have.) As the rc-scripts already exist, doing basically the same thing, this shouldn't be too hard to put together should it? And if the rc-scripts are to be used, then we can go all the way and get the same dependency system as in the /etc/init.d scripts, which in my eyes would be a really nice thing. (Much more flexible than the priority thing of /etc/env.d)
Ok, I havent forgotten about this, just been a bit busy .. will try to respond in the next week or so.
*** Bug 14368 has been marked as a duplicate of this bug. ***
Azarah, would you like me to look at this? Give me the ticket if so.
*** Bug 71611 has been marked as a duplicate of this bug. ***
*** Bug 76304 has been marked as a duplicate of this bug. ***
Ok, just to add my submisssion also here (copied from my Bug): I would suggest to add the following extention for /etc/profile: # Source profile extensions for certain packages # if [ -d /etc/profile.d ] ; then for s in /etc/profile.d/*.sh ; do [ -x "$s" ] && . "$s" done unset s fi with the "test -x" it is possible to enable/disable single scripts w/o deleting them (just set or unset the X-flag). It's not needed otherwise.
*** Bug 38381 has been marked as a duplicate of this bug. ***
I think this "bug" is a little dead here... why? It was started 3 years ago!!! There must be something happening here. Why Gentoo did not have some place to super user's put global customization settings that are untouchable to Gentoo's distribution system and cannot be replaced during a etc-update?
FI, ebuilds for tcsh and xorg-x11 both dump stuff in /etc/profile.d If /etc/profile.d directory is to be populated by the owner rather than Gentoo, these will need to be modified.
Last I checked, xorg-x11 at least do not. To followup .. from -dev ML: ----- On Fri, 2005-07-15 at 19:02 -0400, Mike Frysinger wrote: > On Friday 15 July 2005 06:56 pm, Herbert Fischer wrote: > > Thanks... I saw that "bug" and saw that it is very old (from 2002) and > > nothing was done. Did you know why? > > hmm, us baselayout guys have discussed it before, but i guess we've never > posted to the bug > > the only thing we really have against it is the potential of developer > abuse ... that is, we feel that ebuild authors should *never* install a file > there, it should only ever contain files created by the user I the the resolution was pretty much that it is not that much of a schlep to maintain those lines of code in /etc/profile if the user/admin really wants it. -- Martin Schlemmer
Reply to comment 22: This does not address the issue of packages which actually require installation and sourcing of scripts to function as the authors intended. Cook from 'dev-util' is/was one such package. Long story, but all the 'short versions' of commands were aliases expanding to very long command invocations. Without sourcing a file containing those aliases it was basically unusable. I don't use cook anymore so I don't particularly care about it, but there are bound to be similar packages. Telling the *users* that they need to add custom code to /etc/profile (and profiles of whatever other shells the other users on the system use) just to get a package working is hardly optimal. Also, what kind of 'developer abuse' are you talking about? I can't think of any kind of 'developer abuse' which isn't already possible through other mechanisms anyway. In short, I don't see why adding a short snippet similar to comment 18 is a bad idea. Please explain it to me.
Why trying to be too smart? Wouldn't the following line at the end of /etc/profile suffice? test ! -x /etc/profile.local || . /etc/profile.local
Not really. Sacrificing the flexibility, ease of updates, etc. of a directory-based approach to save 5 lines in /etc/profile is not a good tradeoff.
Sorry, my comment 24 was regarding comment 3 and comment 20. To elaborate further: For user/admin maintained files the hook from comment 24 would be enough. For more complex setups the user/admin could put a snippet similar to that from comment 18 in /etc/profile.local.
Um, ok, but regarding comment 20: Maybe I'm missing something, but I don't really see what the desire to have a file/directory which is protected from portage/etc-update has to do with this "bug". Surely an "exclude these files/directories" feature would something one would add to portage/etc-update -- and as such a request for such features belongs in a separate bug report.
Glad too see that some activity has arisen around this one again. It's been dead for too long. First, regarding comment 20. The issue here is not (as correctly pointed out in comment 27) a place untouched by emerge. This is already facilitated by CONFIG_PROTECT_MASK. Read man pages of env-update: --snip-- etc-update will check all directories in the CONFIG_PROTECT variable. All config files found in CONFIG_PROTECT_MASK will automatically be updated for you by etc-update. See make.conf(5) for more information. --snap-- The issue is still: To have a standardized place where ebuilds (or whatever and whoever with root permission) can drop scripts which are to be run at login time (as opposed from scripts in init.d which are run at boot time). Preferably with options to enable/disable the execution of the scripts. From a personal point of view, adding a small script as the one in comment 18 is perfect. That's what I've been using for the 3 years since this thread was opened. The desire, however, is to have something standardized(!) So that a developer/packager/... can know the behaviour when putting something in /etc/profile.d. If it's not a standard, then it's useless from a packagers point of view. Yes, some of this functionality is in /etc/env.d but significantly less powerful. Similar, very well functioning is the rc-* pile of scripts for handling /etc/init.d and runlevels. This would be great to have at login-level also, but if people feel that's too heavy machinery, comment 18 is the way to go. Only thing needed is to elevate it to a standard.
ok, once again my thoughts: /etc/profile.d is a well known and established standard in many other distros. The code fragment I posted in comment 18 is more or less "stolen" from SuSE. So why do we need something special? Many packages (ie. xorg-x11) are placing files in this directory (if not removed by the package maintainer), because many other distros sources /etc/profile.d/*.sh by default. Ok, we have /etc/env.d, and this is good for most static environment settings. But for dynamic settings, /etc/profile.d is the way to go. Just my 2 euro cents.
Ok. Forgive me if I missed something here in the many lenghty replies above. For tcsh I put some files into /etc/profile.d, in the latest ebuild such that only those which have a .csh suffix are being sourced. This sourcing will probably be made conditional on having an interactive shell or not as per bug #104763. So, since tcsh is blocking this bug now, where do I have to place my files instead?
whats wrong with just using say /etc/tcsh.d/ for tcsh-specific scripts ? imo, only POSIX sh compatible scripts should ever be placed into /etc/profile.d
That's completely fine with me. However, it leaves us with the question why we do it different from other distros. Fedora/RedHat places them also in /etc/profile.d. Debian doesn't have such directory. I think SuSE does also use /etc/profile.d, but I cannot check that. Again, simply moving the location works fine for me, but doesn't solve the security risk imposed by it as written down here. Perhaps it might then be better to merge everything into csh.cshrc and csh.login instead and put the scripts that I disabled as examples somewhere in the same location as the docs?
we could go with the requirement that all files in profile.d be named with .sh and have bash only source those files (which is what redhat does) which means nothing needs to be changed in tcsh, correct ?
tcsh only sources .csh files, so pretty much everything is happily ignored by tcsh. In older versions only 4 named files are also being sourced from /etc/profile.d: tcsh-aliases, tcsh-bindkey, tcsh-complete and tcsh-settings, which have no suffix. This behaviour is removed in the latest version which should still be stabled. tcsh would indeed not need any modifications as it ignores more or less anything which doesn't end with .csh from /etc/profile.d currently and in the future.
added /etc/profild.d/*.sh to svn, thanks Fabian