2

/etc/profile can be invoked by sh and dash inside an interactive login mode. Is there any file in /etc directory to be invoked when they are in an interactive non-login mode?

bcan
  • 123
  • 6
  • 1
    What do you mean exactly by "can be invoked by `/etc/profile`"? It's usually the shell that invokes that file, not the other way around. Your shell's manual should tell you exactly what files are sourced by the shell in interactive and non-interactive modes. Note that `sh` may be implemented by any number of shells, so the manual to check is the manual for the shell that implements `sh`. – Kusalananda Sep 17 '18 at 14:11
  • I edited my question according to your comment. The problem I have with is the default `sh` which invoked by just typing `sh`, same for `dash`. I suppose they have files indicated by `ENV` variable (check here: https://unix.stackexchange.com/questions/38175/difference-between-login-shell-and-non-login-shell?noredirect=1&lq=1) but I dont know how to find it. – bcan Sep 17 '18 at 14:35
  • Simply `echo "$ENV"` in the shell would tell you that. Please notice that per the standard, `ENV` can also contain variables that are expanded by the shell -- eg. `ENV='/etc/shrc-$machine'` –  Sep 17 '18 at 14:45

2 Answers2

2

The dash shell (and sh if implemented by dash) reads /etc/profile when started as a login shell. Then it reads ~/.profile. The ~/.profile file may set and export the ENV environment variable. This variable should hold the path to a file that is sourced by non-login shells. This is usually done on a user-by-user basis, and not in any file in /etc.

From the dash manual (my emphasis):

If the environment variable ENV is set on entry to an interactive shell, or is set in the .profile of a login shell, the shell next reads commands from the file named in ENV. Therefore, a user should place commands that are to be executed only at login time in the .profile file, and commands that are executed for every interactive shell inside the ENV file. To set the ENV variable to some file, place the following line in your .profile of your home directory

ENV=$HOME/.shinit; export ENV

substituting for .shinit any filename you wish.

When calling sh or dash to create an interactive non-login shell session from some other shell or process, just make sure that ENV is set to the appropriate shell initialization file. This can be done from any Bourne-type shell using

ENV="$HOME/.shinit" sh

or

ENV="$HOME/.shinit" dash
Kusalananda
  • 320,670
  • 36
  • 633
  • 936
  • That only solves the case when a `sh` is called from a login `sh`. What if the running shell is ksh (or bash, or zsh …) and `sh` is called as an interactive shell? Should the environment ENV be present in all running shells then?. –  Sep 17 '18 at 20:13
  • @Isaac `ENV` does not need to be set in the environment of the calling shell to be set when invoking `sh` or `dash`. See the recent addition to the answer for how one may invoke `sh` or `dash` and set `ENV` at the same time. – Kusalananda Sep 17 '18 at 20:38
0

One more thing about these commands: they all invoke, /bin/sh (often the dash shell on unix-like systems) but they invoke it as a login shell, not an interactive shell. So the file pointed to by ENV will not get executed, only the hardwired /etc/profile and ~/.profile.

In order to get ENV read, it seems you must put "sh -i -c " in front of your shell commands and quote the command that follows the -c.

sh_command = 'sh -i -c "' + command + ' ' + args.join(' ') + '"'
env = { 'ENV' => Your.shellrc_file }
std_out, std_err, status = Open3.capture3(env, sh_command)

Then you suffer the very slight inefficiency of having the login shell invoke the interactive shell, but ENV will no longer be ignored. If you prefer bash, this also allows you to change sh->bash or ksh or zsh or fish, etc.

Daniel Doherty
  • 189
  • 1
  • 4