有没有办法让一个来源的shell 脚本找出自己的路径?我主要关注 bash,尽管我有一些使用 tcsh 的同事。
我猜我在这里可能没有很多运气,因为采购导致命令在当前 shell 中执行,所以$0
仍然是当前 shell 的调用,而不是源脚本。我目前最好的想法是这样做source $script $script
,以便第一个位置参数包含必要的信息。有人有更好的方法吗?
需要明确的是,我正在采购脚本,而不是运行它:
source foo.bash
Run Code Online (Sandbox Code Playgroud)
Den*_*son 74
在tcsh
,$_
脚本的开头将包含该文件的来源位置,如果该文件$0
已运行,则该位置将包含该位置。
#!/bin/tcsh
set sourced=($_)
if ("$sourced" != "") then
echo "sourced $sourced[2]"
endif
if ("$0" != "tcsh") then
echo "run $0"
endif
Run Code Online (Sandbox Code Playgroud)
在 Bash 中:
#!/bin/bash
[[ $0 != $BASH_SOURCE ]] && echo "Script is being sourced" || echo "Script is being run"
Run Code Online (Sandbox Code Playgroud)
pbm*_*pbm 36
我认为你可以使用$BASH_SOURCE
变量。它返回执行的路径:
pbm@tauri ~ $ /home/pbm/a.sh
/home/pbm/a.sh
pbm@tauri ~ $ ./a.sh
./a.sh
pbm@tauri ~ $ source /home/pbm/a.sh
/home/pbm/a.sh
pbm@tauri ~ $ source ./a.sh
./a.sh
Run Code Online (Sandbox Code Playgroud)
所以下一步我们应该检查路径是否是相对的。如果不是相对的,一切都好。如果是,我们可以用 来检查路径pwd
,用/
和连接$BASH_SOURCE
。
gkb*_*986 23
此解决方案仅适用于 bash 而不是 tcsh。请注意,${BASH_SOURCE[0]}
如果您尝试从函数中查找路径,通常提供的答案将不起作用。
我发现这一行始终有效,无论文件是源文件还是作为脚本运行。
echo "${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}"
Run Code Online (Sandbox Code Playgroud)
如果你想readlink
在你上面得到的路径上使用符号链接,递归或非递归。
双引号可防止路径中的空格将结果拆分为数组,并且不仅用于echo
,而且在任何上下文中都需要使用双引号。由于echo
在数组项之间插入一个空格,除非路径中有两个或多个连续空格,否则差异将被隐藏。
这是一个用于尝试并将其与其他建议的解决方案进行比较的脚本。将其调用为source test1/test2/test_script.sh
or bash test1/test2/test_script.sh
。
echo "${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}"
Run Code Online (Sandbox Code Playgroud)
#
# Location: test1/test2/test_script.sh
#
echo $0
echo $_
echo "${BASH_SOURCE}"
echo "${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}"
cur_file="${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}"
cur_dir="$(dirname "${cur_file}")"
source "${cur_dir}/func_def.sh"
function test_within_func_inside {
echo "${BASH_SOURCE}"
echo "${BASH_SOURCE[${#BASH_SOURCE[@]} - 1]}"
}
echo "Testing within function inside"
test_within_func_inside
echo "Testing within function outside"
test_within_func_outside
Run Code Online (Sandbox Code Playgroud)
one-liner 工作的原因可以通过使用BASH_SOURCE
环境变量及其关联来解释FUNCNAME
。
BASH_SOURCE
一个数组变量,其成员是源文件名,其中定义了 FUNCNAME 数组变量中相应的 shell 函数名。shell 函数 ${FUNCNAME[$i]} 在文件 ${BASH_SOURCE[$i]} 中定义并从 ${BASH_SOURCE[$i+1]} 调用。
函数名
一个数组变量,包含当前在执行调用堆栈中的所有 shell 函数的名称。索引为 0 的元素是任何当前正在执行的 shell 函数的名称。最底部的元素(索引最高的元素)是“main”。此变量仅在执行 shell 函数时存在。对 FUNCNAME 的赋值无效并返回错误状态。如果 FUNCNAME 未设置,它会失去其特殊属性,即使它随后被重置。
此变量可与 BASH_LINENO 和 BASH_SOURCE 一起使用。FUNCNAME 的每个元素在 BASH_LINENO 和 BASH_SOURCE 中都有对应的元素来描述调用栈。例如,${FUNCNAME[$i]} 是从文件 ${BASH_SOURCE[$i+1]} 行号 ${BASH_LINENO[$i]} 处调用的。内置调用者使用此信息显示当前调用堆栈。
[来源:Bash 手册]
Sha*_*off 22
为了彻底和搜索者着想,这里是它们的作用......它是一个社区维基,所以可以随意添加其他 shell 的等效项(显然, $BASH_SOURCE 会有所不同)。
测试.sh:
#! /bin/sh
called=$_
echo $called
echo $_
echo $0
echo $BASH_SOURCE
Run Code Online (Sandbox Code Playgroud)
测试2.sh:
#! /bin/sh
source ./test.sh
Run Code Online (Sandbox Code Playgroud)
$./test2.sh
./test2.sh
./test2.sh
./test2.sh
./test.sh
$ sh ./test2.sh
/bin/sh
/bin/sh
./test2.sh
./test.sh
Run Code Online (Sandbox Code Playgroud)
$./test2.sh
./test2.sh
./test2.sh
./test2.sh
$/bin/sh ./test2.sh
/bin/sh
/bin/sh
./test2.sh
$
Run Code Online (Sandbox Code Playgroud)
$ ./test2.sh
./test.sh
./test.sh
./test.sh
$ zsh test.sh
echo
test.sh
$
Run Code Online (Sandbox Code Playgroud)
小智 18
这在 bash、dash、ksh 和 zsh 中对我有用:
if test -n "$BASH" ; then script=$BASH_SOURCE
elif test -n "$TMOUT"; then script=${.sh.file}
elif test -n "$ZSH_NAME" ; then script=${(%):-%x}
elif test ${0##*/} = dash; then x=$(lsof -p $$ -Fn0 | tail -1); script=${x#n}
else script=$0
fi
echo $script
Run Code Online (Sandbox Code Playgroud)
这些外壳的输出:
BASH source: ./myscript
ZSH source: ./myscript
KSH source: /home/pbrannan/git/theme/src/theme/web/myscript
DASH source: /home/pbrannan/git/theme/src/theme/web/myscript
BASH: ./myscript
ZSH: ./myscript
KSH: /home/pbrannan/git/theme/src/theme/web/myscript
DASH: ./myscript
Run Code Online (Sandbox Code Playgroud)
我试图让它适用于 csh/tcsh,但是太难了;我坚持使用 POSIX。
归档时间: |
|
查看次数: |
73819 次 |
最近记录: |