Sometimes you might need to debug a failure somewhere in the deepest bowels of a system. Particularly a complicated shell script or a build system, where execution is very much affected by the state of and location in the filesystem and environment variables. In these cases getting an interactive shell in the exact problematic environment might be very useful.
With Bash scripts that run interactively it might be sufficient to just put this command at the desired “breakpoint”:
bash -rcfile <(set)
This starts an interactive shell with the invoking shell’s functions and variables. If you need variable attributes (including “export” status) and various shell options transferred as well, then this might do the job:
bash -rcfile <(declare -p; declare -f; set +o; shopt -p)
However, sometimes the script or a build system might have no access to a
screen comes to the rescue. This command:
screen -D -m
will start a detached screen session and will wait until it is finished, so
that you can connect to it with
screen -r and get your interactive shell.
You can combine this and either of the previous approaches, but shell state
will need to be passed via a temporary file or a named pipe, as process
substitution’s file descriptors won’t be inherited by the shell inside
set >tmp_rcfile; screen -D -m bash -rcfile tmp_rcfile
Note though, that
screen is a setuid executable, so it removes some
variables from the environment, such as LD_PRELOAD and LD_LIBRARY_PATH, for
safety. You will need to pass them explicitly. For example, like this:
screen -D -m bash -c "LD_PRELOAD='$LD_PRELOAD' bash"