Reputation: 1701
I have 2 shell scripts.
The second shell script contains following functions second.sh
func1
func2
The first.sh will call the second shell script with some parameters and will call func1 and func2 with some other parameters specific to that function.
Here is the example of what I am talking about
second.sh
val1=`echo $1`
val2=`echo $2`
function func1 {
fun=`echo $1`
book=`echo $2`
}
function func2 {
fun2=`echo $1`
book2=`echo $2`
}
first.sh
second.sh cricket football
func1 love horror
func2 ball mystery
How can I achieve it?
Upvotes: 167
Views: 215965
Reputation: 784958
You can refactor your second.sh
script like this:
func1 () {
fun="$1"
book="$2"
printf "func=%s,book=%s\n" "$fun" "$book"
}
func2 () {
fun2="$1"
book2="$2"
printf "func2=%s,book2=%s\n" "$fun2" "$book2"
}
And then call these functions from script first.sh
like this:
. ./second.sh
func1 love horror
func2 ball mystery
OUTPUT:
func=love,book=horror
func2=ball,book2=mystery
Upvotes: 231
Reputation: 948
This is a very old post, I am aware. However I found I could not source another file even though it was in the same directory.
line 3: ./functions.bash: No such file or directory
Then I remembered I already have in place a method for this exact situation because I import from an ini file. So here is my solution that allows me to run a program from anywhere (and apparently source files) without hardcoding the paths.
app="$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
source $app/functions.bash
I cannot take credit for this, its been a while and I can't recall where I got the line from otherwise I would credit them, but that's all I use to source files.
Upvotes: 1
Reputation: 576
second.sh
#!/bin/bash
function func1() {
fun="$1"
book="$2"
echo "$fun, $book\n"
}
function func2() {
fun2="$1"
book2="$2"
printf "$fun2, $book2\n"
}
first.sh
#!/bin/bash
source /absolute_path_to/second.sh
func1 love horror
func2 ball mystery
source
and .
(a period) are the same command.FILENAME
is not a full path to a file, the command will search for the file in the directories specified in the $PATH
environmental variable . If the file is not found in the $PATH
, the command will look for the file in the current directory.ARGUMENTS
are given, they will become positional parameters to the FILENAME
.FILENAME
exists, the source command exit code is 0
, otherwise, if the file is not found it will return 1
.Among these points the point to be focused on is the second
one, you actually need to provide a ABSOLUTE_PATH
to the file if you are using #!/bin/bash
, RELATIVE_PATH
just doesn't work if that is the case with you then my friend you just need to change the path to ABSOLUTE_FILE_PATH
.
Upvotes: 10
Reputation: 1
#vi function.sh
#!/bin/bash
f1() {
echo "Hello $name"
}
f2() {
echo "Enter your name: "
read name
f1
}
f2
#sh function.sh
Here function f2
will call function f1
Upvotes: -7
Reputation: 2072
The currenly accepted answer works only under important condition. Given...
/foo/bar/first.sh
:
function func1 {
echo "Hello $1"
}
and
/foo/bar/second.sh
:
#!/bin/bash
source ./first.sh
func1 World
this works only if the first.sh
is executed from within the same directory where the first.sh
is located. Ie. if the current working path of shell is /foo
, the attempt to run command
cd /foo
./bar/second.sh
prints error:
/foo/bar/second.sh: line 4: func1: command not found
That's because the source ./first.sh
is relative to current working path, not the path of the script. Hence one solution might be to utilize subshell and run
(cd /foo/bar; ./second.sh)
Given...
/foo/bar/first.sh
:
function func1 {
echo "Hello $1"
}
and
/foo/bar/second.sh
:
#!/bin/bash
source $(dirname "$0")/first.sh
func1 World
then
cd /foo
./bar/second.sh
prints
Hello World
$0
returns relative or absolute path to the executed scriptdirname
returns relative path to directory, where the $0 script exists $( dirname "$0" )
the dirname "$0"
command returns relative
path to directory of executed script, which is then used as argument for source
command /first.sh
just appends the name of imported shell script source
loads content of specified file into current
shellUpvotes: 69
Reputation: 1
If you define
#!/bin/bash
fun1(){
echo "Fun1 from file1 $1"
}
fun1 Hello
. file2
fun1 Hello
exit 0
in file1(chmod 750 file1) and file2
fun1(){
echo "Fun1 from file2 $1"
}
fun2(){
echo "Fun1 from file1 $1"
}
and run ./file2 you'll get Fun1 from file1 Hello Fun1 from file2 Hello Surprise!!! You overwrite fun1 in file1 with fun1 from file2... So as not to do so you must
declare -f pr_fun1=$fun1
. file2
unset -f fun1
fun1=$pr_fun1
unset -f pr_fun1
fun1 Hello
it's save your previous definition for fun1 and restore it with the previous name deleting not needed imported one. Every time you import functions from another file you may remember two aspects:
Upvotes: 0
Reputation: 311377
You can't directly call a function in another shell script.
You can move your function definitions into a separate file and then load them into your script using the .
command, like this:
. /path/to/functions.sh
This will interpret functions.sh
as if it's content were actually present in your file at this point. This is a common mechanism for implementing shared libraries of shell functions.
Upvotes: 104