56

Maybe I am looking at this the wrong way.. But here I what I am trying to do. Do most of my work with Java but just switched to a unix (bash) environment. I am doing this:

[~/Desktop/bashPlay]% cat myFunc
#!/bin/bash

ls2(){
        echo "Hello World"
}

ls3(){
        echo "Testing"
}

echo "this is a test"   
ls2 # this calls a function

[~/Desktop/bashPlay]% myFunc
this is a test
Hello World

But I have two functions in my file and I want to be able to call them separately from the command line. Ie: myFunc.ls2() or even just ls2. I know that I can add the functions to my .bashrc file but is there any other way that I can execute these functions without adding them to my .bashrc?

Hennes
  • 65,142

4 Answers4

44

One way to do this, that involves a bit more typing, is via the source command. To call a function from myFunc you could use source myFunc; ls2 and it would output Hello World.

So for example, I have a file called say.sh:

#!/bin/bash

function talk()
{
        echo "hi!"
}

now I want to call it's talk() function from the command line:

[john@awesome ~]$ source say.sh; talk
hi!

to call it from another bash script:

#!/bin/bash
source say.sh
talk

You can also put each in a separate script and add them in a directory which is in your PATH variable.

so for example, in one script called hello you'd have:

#!/bin/bash
echo "Hello World"

now put it in one of the directories in your PATH, which you can view by running echo $PATH. You can add another directory to your PATH if you'd like or use an existing one. Once you've copied the file there, make it executable with chmod +x filename.

15

If you are like me, you dont want to clutter your environment with functions. You also have a group of functions that belong together in terms of what they do, so putting them in the same script file makes sense. (I know that a folder with multiple files could serve the same purpose). Here is a possible solution that allows you to call a specific function in the script:

$ cat functions.sh    
#!/bin/bash

ls2() {
        echo "Hello World"
}

ls3() {
        echo "Testing $*"
}

# the next line calls the function passed as the first parameter to the script.
# the remaining script arguments can be passed to this function.

$1 $2 $3 $4 $5 

$ ./functions.sh ls2    
Hello World   
$ ./functions.sh ls3    
Testing     
$ ./functions.sh ls3 first_arg    
Testing first_arg    
$
  • 2
    I like this a lot more than source since it can handle having two functions of the same name in two different sh files. I refined it to handle an arbitrary number of parameters by replacing $1 $2 $3 $4 $5 with FUNC_CALL=$1; shift; $FUNC_CALL "$@" – Chuck Wilbur Jan 29 '18 at 19:53
  • 2
    @ChuckWilbur: Why jump through hoops?  Just change the last line to "$@". P.S. Your approach is actually wrong; the last part should be "$FUNC_CALL" "$@"  (i.e., $FUNC_CALL should be in quotes). – Scott - Слава Україні Apr 20 '18 at 02:48
  • What is "$FUNC_CALL"? – ctrl-alt-delor Jul 08 '19 at 08:41
7

Another approach would be to create a script called functions.sh ( in the ~/bin directory for example) .

In this script, you add all your personal function definitions (let's say every time you add a function you add it to this file...)

Finally you just have to add the source ~/bin/functions.sh line to your .bashrc file. This way you will be able to call them from the command line, your .bashrc will stay clean, and you will have a specific place for your personal functions.

Gareth
  • 18,809
Debugger
  • 291
1

The dot operator or source builtin in bash is analogous to the import statement in Java.

You can read more about the dot operator or the source builtin.

eleven81
  • 15,614
  • Sometimes, If you are inside a script, and want to call a function, it can be handy to `printf "$(functionName)" – MarkHu Sep 09 '22 at 18:00