28

I'm looking for a way to nullify the undesirable behaviour of some installers that append code to .bashrc to force-load their environment automatically. The problem cropped-up a few times, mostly with Conda, and in some cases the user ended-up with a broken account that prevented them from logging in anymore.

I tried to add an unclosed here-document at the end of .bashrc, like this:

# .bashrc

#...

: <<'__END__'

Which works, but generates parsing errors annoying warnings.

What would be a clean way to do that (without making the .bashrc readonly)?

1
  • 1
    When you discover a script that auto-appends to your startup files, the appropriate thing to do is to email the maintainer of that script and inform them that their package is broken. Commented Apr 15, 2022 at 18:00

3 Answers 3

46

If you end your .bashrc with

return 0

Bash will ignore any lines added after that, since .bashrc is handled like a sourced script:

return may also be used to terminate execution of a script being executed with the . (source) builtin, returning either n or the exit status of the last command executed within the script as the exit status of the script.

(exit 0 causes the shell to exit, which isn’t what you want.)

0
6

While Stephen's trick definitely works, the fundamental problem here is that the installer is run with privileges that allow it to modify your .bashrc. If it's doing that, it could be making all sorts of unwanted changes to other things that might cause broken interactions or be outright malicious (ranging from phone-home spyware shipped intentionally to outright malware from a supply chain compromise or inside threat).

The right solution is not to run "installers" with any privileges. Instead you can run them inside a throwaway container or user account, then copy only the wanted files out of the "staging" environment to the environment you want to use them in. I do something like this with a tool I wrote, usand, which uses unshare to make new user and mount namespaces that block network access and write access to files outside of the current directory and everything under it. While it's not presently very flexible, many of the same concepts can be applied to do something suited to your particular workflow.

7
  • 18
    Why are you using the software at all if you don't trust the installer?
    – eesiraed
    Commented Apr 13, 2022 at 23:39
  • 12
    @B.Kaatz This answer seems to be talking about running an installer in a sandboxed environment and then moving the resulting files out of the sandbox. This doesn't make sense since a malicious installer can just generate malicious executables. As far as I can tell, this isn't about compiling software from source because you don't trust prebuilt binaries.
    – eesiraed
    Commented Apr 14, 2022 at 7:12
  • 4
    @eesiraed: In practice, commercial or other non-free software that installs and changes crap you don't want tends to do it via an installer, not by having the main program redo it every time. Obviously this doesn't defend against truly malicious attacks, but may help against some unscrupulous installers for otherwise-ok software. IDK, I very rarely install anything non-free, and haven't for quite a while. Commented Apr 14, 2022 at 10:23
  • 1
    @eesiraed: If you're concerned about the executables installed themselves being malicious, you can use a similar sandboxing approach for them. That's actually part of my normal workflow with usand. I run them in an isolated directory tree with just the data they're supposed to operate on, and no network access. If they need GUI it's more difficult but a setup with a proxy X display is possible (xnest or similar). But if your main concern is the installer doing stupid stuff, just doing this at install time suffices. Commented Apr 14, 2022 at 12:07
  • 1
    @R..GitHubSTOPHELPINGICE I'm interested in your isolation workflow. Is there a way we can chat somewhere else? Currently I manually read through the installer to check for malicious code and unwanted behaviour, but that's time consuming.
    – studog
    Commented Apr 14, 2022 at 20:06
2

Using return prevents the extra content from being executed, but it doesn't prevent the file from filling up with all that junk over time. It also creates the problem where you accidentally add something below the return and have to figure out why your changes aren't taking effect.

What I've done before is to add a line at the end like # END_ACTUAL_CONTENT. I created a script that would locate this marker and delete everything located after it, and set that script to run periodically.

You can also use functions like this to neutralize those annoying installers:

function bashrc_save() { cp -f ~/.bashrc ~/.bashrc.backup }
function bashrc_restore() { mv -f ~/.bashrc.backup ~/.bashrc }

Install your program with bashrc_save; ./install.sh; bashrc_restore and any changes that it makes to your .bashrc file will be automatically rolled back.

I currently take this a step farther. I store my .bashrc file (as well as a bunch of other configuration files) in a separate directory ~/.configfiles, and I create symlinks to the locations where these files normally reside. The contents of that folder are in a git repository. I do that to make it easy to synchronize between systems, but it has the added benefit of being able to use git diff to see all the changes an installer has made and to use git restore to revert them en masse.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .