Ixxie Ixxie - 4 months ago 11
Bash Question

Getting bash script to update parent shell's Environment

I am attempting to write a

bash
command line tool that is usable immediately after installation, i.e. in the same shell as its installation script was called. Lets say
install-script.sh
(designed for Ubuntu) looks like:

# Get the script's absolute path:
pushd `dirname $0` > /dev/null
SCRIPTPATH=`pwd`
popd > /dev/null

# Add lines to bash.bashrc to export the environment variable:
echo "SCRIPT_HOME=${SCRIPTPATH}" >> /etc/bash.bashrc
echo "export SCRIPT_HOME" >> /etc/bash.bashrc

# Create a new command:
cp ${SCRIPTPATH}/newcomm /usr/bin
chmod a+x /usr/bin/newcomm


The idea is that the new command
newcomm
uses the
SCRIPT_HOME
environment variable to reference the main script - which is also in
SCRIPTPATH
:

exec "${SCRIPT_HOME}/main-script.sh"


Now, the updated
bash.bashrc
hasn't been loaded into the parent shell yet. Worse, I cannot
source
it from within the script - which is running in a child shell. Using
export
to change
SCRIPT_HOME
in the parent shell would at best be duct-taping the issue, but even this is impossible. Also note that the installation script needs to be run using
sudo
so it cannot be called from the parent shell using
source
.

It should be possible since package managers like
apt
do it. Is there a robust way to patch up my approach? How is this usually done, and is there a good guide to writing bash installers?

Answer

You can't. Neither can apt.

A package manager will instead just write required data/variables to a file, which are read either by the program itself, by a patch to the program, or by a wrapper.

Good examples can be found in /etc/default/*. These are files with variable definitions, and some even helpfully describe where they're sourced from:

$ cat /etc/default/ssh
# Default settings for openssh-server. This file is sourced by /bin/sh from
# /etc/init.d/ssh.

# Options to pass to sshd
SSHD_OPTS=

You'll notice that none of the options are set in your current shell after installing a package, since programs get them straight from the files in one way or another.