Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 627
Josh Pinto Avatar asked Apr 24 '16 23:04

Josh Pinto


1 Answers

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
like image 59
gudok Avatar answered Nov 15 '22 06:11

gudok