![如何将模块化 bash 脚本添加到“bin”?](https://linux22.com/image/153321/%E5%A6%82%E4%BD%95%E5%B0%86%E6%A8%A1%E5%9D%97%E5%8C%96%20bash%20%E8%84%9A%E6%9C%AC%E6%B7%BB%E5%8A%A0%E5%88%B0%E2%80%9Cbin%E2%80%9D%EF%BC%9F.png)
我有一个 bash 脚本,用于source
使脚本更加模块化。这是复制到用户bin
目录中的样子:
/bin
modules/
script-1
script-2
script-3
script-4
script-5
main-app
main-app
但是,如果您想从您的目录之外的目录执行,则这不起作用bin
。有没有办法使用source ./modules/script-x
inmain-app
以便我可以正确获取这些文件?或者我应该转换main-app
成一个文件?如果我确实需要,我应该手动执行此操作还是应该使用某种“编译器”?
答案1
答案2
您必须提取脚本的真实路径,然后获取您的模块:
#!/bin/bash
FULLPATH_OF_MAIN=`realpath $BASH_SOURCE`
SOURCEDIR=`dirname ${FULLPATH_OF_MAIN}`
source ${SOURCEDIR}/modules/script-x
答案3
.
在目录中使用点 ( ) 使它们相对于点“此目录”(pwd)。
如果您不介意静态目录(相对于用户目录(~)),您可以使用:
source ~/bin/modules/script-x # or equivalent: . ~/bin/modules/script-x
如果您需要相对于 main-app 启动目录(任何目录)的目录,您可以使用(在 bash 中):
source "${BASH_SOURCE%/*}/modules/script-x"
或者,在许多 shell 中:
source "$(basename "$0")/modules/script-x"
$0
假设主应用程序的调用方式将使 ps 列出的名称包含文件的正确路径,那么这将起作用。但情况并非总是如此:
$ exec -atestname /bin/bash
$ echo "$0"
testname
如果您的目录可能包含链接并且您需要规范路径(不使用链接或相对 (..) 名称),则使用:
source "$(basename "$(readlink -f -- "$BASH_SOURCE")" )/modules/script-x"
或者替换"$BASH_SOURCE"
为"$0"
(如果需要)。
注:即在一些极端情况你实际上可能需要使用realpath
而不是readlink -f
或者只是cd
到正确的目录(避免 readlink 或 realpath):
source "$( cd "${BASH_SOURCE%/*}" > /dev/null && pwd )/modules/script-x"