0

In zsh, a subshell created via parentheses can have an rcfile sourced to use commands which may be aliases, only available when specific directories are added to PATH, etc.:

~ » /bin/zsh -c "workon"
zsh:1: command not found: workon
------------------------------------------------------------
~ » /bin/zsh -c "source ~/.zshrc; workon"
env1
env2
env3
... (expected output)

However, the same is not true with bash:

~ » /bin/bash -c "workon"
/bin/bash: workon: command not found
------------------------------------------------------------
~ » /bin/bash -c "source ~/.bashrc; workon"
/bin/bash: workon: command not found
------------------------------------------------------------
~ » bash
sean@helium:~$ workon
env1
env2
env3
... (expected output)

Is there any way a bash subshell can source an rcfile?


To get a head-start on "X-Y problem" responses, this is for a script called in:

#!/bin/zsh
(source ~/.zshrc; cd $1; ${@:2})

I have a directory full of projects (using git) where I often forget if I have left anything uncommitted, so in allows me to quickly write $ in ProjectDir/ git status, rather than $ (cd ProjectDir; git status) (the former feels easier to type than the latter).

Preferably, I would like this script usable with bash (which is why I ask, even though it works currently with zsh).

5
  • The standard answer is to use exported functions instead of aliases, eg workon() { ...; }; export workon. Alternatively, make workon a script in one of the directories in $PATH.
    – AFH
    May 15, 2018 at 22:03
  • @AFH workon is actually an exported function, part of a Python package called virtualenvwrapper, my apologies for mislabeling it an alias. May 15, 2018 at 22:05
  • I think you don't need (…) in your in script (if you run it in bash). May 15, 2018 at 22:07
  • "Preferably, I would like this script usable with bash" – This I don't understand. You can run in from within bash if your $PATH is right, regardless of the script shebang. If it works when interpreted by zsh, why do you need to change it? May 15, 2018 at 22:12
  • I apologise: I omitted -f from the export in my definition of workon - it should have been workon() { ...; }; export -f workon. Exported functions should work in any subshell, so workon ought to be found without needing to run ~/.bashrc beforehand (PATH is exported). With this or an equivalent definition, bash -c workon should be sufficient, though I don't see why you would use bash -c at all. By the way, you do not need the brackets around the second line of in, since scripts run in a subshell (unless invoked with source), and you don't need a further level of subshell.
    – AFH
    May 15, 2018 at 23:10

1 Answer 1

1

In my Kubuntu the first thing .bashrc does is this:

# If not running interactively, don't do anything
case $- in
    *i*) ;;
      *) return;;
esac

I guess your .bashrc is similar. This is why /bin/bash -c "source ~/.bashrc; …" "doesn't" source. If you used bash -i -c … then .bashrc would be sourced automatically and your source would parse it unnecessarily for the second time.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.