Brenton Horne Brenton Horne - 7 months ago 19
Bash Question

How to import shell functions from one file into another?

I have the shell script:

#!/bin/bash

export LD=$(lsb_release -sd | sed 's/"//g')
export ARCH=$(uname -m)
export VER=$(lsb_release -sr)

# Load the test function
/bin/bash -c "lib/test.sh"

echo $VER
DISTROS=('Arch'
'CentOS'
'Debian'
'Fedora'
'Gentoo')
for I in "${DISTROS[@]}"
do
i=$(echo $I | tr '[:upper:]' '[:lower:]') # convert distro string to lowercase
if [[ $LD == "$I"* ]]; then
./$ARCH/${i}.sh
fi
done


As you can see it should run a shell script, depending on which architecture and OS it is run on. It should first run the script
lib/test.sh
before it runs this architecture and OS-specific script. This is
lib/test.sh
:

#!/bin/bash

function comex {
which $1 >/dev/null 2>&1
}


and when I run it on x86_64 Arch Linux with this
x86_64/arch.sh
script:

#!/bin/bash

if comex atom; then
printf "Atom is already installed!"
elif comex git; then
printf "Git is installed!"
fi


it returned the output:

rolling
./x86_64/arch.sh: line 3: comex: command not found
./x86_64/arch.sh: line 5: comex: command not found


so clearly the
comex
shell function is not correctly loaded by the time the
x86_64/arch.sh
script is run. Hence I am confused and wondering what I need to do in order to correctly define the
comex
function such that it is correctly loaded in this architecture- and OS-dependent final script.

I have already tried using
. "lib/test.sh"
instead of
/bin/bash -c "lib/test.sh"
and I received the exact same error. I have also tried adding
. "lib/test.sh"
to the loop, just before the
./$ARCH/${i}.sh
line. This too failed, returning the same error.

Answer

Brief answer: you need to import your functions using . or source instead of bash -c:

# Load the test function
source "lib/test.sh"

Longer answer: when you call script with bash -c, a child process is created. This child process sees all exported variables (including functions) from parent process. But not vice versa. So, your script will never see comex function. Instead you need to include script code directly in current script and you do so by using . or source commands.


Part 2. After you "sourced" lib/test.sh, your main script is able to use comex function. But arch scripts won't see this function because it is not exported to them. Your need to export -f comex:

#!/bin/bash

function comex {
  which $1 >/dev/null 2>&1
}
export -f comex
Comments