Reputation: 1955
I am trying to get the directory of the sourced script, and an important requirement is that sourcing can be nested, and the deepest script is sourced with something like source <(cat file)
, so the directory should be taken for the second deepest file, which is easy to do in Bash with ${BASH_SOURCE[1]}
. Any idea how to do the same in Zsh?
(From my comment below) The difference between ${BASH_SOURCE[0]} and ${BASH_SOURCE[1]} matters a lot in this case, because the script is sourced with <(...), and ${BASH_SOURCE[0]} doesn't point to a real file, but to a temporary file descriptor instead, which is why I need to get the second deepest file in the source chain.
Upvotes: 1
Views: 880
Reputation: 1563
You can use the funcfiletrace
parameter defined by the zsh/parameter
module.
funcfiletrace
This array contains the absolute line numbers and corresponding file names for the point where the current function, sourced file, or (if
EVAL_LINENO
is set) eval command was called.The array is of the same length as
funcsourcetrace
andfunctrace
, but differs fromfuncsourcetrace
in that the line and file are the point of call, not the point of definition, and differs fromfunctrace
in that all values are absolute line numbers in files, rather than relative to the start of a function, if any.
Use the last element of this array.
Consider the following files structure:
foo
└── bar
├── baz
│ └── baz.zsh
└── foo.zsh
and files content:
file="$(print -P ${(%):-%x})"
dir="${file:h}"
echo "foo file: $file"
echo "foo directory: $dir"
source <(cat "$dir/baz/baz.zsh")
zmodload zsh/parameter
file="$funcfiletrace[$#funcfiletrace]"
dir="${file:h}"
echo "foo file from bar: $file"
echo "foo directory from bar: $dir"
% zsh foo/bar/foo.zsh
foo file: foo/bar/foo.zsh
foo directory: foo/bar
foo file from bar: foo/bar/foo.zsh:7
foo directory from bar: foo/bar
Upvotes: 2