I am reading about basic shell scripting from Linux Command Line and Shell Scripting Bible.

It says that the /etc/profile file sets the environment variables at startup of the Bash shell. The /etc/profile.d directory contains other scripts that contain application-specific startup files, which are also executed at startup time by the shell.

  • Why are these files not a part of /etc/profile if they are also critical to Bash startup ?

  • If these files are application-specific startup files not critical to Bash startup, then why are they part of the startup process ? Why are they not run only when the specific applications, for which they contain settings, are executed ?

3 Answers 3


Why are these files not a part of /etc/profile if they are also critical to Bash startup ?

If you mean, "Why are they not just combined into one giant script?", the answer is:

  1. Because that would be a maintenance nightmare for the people who are responsible for the scripts.
  2. Because having the scripts loaded as independent modules makes the whole system more dynamically adjustable -- individual scripts can be added and removed without affecting the others. Etc.
  3. Because they are loaded via /etc/profile which makes them a part of the bash "profile" in the same way anyway.

If these files are application-specific startup files not critical to Bash startup, then why are they part of the startup process ? Why are they not run only when the specific applications, for which they contain settings, are executed ?

That seems to me like a broader design philosophy question that I'll split into two. The first question is about the value and appropriateness of using the shell environment. Does it have positive value? Yes, it is useful. Is it the best solution to all configuration issues? No, but it is very efficient for managing simple parameters, and also widely recognized and understood. Contrast that to say, deciding to configure such things heterogeneously, perhaps $PATH could be managed by a separate independent tool, preferred tools such as $EDITOR could be in an sqlite file somewhere, $LC lang stuff could be in a text file with a custom format somewhere else, etc -- doesn't just using env variables and /etc/profile.d suddenly seem simpler? You probably already know what an env variable is, how they work and how to use them, vs. learning 5 completely different mechanisms for 5 different ubiquitous aspects of what is appropriately named "the environment".

The second question is, "Is startup the appropriate time for this?", which begs the objection that it is not very efficient (all that data which may or may not get used, etc). But:

  • Realistically, it is not all that much data, partially because no one in their right mind would use it for more than a few simple parameters (since there are other means of configuring an application).
  • If it is used wisely, with regard to things that are commonly invoked, then setting, eg, default $CFLAGS from a file somewhere every time you invoke gcc would be less efficient. Keep in mind that the amount of memory involved is, again, infinitesimal.
  • It can involve systemic things which more than one application may be involved with, and the shell is a common ground.

More could be added to that list, but hopefully this gives you some idea about the pros and cons of the issue -- the major 'pro' and the major 'con' being that it is a global namespace.

  • Does it have positive ... and understood. What are you trying to say here ? I understood everything other than that paragraph.
    – asheeshr
    Commented Feb 9, 2013 at 14:22
  • 3
    The shell environment is generally used for configuring the shell itself and other ubiquitous tools. This is not the only way that configuration could be done, so it is worth considering whether the environment is better or worse than the other options. By having "positive value", I meant that using the environment does seem to have some advantages over other options at least WRT "managing simple parameters" -- namely that it is very efficient and "widely recognized and understood"...and I'll add a bit to explain that phrase further.
    – goldilocks
    Commented Feb 9, 2013 at 16:23
  • What about appending lines to profile.local? Is this acceptable vs. creating scripts in the profile.d folder? Commented Jul 30, 2014 at 18:32
  • @AvindraGoolcharan Different distros may use different schemes for this kind of thing. The profile.d directory only works because its contents are sourced by /etc/profile, which is specified by shells such as bash as a startup file (see INVOCATION in man bash); if you edit /etc/profile, you can disable /etc/profile.d. /etc/profile.local seems to be a SUSE invention, presumably sourced from somewhere such as /etc/profile so that you can put your own stuff there. However, if you move it to a non SUSE system and don't make any other adjustments, it won't be used by anything.
    – goldilocks
    Commented Jul 30, 2014 at 19:09
  • Gotcha, that's crystal clear. Yeah we use SUSE at my job. /etc/profile. seems like a much better bet. Commented Jul 31, 2014 at 22:49

Those files are specific to an application, but are sourced at shell startup, not when the application starts. A configuration directory is used here for the same reason that it is found in many other places. This allows an application or software package to modify configurations. This wouldn't be possible without a split configuration, as multiple packages trying to manage/update a single configuration file that can also be modified by the user would be buggy and messy.

Also a side note, /etc/profile is sourced by all shells, not just bash. The bash specific configuration file is bashrc and only sourced for interactive shells.

  • 3
    The second paragraph is interesting. Since different shells support different syntax, this would require that there be a significant common syntax. True for bash and sh, but I don't think so for others like csh or tcsh, which have their own global login startup scripts. On many systems, /bin/sh is just a link to /bin/bash. But bash modifies its behavior to be posix-compliant when invoked as sh. So one would think that authors of scripts in /etc/profile.d would need to be careful to avoid using bash extensions outside the posix subset.
    – sootsnoot
    Commented Oct 10, 2014 at 6:28
  • Under linux there are separate .csh and .sh files for the two major shell types.
    – stark
    Commented Jan 13, 2015 at 14:25
  • 4
    /etc/profile is not processed by all shells. zsh does not. At least not on debian 11.
    – RichieHH
    Commented Dec 6, 2020 at 9:05

jordanm's answer is incorrect. /etc/profile is not sourced by all shells. As you point out, it is not sourced by csh, tcsh - I'm not sure about zsh. It is sourced by Bourne shell (sh) derivatives, like Korn Shell (ksh) and BASH (bash). csh uses /etc/login. People who tend to exclusively use Borne Shell derivatives tend to forget other shells exist. They add something to /etc/profile expecting it to apply to "all users" and then are surprised when the odd C Shell user (and we are an odd lot) doesn't have the stuff they configured in /etc/profile.

Even so, people tend to forget about other Borne Shell derivative shells exist. If they use bash or ksh, they feel free to add syntax to /etc/profile that is not valid in Bourne Shell, like say defining a variable and exporting it on the same line. Then you get some script that does #!/bin/sh and it chokes on the syntax. /etc/profile should stick to Bourne Shell compatible syntax.

Likewise, you should stick to it in your own .profile (use .bash_profile if you want some bash syntax) - it may be a little extra typing, but it is extra typing you do all of once. Reference ${HOME} and not ~, etc. Some flavors of Unix, cron jobs run under sh, each line of your Makefile is processed by sh, so if you're working across multiple flavors of UNIX, it really pays to keep your .profile Bourne shell compatible. As a SysAdmin, I can't tell you how many times I've helped someone by fixing up their .profile to be Bourne Shell compatible.

On Linux, /bin/sh is a link to /bin/bash and when you run it, it looks a the path that was used to run it, and (in theory) limits itself to only things that Bourne Shell supports. Likewise, vi on Linux is really vim, again limiting itself. Occasionally you see features "bleed through". Occasionally vim pretending to be vi will do something that vim supports that vi does not because the authors of vim forgot to disable this in "vi backwards compatibility" mode. I would not be surprised if bash pretending to be sh has some similar "bleed through" features. Wouldn't be surprised if some feature "works on Borne Shell on Linux", but not on a System V or BSD based UNIX (AIX, OpenBSD, etc.).

  • 1
    Are you sure "on Linux /bin/sh is a link to /bin/bash"? That's a sound statement.
    – 41754
    Commented Sep 13, 2019 at 14:38
  • 2
    ZSh does not process /etc/profile either in Debian. I added a line to source it in /etc/zsh/zprofile
    – RichieHH
    Commented Dec 6, 2020 at 9:07
  • As @41754 implies, /bin/sh is not (necessarily) a link to /bin/bash. At least on Debian it's a link to /bin/dash.
    – FWDekker
    Commented Feb 19 at 8:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .