如何将shell函数从一个文件导入另一个文件?

BH2*_*017 5 shell import function

我有shell脚本:

#!/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
Run Code Online (Sandbox Code Playgroud)

如您所见,它应该运行一个 shell 脚本,具体取决于它运行的架构和操作系统。它应该先运行脚本,lib/test.sh然后再运行此体系结构和特定于操作系统的脚本。这是lib/test.sh

#!/bin/bash

function comex {
  which $1 >/dev/null 2>&1
}
Run Code Online (Sandbox Code Playgroud)

当我使用这个x86_64/arch.sh脚本在 x86_64 Arch Linux 上运行它时:

#!/bin/bash

if comex atom; then
  printf "Atom is already installed!"
elif comex git; then
  printf "Git is installed!"
fi
Run Code Online (Sandbox Code Playgroud)

它返回了输出:

rolling
./x86_64/arch.sh: line 3: comex: command not found
./x86_64/arch.sh: line 5: comex: command not found
Run Code Online (Sandbox Code Playgroud)

很明显,comexx86_64/arch.sh脚本运行时,shell 函数没有正确加载。因此,我很困惑,想知道我需要做什么才能正确定义comex函数,以便在这个依赖于体系结构和操作系统的最终脚本中正确加载它。

我已经尝试使用. "lib/test.sh"而不是,/bin/bash -c "lib/test.sh"我收到了完全相同的错误。我也尝试添加. "lib/test.sh"到循环中,就在该./$ARCH/${i}.sh行之前。这也失败了,返回相同的错误。

gud*_*dok 10

简要回答:您需要使用.source而不是导入您的函数bash -c

# Load the test function
source "lib/test.sh"
Run Code Online (Sandbox Code Playgroud)

更长的答案:当您使用 调用脚本时bash -c,会创建一个子进程。这个子进程可以看到所有从父进程导出的变量(包括函数)。但反之则不然。因此,您的脚本永远不会看到comex功能。相反,您需要直接在当前脚本中包含脚本代码,并通过使用.source命令来实现。


第 2 部分。“sourced”之后lib/test.sh,您的主脚本就可以使用comex函数了。但是 arch 脚本不会看到这个函数,因为它没有导出给它们。您需要export -f comex

#!/bin/bash

function comex {
  which $1 >/dev/null 2>&1
}
export -f comex
Run Code Online (Sandbox Code Playgroud)