I have a script with some logic to check if the script is being run in interactive mode or not. Both bashrc and bash_profile contain the same environment variables I exported. I want to load these when running the script either interactively or via cron as they are used for if/then statements and case statements later in the script:

if [[ $- == *i* ]]; then
   source ~/.bash_profile
   source ~/.bashrc

When I test interactively however, it seems this condition does not work and the "else" condition is used. This does not load the vars since the logic in bashrc detects the script is being run interactively. Do I have a gross misunderstanding of the how these files are supposed to behave?

  • 1
    When you run a script the script runs in a new subshell and that shell is not interactive, so you can't "run a script interactively" (aside from sourcing it or with bash -i). Also, in your interactive session both bash_profile and bashrc will already be sourced.
    – jesse_b
    Jun 1, 2022 at 19:27
  • 2
    The shell running a script is never interactive unless you force it to be with bash -i. If your variables are exported in the session you start your script from, they should already be available in your script.
    – Kusalananda
    Jun 1, 2022 at 19:29
  • To add more context, I have an init script that a user runs to add these variables to bashrc and bash_profile, but if this is the first time run, my logic to check the variables are not empty - i.e. [ ! -z "$var1"] will always fail. Perhaps I am better off using grep to check the physical files.
    – Jeff Sani
    Jun 1, 2022 at 20:03
  • 1
    Bash reads .bashrc on interactive shells, and it's commonly used for setting stuff that matters mostly (or only) in interactive use, like the prompt and aliases etc. Reading it from a non-interactive shell seems a bit odd.
    – ilkkachu
    Jun 1, 2022 at 20:09
  • 1
    If all you want is to have certain variables available to the script, where ever it runs, why not just make ~/mytool.rc (or such) and then source that from the script?
    – ilkkachu
    Jun 1, 2022 at 20:10

1 Answer 1


This might be useful:

if [[ $- == *i* ]]; then
#   source ~/.bash_profile
   echo 'this script is interactive; $- is equal to *i*'
#   source ~/.bashrc
echo 'this script is not interactive; $- is NOT equal to *i*'

The output will always be the else condition because a script runs in a subshell by default. You can run the script interactively by changing the shebang slightly:

FROM: #!/bin/bash

TO: #!/bin/bash -i

You must log in to answer this question.

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