来源的 shell 脚本是否有可能知道它的位置?我读过确定来源的shell脚本路径,但答案集中在bash和tcsh,如果使用POSIX外壳失败。$0也不是解决方案并产生错误的结果。
解决方案不需要 100% 可靠。路径不太可能包含硬链接或符号链接。
# sourcing the script should yield the absolute path to the script
. somedir/thescript
# within “thescript”
-> /tmp/foo/bar/somedir
Run Code Online (Sandbox Code Playgroud)
一些背景:该脚本是现有应用程序的一部分,其中包含bin与源脚本相关的已知位置(因架构而异)的目录中的数十个二进制文件。要使用该应用程序,用户需要将bin目录PATH放在 .
Gil*_*il' 10
除非您使用提供 POSIX 规范扩展的 shell,否则源脚本的位置不可用。您可以使用以下代码段对此进行测试:
env -i PATH=/usr/bin:/bin sh -c '. ./included.sh' | grep included
Run Code Online (Sandbox Code Playgroud)
其中included.sh包含
echo "$0"
set
Run Code Online (Sandbox Code Playgroud)
在 bash 中,源脚本的名称在$BASH_SOURCE. 在 zsh 中(在 zsh 兼容模式下,而不是在 sh 或 ksh 兼容模式下),它在$0(注意,在函数中,$0是函数名)。在 pdksh 和 dash 中,它不可用。在 ksh93 中,此方法不会显示解决方案,但包含脚本的完整路径可作为${.sh.file}.
如果需要 bash 或 ksh93 或 zsh 就足够了,您可以使用以下代码段:
if [ -n "$BASH_SOURCE" ]; then
this_script=$BASH_SOURCE
elif [ -n "$ZSH_VERSION" ]; then
setopt function_argzero
this_script=$0
elif eval '[[ -n ${.sh.file} ]]' 2>/dev/null; then
eval 'this_script=${.sh.file}'
else
echo 1>&2 "Unsupported shell. Please use bash, ksh93 or zsh."
exit 2
fi
Run Code Online (Sandbox Code Playgroud)
您可以通过查看 shell 打开的文件来尝试猜测脚本的位置。实验上,这似乎适用于 dash 和 pdksh,但不适用于 bash 或 ksh93,至少对于短脚本而言,它们在执行脚本文件时已关闭脚本文件。
open_file=$(lsof -F n -p $$ | sed -n '$s/^n//p')
if [ -n "$open_file" ]; then
# best guess: $open_file is this script
fi
Run Code Online (Sandbox Code Playgroud)
如果脚本源自一个复杂的脚本,该脚本一直在玩重定向,则该脚本可能不是具有最高编号描述符的文件。您可能希望遍历打开的文件。无论如何,这不能保证工作。定位源脚本的唯一可靠方法是使用 bash、ksh93 或 zsh。
如果您可以更改接口,那么不要获取您的脚本,而是让您的脚本打印出要传递给eval调用者的 shell 片段。这是设置环境变量的脚本通常所做的。它允许您的脚本独立于调用者的 shell 和 shell 配置的变幻莫测而编写。
#!/bin/sh
FOO_DIR=$(dirname -- "$0")
cat <<EOF
FOO_DIR='$(printf %s "$FOO_DIR" | sed "s/'/'\\''/g")'
PATH="\$PATH:$FOO_DIR/bin";
export FOO_DIR PATH
EOF
Run Code Online (Sandbox Code Playgroud)
在调用者中: eval "`/path/to/setenv`"
| 归档时间: |
|
| 查看次数: |
7656 次 |
| 最近记录: |