0

I'm trying to run a non-interactive command within a login shell (using su - or sudo -i) but couldn't make it work so far.

Within ~/.bashrc I have sourced a script which sets all variables my application needs. When I do an interactive login su - username I can see all my variables there and if I run my application it works fine. However, when I try to execute my application by using su - username -c 'command' the necessary variables are not being set. In other words, it seems su - is incompatible with -c option. The same happens with sudo -i -u user command.

I have searched tons of questions but couldn't find an answer to this specific behavior.

According to bash man pages:

When bash is invoked as an interactive login shell, or as a non-interactive
shell with the `--login` option, it first reads and executes commands from the
file `/etc/profile`, if that file exists. After reading that file, it looks for
`~/.bash_profile`, `~/.bash_login`, and `~/.profile`, in that order, and reads and
executes commands from the first one that exists and is readable. The
`--noprofile` option may be used when the shell is started to inhibit this
behavior.

The above behavior is not working as ~/.profile executes ~/.bashrc and it in turn sources the script which sets all variables.

How can I execute a non-interactive login shell?

Thank you

Félicien
  • 1,183
felima
  • 1
  • Might be helpful: https://askubuntu.com/questions/879364/differentiate-interactive-login-and-non-interactive-non-login-shell – d a i s y Feb 28 '18 at 08:53
  • Thank you for the reference @daisy, very good explanation. My understanding about the behavior of a login shell (bash) is that it to goes through /etc/profile, ~/.bash_profile, ~/.bash_login, and ~/.profile and a non-interactive shell is when a script os executable is run directly by the shell (no prompt) as "su -c" does. So I was wondering that "su - (with -c) option would execute a non-interactive login shell, but it seems it doesn't. Is my understanding incorrect? – felima Feb 28 '18 at 09:37
  • Does su - username -c 'bash -l -c command' work? With a login-shell (bash -l) in-between? – PerlDuck Feb 28 '18 at 10:14
  • Thank you @PerlDuck it worked indeed. Got focused on understanding about su/sudo behavior and this great workaround never came to mind. – felima Mar 01 '18 at 21:37

1 Answers1

0

You can source the variable file in your script. In your script, include the following line before referencing any of the variables:

source full_path_to_variable_file

This will read your variables into the script's session. You must use the full literal path (no aliases), starting with the root directory'/', so for example if your home directory's .bash_aliases defines your variables:

source /home/felima/.bash_aliases

On the command line '.' has the same effect

. ~/.bash_aliases

But in scripts using 'source' is more clear.

  • Hi @StephenBoston I failed to mention that application executable is started by a script in /etc/init.d (which cannot be changed due to support requirements) and it expects to have all variables set by the user environment. So the script which sets all variables was added to the last line of ~/.bashrc as you mentioned "source full_path_of_script_which-sets_all_vars", so I understand ~/.bashrc is not being run on non-interactive login. So the question is how we make the non-interactive shell with the --login option work (as described by the bash man page)? – felima Feb 28 '18 at 08:57
  • Ah! What a nuisance. I am sorry. So you do not have write access to the script. It is a shared file? Then does the script work for other users, in other contexts? – Stephen Boston Feb 28 '18 at 10:23
  • Yes, I can't change them. Anyway, @PerlDuck suggestion worked like a charm. Thank you for your comments. – felima Mar 01 '18 at 21:40