1

I have bash functions foo and bar in my ~/.bashrc.

Function foo calls an external command ext_command that itself takes as one of its arguments another command. I want to pass bar as that command, i.e. I'd want my .bashrc to look something like this:

bar() {
...
}
foo() {
 ext_command --invoke bar
} 

However, this doesn't work, because the external command, which is not a shell script, doesn't know bar. How can I solve this?

I was thinking to instead do

ext_command --invoke "bash -c 'bar'"

But the Bash in this invocation isn't run as an interactive shell, so it doesn't know bar either.

Hence, I believe one way to solve my problem would be to force Bash to be run as an interactive shell; unfortunately I don't know how to do that.

Another way that I would have thought should definitely work is to use

ext_command --invoke "bash -c 'source ~/.bashrc; bar'"

but for some reason this doesn't work and indeed simply running

bash -c 'source ~/.bashrc; bar'

in an interactive bash session gives

bash: bar: command not found

In any case, I don't like that solution, because I'd like foo to work no matter which file it is sourced from.

Bananach
  • 435
  • 4
  • 15
  • 1
    Make a shellscript named `bar`. – Ipor Sircer Nov 21 '18 at 08:48
  • @IporSircer I don't like the clutter. I am already using the same `~/.bashrc` on all the different machines I'm working on and don't want to have to install and update that additional script file on each. – Bananach Nov 21 '18 at 09:27
  • What is `ext_command`? What does it use `bar` for? Can it be made to read the output from `bar` or in some other way do what it's supposed to do without injecting shell code into it? – Kusalananda Nov 21 '18 at 09:35

1 Answers1

3

You generally have these ways to go:

  1. Rewrite the function to command, ie. a script on its own. A common practice is to keep a ~/bin directory and include it in your $PATH.
  2. Export the function to the environment and make the other shell get it from there. See Can I "export" functions in bash?
  3. Stick to bar being a sourcable function, but sourcing it from ~/.bashrc may not be the best solution. You might put it in its own file in ~/bin and source it from there. This would make things simple.
  4. If possible, feed the logic to the ext_command in your foo function somehow else, eg. through a here-doc.
  • 2. works perfectly. I don't even understand what 'make the other shell get it from there' means and it still works. I'm simply using `ext_command --invoke bar` – Bananach Nov 21 '18 at 09:35
  • @Bananach From there = from the environment. –  Nov 21 '18 at 09:37
  • Okay, but what is "the other shell" in your sentence? I'm perfectly happy, but just to be sure, is what I am doing now what you meant I should? If so, I simply don't understand in which way I am using "another shell" – Bananach Nov 21 '18 at 09:40
  • @Bananach Check `ext_command`. It must invoke another Bash, is a Bash script itself, or is something unusual that can import Bash functions from the environment. –  Nov 21 '18 at 09:45
  • It's a binary, `fzf` to be precise, and what I call `invoke` here is actually `preview`. It does seem to invoke another bash because if I don't `export -f bar` it says `/bin/bash: bar: command not found` in its preview window. I guess I lucked out then, since I didn't like any of the other options :) – Bananach Nov 21 '18 at 09:51