3

I am trying to make a working example for logrotate, and to help me through this I figured it was a good idea to turn stderr to red.

Through some reading, I came upon stderred, which I meant to adopt. I downloaded it, make'd it and it works nicely for the user.

The red formatting however is lost when the command is summoned through sudo. Specifically, red formatting is visible with this command:

$ /usr/games/cowsay -f fudge Yo
cowsay: Could not find fudge cowfile!

but not with this command:

$ sudo /usr/games/cowsay -f fudge Yo
cowsay: Could not find fudge cowfile!

I have tried editing /root/.bashrc to contain:

export LD_PRELOAD="/home/user/path/to/stderred/build/libstderred.so${LD_PRELOAD:+:$LD_PRELOAD}"

but that apparently does not make it work. What am I missing?

Tfb9
  • 681
  • 4
  • 13
  • 33

1 Answers1

3

This is because sudo command runs command in its own subshell, started by root. This means that your ~/.bashrc file is ignored. It also means that any environment variables defined in the parent shell (such as the LD_PRELOAD you are setting in ~/.bashrc) are not passed to the sudo shell. This is explained in man sudoers:

By default, the env_reset option is enabled. This causes commands to be executed with a new, minimal environment. On AIX (and Linux systems without PAM), the environment is initialized with the contents of the /etc/environment file. The new environment contains the TERM, PATH, HOME, MAIL, SHELL, LOGNAME, USER, USERNAME and SUDO_* variables in addition to variables from the invoking process permitted by the env_check and env_keep options. This is effectively a whitelist for environment variables.

I couldn't get the env_keep option to work here, I don't know why. The best way I could find of passing the variable to sudo is to create a file (for example /path/to/foo) with this line:

LD_PRELOAD="/home/terdon/Setups/stderred/build/libstderred.so"

Then, run sudo visudo and add this line:

Defaults        env_file="/path/to/foo"

That will cause sudo to read /path/to/foo and add any variable definitions there to its environment.

terdon
  • 100,812
  • Thanks, I'll give these options a shot. Did you mean: (such as the LD_PRELOAD you are setting in /root/.bashrc)? – Tfb9 Dec 23 '15 at 23:59
  • On Ubuntu 15.10, I get the error >>> /etc/sudoers: erreur de syntaxe near line 13 <<< when quitting and saving after the call to sudo visudo – Tfb9 Dec 24 '15 at 00:10
  • @Tfb9 i) no, I meant ~/.bashrc which is where you were setting it. That shell (normal user) then calls sudo and the sudo doesn't inherit the variable. ii) Bon, t'as un erreur sur la ligne 13 donc. iii) you're welcome :) – terdon Dec 24 '15 at 00:50
  • i) Understood - but why didn't my edition of /root/.bashrc have any effect? ii) The line 13 error was exactly where I had added the env_keep line. iv) Seems like option 1 (ugliest) is not acceptable - I'm running into scary issues with a script of mine from .bashrc (a script that uses a pipe to w3m, which seems to go in error with this setup); symptoms are that for user on ssh, all text is red (even commands I type in) and in VNC I wasn't able to start a new gnome-terminal by clicking the icon. I am back at square I – Tfb9 Dec 24 '15 at 02:25
  • @Tfb9 i) See updated answer, I found a clean way of doing it! ii) root's .bashrc is not read by sudo. .bashrc is only read by non-login, interactive shells. AFAIK, sudo starts a non-interactive shell so none of the regular startup files will be read. iii) there must have been a syntax error then. It worked fine on my machine. iv) I'm not surprised. My original solution overwrote anything in LD_PRELOAD and, as I mentioned, that could cause problems. Sadly, /etc/environment only takes simple foo=bar assignments so there was no other choice. – terdon Dec 24 '15 at 09:04