{"id":701,"date":"2011-09-27T09:40:52","date_gmt":"2011-09-27T09:40:52","guid":{"rendered":"http:\/\/blog.designed79.co.uk\/?p=701"},"modified":"2011-09-27T10:04:11","modified_gmt":"2011-09-27T10:04:11","slug":"zshbash-startup-files-loading-order-bashrc-zshrc-etc","status":"publish","type":"post","link":"https:\/\/blog.designed79.co.uk\/?p=701","title":{"rendered":"Zsh\/Bash startup files loading order (.bashrc, .zshrc etc.)"},"content":{"rendered":"<p id=\"post-426\"><span class=\"Apple-style-span\" style=\"font-size: 13px; font-weight: normal;\">If you have ever put something in a file like\u00a0<tt>.bashrc<\/tt>\u00a0and had it not work, or are confused by why there are so many different files \u2014\u00a0<tt>.bashrc<\/tt>,\u00a0<tt>.bash_profile<\/tt>,\u00a0<tt>.bash_login<\/tt>,\u00a0<tt>.profile<\/tt>\u00a0etc. \u2014 and what they do, this is for you.<\/span><\/p>\n<div>\n<p>The issue is that Bash sources from a different file based on what kind of shell it thinks it is in. For an \u201cinteractive non-login shell\u201d, it reads\u00a0<tt>.bashrc<\/tt>, but for an \u201cinteractive login shell\u201d it reads from the\u00a0<em>first<\/em>\u00a0of .bash_profile, .bash_login and .profile (only). There is no sane reason why this should be so; it\u2019s just historical. Follows in more detail.<\/p>\n<p>For Bash, they work as follows. Read down the appropriate column. Executes A, then B, then C, etc. The B1, B2, B3 means it executes only the first of those files found.<\/p>\n<pre>+----------------+-----------+-----------+------+\r\n|                |Interactive|Interactive|Script|\r\n|                |login      |non-login  |      |\r\n+----------------+-----------+-----------+------+\r\n|\/etc\/profile    |   A       |           |      |\r\n+----------------+-----------+-----------+------+\r\n|\/etc\/bash.bashrc|           |    A      |      |\r\n+----------------+-----------+-----------+------+\r\n|~\/.bashrc       |           |    B      |      |\r\n+----------------+-----------+-----------+------+\r\n|~\/.bash_profile |   B1      |           |      |\r\n+----------------+-----------+-----------+------+\r\n|~\/.bash_login   |   B2      |           |      |\r\n+----------------+-----------+-----------+------+\r\n|~\/.profile      |   B3      |           |      |\r\n+----------------+-----------+-----------+------+\r\n|BASH_ENV        |           |           |  A   |\r\n+----------------+-----------+-----------+------+\r\n|                |           |           |      |\r\n+----------------+-----------+-----------+------+\r\n|                |           |           |      |\r\n+----------------+-----------+-----------+------+\r\n|~\/.bash_logout  |    C      |           |      |\r\n+----------------+-----------+-----------+------+<\/pre>\n<p>Typically, most users will encounter a login shell only if either:<br \/>\n* they logged in from a tty, not through a GUI<br \/>\n* they logged in remotely, such as through ssh.<br \/>\nIf the shell was started any other way, such as through GNOME\u2019s\u00a0<tt>gnome-terminal<\/tt>\u00a0or KDE\u2019s\u00a0<tt>konsole<\/tt>, then it is typically not a login shell \u2014 the login shell was what started GNOME or KDE behind your back when you logged in; things started anew are not login shells. New terminals or new screen windows you open are not login shells either. (Starting a new window in OS X\u2019s Terminal.app seems to count as a login shell, though.)<\/p>\n<p>So typically (or sooner or later), what you will encounter are non-login shells. So this case is what you should write your config files for. This means\u00a0putting most of your stuff in\u00a0<tt>~\/.bashrc<\/tt>, having exactly one of<tt>~\/.bash_profile<\/tt>,\u00a0<tt>~\/.bash_login<\/tt>, and\u00a0<tt>~\/.profile<\/tt>, and sourcing\u00a0<tt>~\/.bashrc<\/tt>\u00a0from it. If you have nothing that you specifically want to happen only for login shells, you can even symlink one of the three to<tt>~\/.bashrc<\/tt>. In fact, even if you do, it is probably a good idea to have only file, as follows:<\/p>\n<pre># Bash customisation file\r\n\r\n#General configuration starts: stuff that you always want executed\r\n\r\n#General configuration ends\r\n\r\nif [[ -n $PS1 ]]; then\r\n    : # These are executed only for interactive shells\r\n    echo \"interactive\"\r\nelse\r\n    : # Only for NON-interactive shells\r\nfi\r\n\r\nif shopt -q login_shell ; then\r\n    : # These are executed only when it is a login shell\r\n    echo \"login\"\r\nelse\r\n    : # Only when it is NOT a login shell\r\n    echo \"nonlogin\"\r\nfi<\/pre>\n<p>Almost everything should go in the \u201cgeneral configuration\u201d section. There might be some commands (those which produce output, etc.) that you only want executed when the shell is interactive, and not in scripts, which you can put in the first \u201cconditional section\u201d. I don\u2019t see any reason to use the rest. You can drop the \u201cecho\u201d lines, but keep the \u201c:\u201ds \u2014 they are commands which do nothing, and are needed if that section is empty.<\/p>\n<p>You then need to have only file, and you can call this\u00a0<tt>~\/.bashrc<\/tt>\u00a0and do\u00a0<tt>cd &amp;&amp; ln -s .bashrc .bash_profile<\/tt><\/p>\n<p>For zsh: [Note that zsh seems to read\u00a0<tt>~\/.profile<\/tt>\u00a0as well, if\u00a0<tt>~\/.zshrc<\/tt>\u00a0is not present.]<\/p>\n<pre>+----------------+-----------+-----------+------+\r\n|                |Interactive|Interactive|Script|\r\n|                |login      |non-login  |      |\r\n+----------------+-----------+-----------+------+\r\n|\/etc\/zshenv     |    A      |    A      |  A   |\r\n+----------------+-----------+-----------+------+\r\n|~\/.zshenv       |    B      |    B      |  B   |\r\n+----------------+-----------+-----------+------+\r\n|\/etc\/zprofile   |    C      |           |      |\r\n+----------------+-----------+-----------+------+\r\n|~\/.zprofile     |    D      |           |      |\r\n+----------------+-----------+-----------+------+\r\n|\/etc\/zshrc      |    E      |    C      |      |\r\n+----------------+-----------+-----------+------+\r\n|~\/.zshrc        |    F      |    D      |      |\r\n+----------------+-----------+-----------+------+\r\n|\/etc\/zlogin     |    G      |           |      |\r\n+----------------+-----------+-----------+------+\r\n|~\/.zlogin       |    H      |           |      |\r\n+----------------+-----------+-----------+------+\r\n|                |           |           |      |\r\n+----------------+-----------+-----------+------+\r\n|                |           |           |      |\r\n+----------------+-----------+-----------+------+\r\n|~\/.zlogout      |    I      |           |      |\r\n+----------------+-----------+-----------+------+\r\n|\/etc\/zlogout    |    J      |           |      |\r\n+----------------+-----------+-----------+------+<\/pre>\n<p>Moral:<br \/>\nFor bash, put stuff in ~\/.bashrc, and make ~\/.bash_profile source it.<br \/>\nFor zsh, put stuff in ~\/.zshrc, which is always executed.<\/p>\n<p>[Note: This is assuming you care only about interactive shells (shells you can type at). If further you ever use non-interactive shells (like &#8220;ssh [host] [command]\u201d which executes [command] on [host] and logs out immediately)\u00a0<em>and<\/em>\u00a0there is something you absolutely absolutely want executed first even for these cases (think carefully: they can interfere in strange ways and you may be able to do without them), then you can put such stuff in ~\/.zshenv. For bash, put them in a file and set the value of BASH_ENV to the filename.]<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>If you have ever put something in a file like\u00a0.bashrc\u00a0and had it not work, or are confused by why there are so [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-701","post","type-post","status-publish","format-standard","hentry","category-info-on-tech"],"_links":{"self":[{"href":"https:\/\/blog.designed79.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/701","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.designed79.co.uk\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.designed79.co.uk\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.designed79.co.uk\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.designed79.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=701"}],"version-history":[{"count":0,"href":"https:\/\/blog.designed79.co.uk\/index.php?rest_route=\/wp\/v2\/posts\/701\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.designed79.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=701"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.designed79.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=701"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.designed79.co.uk\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=701"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}