1

I am trying to source specific function of a bash file. Please find below simplified loadfun.sh :-

function a(){
        echo "This is a"
}

function b(){
        echo "This is b"
}

function load(){
        echo "exporting $1"
        export -f $1
}

$@

Also, please find below execution sequence of commands :-

$cat loadfun.sh                             
function a(){                               
        echo "This is a"                    
}                                           

function b(){                               
        echo "This is b"                    
}                                           

function load(){                            
        echo "exporting $1"                 
        export -f $1                        
}                                           

$@                                          
$                                           
$                                           
$                                           
$sh loadfun.sh a                            
This is a                                   
$                                           
$                                           
$a                                          
bash: a: command not found                  
$                                           
$                                           
$sh loadfun.sh load a                       
exporting a                                 
$                                           
$                                           
$                                           
$a                                          
bash: a: command not found                  
$                                           

I am not sure why

export -f a

is not exporting function a.

mogli
  • 1,549
  • 4
  • 29
  • 57
  • 2
    When you run `sh command...` it creates a new child process and run `sh` in it. I think the export works for this child process, but not for your shell. This seems relevant: http://stackoverflow.com/questions/16618071/can-i-export-a-variable-to-the-environment-from-a-bash-script-without-sourcing-i – selalerer May 14 '17 at 14:49
  • 2
    Export only makes things available for child processes. A child process cannot change the parents environment. – 123 May 14 '17 at 14:50
  • okies. But, is there any way to export specific functions of a bash script. – mogli May 14 '17 at 14:59
  • . loadfun.sh loads all the functions of bash script, but i only want specific methods to export. – mogli May 14 '17 at 14:59
  • 1
    (and `sh yourscript` isn't even running bash -- it's running `/bin/sh`, which isn't guaranteed to have function export support *at all*; so even if the process you expected to *use* the exported function in **was** a child of `sh yourscript`, it still wouldn't be guaranteed to be present). – Charles Duffy May 14 '17 at 15:30
  • 1
    The important thing to understand, though, is that `export` does the same thing with a variable as a function -- it makes that variable *available to child processes of the current shell*. Not parents -- ie. the thing that started the shell -- but rather, processes *started by* the shell. – Charles Duffy May 14 '17 at 15:34
  • 1
    (As another aside -- bare `$@` has the exact same bugs as just running `$*`. Always use `"$@"` instead; this is an issue that http://shellcheck.net/ will catch). – Charles Duffy May 14 '17 at 15:35
  • @Charles Duffy :Is there any other way to export specific functions of a bash script. – mogli May 14 '17 at 16:42
  • Maybe we need to be clear about what you mean by the word "export". Do you really mean in it in its technical sense, of putting a function into an environment variable, or do you mean something else? – Charles Duffy May 14 '17 at 17:30
  • i want to specifically make method a (or b) available to call from shell (but not both). – mogli May 14 '17 at 17:36
  • if i do . loadfun.sh, that will make all the functions available to call from shell. – mogli May 14 '17 at 17:37
  • Right, and that's exactly what you should expect. `export` doesn't change which variables are available to the immediate process; it changes what's available to its children. – Charles Duffy May 14 '17 at 18:04

2 Answers2

1

If you only want to set specific functions whilst sourcing the file then you could use a case statement

case $1 in   
a)
        a(){
                echo "This is a"
        }
;;
b)
        b(){
                echo "This is b"
        }
;;
*)
        echo error message
;;
esac

And call the script with

. ./script [function to export]
123
  • 10,778
  • 2
  • 22
  • 45
  • Eh? The function isn't being exported (made available to child processes) at all here; it's only defined into the immediate shell. – Charles Duffy May 14 '17 at 15:33
  • 1
    @CharlesDuffy From the comments and title, I assumed thats what they actually wanted. – 123 May 14 '17 at 15:33
  • I am sorry if the title or comment is misleading. i want function a to be exported not method a. – mogli May 14 '17 at 16:29
  • 2
    @mogli: If by "export" you mean "make available in the current shell" (selectively, on demand), then that's exactly what this answer provides. True _exporting_ of functions - so they become part of the environment of child processes - is a Bash-specific concept, and only child processes that are also Bash shells will honor them. – mklement0 May 14 '17 at 17:21
0

Source your script rather than executing it, so that the definitions and the export take place in your current shell:

source loadfun.sh a

As an aside -- the .sh extension is misleading; since this uses bash-only functionality, it should be named loadfun.bash. (Using extensions is frowned on in general for executable scripts, but since this is intended to be loaded as a library, an extension is appropriate).

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441