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.

  • 1
    Make a shellscript named bar. – Ipor Sircer Nov 21 '18 at 8: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 9: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 9:35
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 9:35
  • @Bananach From there = from the environment. – Tomasz Nov 21 '18 at 9: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 9: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. – Tomasz Nov 21 '18 at 9: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 9:51

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.