9

I'm trying to set environment variables for non-interactive non-login shell. I know bash reads the contents of ~/.bashrc before execute the command. In the beginning of the script there's a part:

*# If not running interactively, don't do anything

case $- in
*i*) ;;
  *) return;;
esac*

So I think if I add something above it, it will take effect no matter if the shell is interactive or not:

export VAR=something

# If not running interactively, don't do anything

case $- in
*i*) ;;
  *) return;;
esac

However it doesn't work :(. I want to avoid using $BASH_ENV because it messes up my xkb settings. I remapped some keys in /usr/share/X11/xkb/symbols/pc. And if I set $BASH_ENV, it will just loads the default keymap.

Trung Quan Vo
  • 359
  • 1
  • 3
  • 10
  • Why does setting `BASH_ENV` mess with your xkb settings? Are you setting it to a filename with code for changing your key layout? Have you tried not doing that? – that other guy Mar 10 '17 at 19:16
  • I set $BASH_ENV to a script that has a few "export" in order to have some default environment variables. There's nothing related to xkb in that – Trung Quan Vo Mar 10 '17 at 20:15
  • Sorry that I assumed incorrectly. XKB still works fine. The problem is with the ~/.xbindkeysrc. I have a line to run it in the rc.local file, and when BASH_ENV is set, that doesn't work. But I just want to know why adding export VAR=something doesn't work. – Trung Quan Vo Mar 10 '17 at 20:35
  • I tried to set a variable in ~/.bashrc and when using "ssh host script" the variable was available for use. Could you please detail your scenario more precisely. – czvtools Mar 10 '17 at 23:34
  • Well czvtools, you can read the https://www.gnu.org/software/bash/manual/html_node/Bash-Startup-Files.html, invoked non-interactively. I'm trying to execute a script when run the shell non-interactively by setting BASH_ENV. But it doesn't work. And I think my xbindkeys has been affected by a side effect – Trung Quan Vo Mar 11 '17 at 05:36
  • What do you set BASH_ENV to? – that other guy Mar 11 '17 at 05:55
  • The behavior is random as sometimes xbindkeys -p (the command to activate it) runs and sometimes doesn't. Also I get some "System detected warnings" when the computer starts as well. – Trung Quan Vo Mar 11 '17 at 05:57
  • it's a script is /mybin/bash.sh (with execution permission). – Trung Quan Vo Mar 11 '17 at 05:58
  • 3
    Ok. Solution for Ubuntu: set the variables in /etc/environment, and it works for all users and all types of shells ... If only I had known that in the beginning. – Trung Quan Vo Mar 11 '17 at 06:25
  • @TrungQuanVo please make your last comment as answer for this. – Krishna Oza Mar 08 '19 at 16:36
  • Also please make sure no env variables are filtered out by sudoers configuration. – Sunil Dias Apr 25 '19 at 15:04

2 Answers2

14

Solution for Ubuntu: set the variables in /etc/environment, and it works for all users and all types of shells.

Pika Supports Ukraine
  • 3,612
  • 10
  • 26
  • 42
Trung Quan Vo
  • 359
  • 1
  • 3
  • 10
  • 2
    So it's not possible to set user-specific environment variables for non-interactive shell? – wuarmin Apr 02 '19 at 14:32
  • perhaps that's a bit of an edge case wrt the question, but if you run bash in a ubuntu container, i.e. `docker run --rm -ti ubuntu:18.04 /bin/bash`, then /etc/environment is completely ignored. I'm not aware of a mode to have that file loaded up, other than using BASH_ENV – init_js Apr 10 '19 at 05:46
  • 1
    @wuarmin apparently the answer is BASH_ENV. Please check https://serverfault.com/a/593487/951855 – Ahmad Ismail Feb 10 '22 at 09:04
1

The details are somewhat platform-dependent. Bash Startup Files in the reference manual describes the default behavior of Bash itself; but you also need to take into account the behavior of your particular platform.

In general, $HOME/.bashrc is executed for non-interactive login shells, but no script can be guaranteed to run for a non-interactive non-login shell. You can force it by setting (and exporting!) BASH_ENV from a parent shell to the name of a script which you want to execute when a non-interactive shell is started.

Sometimes, an acceptable workaround is to run a script in a login shell, and trust that the non-interactive non-login script you run inherits whatever parameters you set in the login shell. This is what e.g. /etc/environment can do; but it does not force a piece of script to run at the time when a noninteractive shell is subsequently started (except of course if you use /etc/environment to set up BASH_ENV as described above).

tripleee
  • 175,061
  • 34
  • 275
  • 318