2

I have a couple of scripts /tmp/foo/bar.sh and /tmp/foo/baz.sh, the look like this:

# /tmp/foo/bar.sh

alias -g __FILE__='${(%):-%x}'
alias -g __DIR__='${${(%):-%x}%/*}'

printf "sourcing %s\n" __FILE__
printf "about to source %s/baz.sh\n" __DIR__

. /tmp/foo/baz.sh

. $( printf "%s/baz.sh" __DIR__ ) # succeeds
. __DIR__"/baz.sh"                  # fails
# /tmp/foo/baz.sh

printf "sourcing %s\n" __FILE__

The first script, /tmp/foo/bar.sh, defines a couple of global (-g) aliases as incantations that should expand (to a first approximation!) to the current script's (invocation) path, and it's containing directory. Then it uses these aliases as arguments in a couple of printf commands. Finally, it sources the second script, /tmp/foo/baz.sh, in three different ways:

  1. using the literal path to the second script;
  2. using the __DIR__ alias indirectly, through a printf command substitution;
  3. using the __DIR__ alias directly.

Here's what I get when I source the first script:

% (/usr/bin/env -i zsh -fc '. /tmp/foo/bar.sh')
sourcing /tmp/foo/bar.sh
about to source /tmp/foo/baz.sh
sourcing /tmp/foo/baz.sh
sourcing /tmp/foo/baz.sh
/tmp/foo/bar.sh:.:11: no such file or directory: __DIR__/baz.sh

(The song-and-dance with /usr/bin/env is my attempt to source /tmp/foo/bar.sh in as barebones an environment as possible.)

It appears that if __DIR__ is immediately followed by /baz.sh, then it is not recognized as an alias, which is not unreasonable. The form $( printf "%s/baz.sh" __DIR__ ) gets around this problem, but its length and convolutedness pretty much of the benefit of using an alias in the first place.

Is there a more convenient way to build the path to the second string using the __DIR__ alias?

More generally, is there some general "syntactic trick" to alert the parser that a specific sequence of characters should be treated like an alias? My hope is to make such a global alias more closely resemble the behavior of a simple (i.e. one-line, no arguments, etc.) C pre-processor macro. An example of the kind of "syntatic trick" I have in mind is something like the following (none of which work):

. {__DIR__}/baz.sh
. __DIR__"/baz.sh"

2 Answers 2

1

There's a feature that allows a string to be substituted by another string with just one extra character:

__FILE__='${(%):-%x}'
__DIR__='${${(%):-%x}%/*}'
. $__DIR__/baz.sh

If you really don't want to define a variable, an alternative is to define a named directory, which is only expanded after a tilde at the beginning of a word. This works in your example but might not generalize to all the cases where you want it.

hash -d __FILE__='${(%):-%x}'
hash -d __DIR__='${${(%):-%x}%/*}'
. ~__DIR__/baz.sh
0

OK, I found an adequate solution, illustrated below

# /tmp/foo/bar.sh

alias -g __FILE__='echo "${(%):-%x}"'
alias -g __DIR__='echo "${${(%):-%x}%/*}"'

printf "sourcing %s\n" $(__FILE__)
printf "about to source %s/baz.sh\n" $(__DIR__)

. $(__DIR__)/baz.sh               # succeeds

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .