Is it possible to source a file in bash, but skipping specific functions?

9,188

Solution 1

In a function definition foo () { … }, if foo is an alias, it is expanded. This can sometimes be a problem, but here it helps. Alias foo to some other name before sourcing the file, and you'll be defining a different function. In bash, alias expansion is off by default in non-interactive shells, so you need to turn it on with shopt -s expand_aliases.

If sourced.sh contains

foo () {
  echo "foo from sourced.sh"
}

then you use it this way

foo () {
  echo "old foo"
}
shopt -s expand_aliases   # necessary in bash; just skip in ash/ksh/zsh
alias foo=do_not_define_foo
. sourced.sh
unalias foo; unset -f do_not_define_foo
foo

then you get old foo. Note that the sourced file must use the foo () { … } function definition syntax, not function foo { … }, because the function keyword would block alias expansion.

Solution 2

Not exactly, however, you can override the test() function. The last function definition always takes precedence. So if you source a file that has test() then define a function with the same name after that, the latter function will override the one that was sourced. I take advantage of this to provide some object-orientedness in some of my scripts.

Example:

bash_functions.sh:

test(){
    echo "This is the test function from bash_functions."
}
test2(){
    echo "This is the test2 function from bash_functions."
}

scripty_scripterson.sh

test2(){
    #this is thrown in just to show what happens in
    #the other direction
    echo "This is the test2 function from scripty."
}

source bash_functions.sh

test1(){
    echo "This is the test1 function from scripty."
}

test1
test2

At the command line:

$ ./scripty_scripterson.sh 
This is the test1 function from scripty.
This is the test2 function from bash_functions.

Solution 3

You may create a temp-file, read it in, and delete it afterwards. To delete function 'test', I assume here that there is no '}' inside the function.

sed '/test()/,/}/d' testrc > ./tmprc && source ./tmprc && rm tmprc
Share:
9,188

Related videos on Youtube

Somebody still uses you MS-DOS
Author by

Somebody still uses you MS-DOS

Updated on September 17, 2022

Comments

  • Somebody still uses you MS-DOS
    Somebody still uses you MS-DOS over 1 year

    Suppose I have bash_functions.sh:

    function test(){
    }
    
    function test2(){
    }
    

    And in my ~/.bashrc I do:

    source ~/bash_functions.sh
    

    Is it possible to, when sourcing it, avoid sourcing a specific function? I mean, source everything in bash_functions.sh, except for test?

    • Alen Milakovic
      Alen Milakovic about 13 years
      @Somebody: Perhaps you could elaborate on your use case? What are you trying to do here?
    • Somebody still uses you MS-DOS
      Somebody still uses you MS-DOS about 13 years
      Sometimes you're using bash_functions.sh from someone, and want everything there's there except for a few functions that you already have defined in your own files and don't want them overriden.
    • Alen Milakovic
      Alen Milakovic about 13 years
      @Somebody: couldn't you just comment out the ones you don't want?
    • Somebody still uses you MS-DOS
      Somebody still uses you MS-DOS about 13 years
      @Faheem Mitha: this becomes unpractical over time if you use a bash_functions.sh that is versioned somewhere, and always do a checkout/pull from it.
    • Alen Milakovic
      Alen Milakovic about 13 years
      @Somebody: Ok. I see. I guess keeping your diffs local and merging with upstream is not an option then?
  • Somebody still uses you MS-DOS
    Somebody still uses you MS-DOS about 13 years
    I'm already doing this approach. :) But somehow it seens wrong to me, and in my use case, I have to soure my files, source the external bash_functions.sh and again source my files (since I use some functions from my files when sourcing bash_functions.sh)
  • Somebody still uses you MS-DOS
    Somebody still uses you MS-DOS about 13 years
    This seems to be an interesting approach, but I need the sourced scripts to be in the same foo () { ... } definition, right? I was thinking about putting all function names I didn't want to source in an array, and somehow "source" receive it and don't source them. Well, I think it's not going to be possible. Interesting hack, anyways!
  • Gilles 'SO- stop being evil'
    Gilles 'SO- stop being evil' about 13 years
    @Somebody: I don't understand your comment. The function definitions need to be in the portable foo () form and not in the ksh extension function foo form, but other than that you can effectively re-route any number of function definitions.