Some platforms come with a ~/.bashrc
that has a conditional at the top that explicitly stops processing if the shell is found to be non-interactive - even though bash
only automatically sources ~/.bashrc
in interactive (non-login) sessions anyway.
For example, on Ubuntu 18.04:
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
A similar test, seen in /etc/bash.bashrc
on the same platform:
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
If this is the case, sourcing ~/.bashrc
from a script will have no effect, because scripts run in non-interactive shells by default.
Your options are:
Either: deactivate the conditional in ~/.bashrc
Or: Try to to emulate an interactive shell before invoking source ~/.bashrc
.
The specific emulation needed depends on the specifics of the conditional, but there are two likely approaches; you may have to employ them both if you don't know ahead of time which conditional you'll encounter:
set -i
temporarily to make $-
contain i
, indicating an interactive shell.
- If you know the contents of the line that performs the interactivity test, filter it out of the
~/.bashrc
using grep
, and then source the result with eval
(the latter should generally be avoided, but it in this case effectively provides the same functionality as sourcing).
Note that making sure that environment variable PS1
has a value is not enough, because Bash actively resets it in non-interactive shells - see this answer for background information.
eval "$(grep -vFx '[ -z "$PS1" ] && return' ~/.bashrc)"
Alternatively, if you control how your own script is invoked, you can invoke it with
bash -i script
.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…