Bash函数-返回父脚本文件路径
我有一个bash脚本,其中包含一个由许多不同bash脚本提供的函数。此函数可能会根据其输入失败,我想在函数中创建日志记录,以确定哪些脚本导致失败 例如:。, source/path/to/function.sh 最接近我的是:Bash函数-返回父脚本文件路径,bash,Bash,我有一个bash脚本,其中包含一个由许多不同bash脚本提供的函数。此函数可能会根据其输入失败,我想在函数中创建日志记录,以确定哪些脚本导致失败 例如:。, source/path/to/function.sh 最接近我的是: ps --no-heading -ocmd -p $$ 如果使用完整的文件路径来运行父脚本,则此操作非常有效,返回: /bin/bash /path/to/parent.sh 但如果父脚本从相对路径运行,则无法提供完整路径,返回: /bin/bash ./parent
ps --no-heading -ocmd -p $$
如果使用完整的文件路径来运行父脚本,则此操作非常有效,返回:
/bin/bash /path/to/parent.sh
但如果父脚本从相对路径运行,则无法提供完整路径,返回:
/bin/bash ./parent.sh
理想情况下,我想要一种可靠地返回两种情况下的父脚本文件路径的方法
我想我可以让每个父脚本将其文件路径传递给函数(通过$0或类似的方式),但这似乎很难实现,也不是非常优雅
有什么想法或替代方法吗?我是否应该不担心相对路径的情况,而只是对所有内容使用完整/绝对文件路径
谢谢
我使用的是Centos 5.9。
Bash版本-
GNU bash,版本3.2.25(1)-在父脚本开始导出后立即发布(x86_64-redhat-linux-GNU)
"`pwd`/$0"
或者,在一个env变量中,比如说ORIG_脚本,然后在函数中使用ORIG_脚本
您需要在脚本启动时立即执行此操作,因为$0可能与PWD有关,如果您以后在需要ORIG_脚本的值之前更改PWD,那么它会变得不必要的复杂
更新:
由于您通过$$了解pid,您可能会从/proc//cmdline中获得一些信息,但我不知道这一点现在是如何工作的。您可以使用readlink跟踪所有符号链接以获得绝对路径
echo $(readlink -f $0)
您可以使用
${BASH_SOURCE[1]}
获取调用函数的脚本,但该脚本并不总是绝对路径形式。您可以通过readlink-m
、realpath
或其他方式获取它的绝对路径,但是如果脚本不时更改目录,则将相对路径转换为绝对路径将不再准确,因为这些工具将从当前目录获取实际的表单
不过,有一种解决方法,但这需要在调用(寻源)包含函数的脚本之前,不要更改脚本中的目录。您必须将当前目录保存在该脚本本身中,然后通过该目录创建绝对路径。脚本包含后,您可以自由更改目录。例如:
ORIGINAL_PWD=$PWD
function x {
local CALLING_SCRIPT="${BASH_SOURCE[1]}"
if [[ -n $CALLING_SCRIPT ]]; then
if [[ $CALLING_SCRIPT == /* ]]; then
CALLING_SCRIPT=$(readlink -m "$CALLING_SCRIPT")
else
CALLING_SCRIPT=$(readlink -m "$ORIGINAL_PWD/$CALLING_SCRIPT")
fi
echo "Calling script: $CALLING_SCRIPT"
else
echo "Caller is not a script."
fi
}
或
ORIGINAL_PWD=$PWD
函数getabspath{
局部-a T1 T2
局部-i=0
本地IFS=/A
案件“$1”
/*)
read-r-AT1这里有一个类似的问题,我想可能会让你开始:谢谢,我不认为检查它-似乎是最简单的解决方案。
ORIGINAL_PWD=$PWD
function getabspath {
local -a T1 T2
local -i I=0
local IFS=/ A
case "$1" in
/*)
read -r -a T1 <<< "$1"
;;
*)
read -r -a T1 <<< "/$PWD/$1"
;;
esac
T2=()
for A in "${T1[@]}"; do
case "$A" in
..)
[[ I -ne 0 ]] && unset T2\[--I\]
continue
;;
.|'')
continue
;;
esac
T2[I++]=$A
done
case "$1" in
*/)
[[ I -ne 0 ]] && __="/${T2[*]}/" || __=/
;;
*)
[[ I -ne 0 ]] && __="/${T2[*]}" || __=/.
;;
esac
}
function x {
local CALLING_SCRIPT="${BASH_SOURCE[1]}"
if [[ -n $CALLING_SCRIPT ]]; then
if [[ $CALLING_SCRIPT == /* ]]; then
getabspath "$CALLING_SCRIPT"
else
getabspath "$ORIGINAL_PWD/$CALLING_SCRIPT"
fi
echo "Calling script: $__"
else
echo "Caller is not a script."
fi
}