Forçando a expansão de um alias global em parte de uma palavra

2

Eu tenho alguns scripts /tmp/foo/bar.sh e /tmp/foo/baz.sh , o seguinte:

# /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__

O primeiro script, /tmp/foo/bar.sh , define alguns aliases globais ( -g ) como encantamentos que devem ser expandidos ( para uma primeira aproximação !) caminho do script atual (invocação) e contém o diretório. Em seguida, ele usa esses aliases como argumentos em alguns comandos printf . Por fim, ele origina o segundo script, /tmp/foo/baz.sh , de três maneiras diferentes:

  1. usando o caminho literal para o segundo script;
  2. usando indiretamente o __DIR__ alias, por meio de uma substituição de comando printf ;
  3. usando diretamente o __DIR__ alias.

Veja o que recebo quando eu faço o primeiro 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

(A música e dança com /usr/bin/env é minha tentativa de usar /tmp/foo/bar.sh como possíveis ambientes.)

Parece que se __DIR__ for imediatamente seguido por /baz.sh , ele não será reconhecido como um alias, o que não é irracional. O formulário $( printf "%s/baz.sh" __DIR__ ) contorna este problema, mas sua extensão e convolutividade são praticamente o benefício de usar um alias em primeiro lugar.

Existe uma maneira mais conveniente de construir o caminho para a segunda string usando o __DIR__ alias?

Em geral, há algum "truque sintático" geral para alertar o analisador de que uma sequência específica de caracteres deve ser tratada como um alias? Minha esperança é fazer com que tal pseudônimo global se assemelhe mais ao comportamento de uma macro de pré-processador simples (em uma linha, sem argumentos, etc.). Um exemplo do tipo de "truque sintático" que tenho em mente é algo como o seguinte (nenhum dos quais funciona):

. {__DIR__}/baz.sh
. __DIR__"/baz.sh"
    
por kjo 12.11.2015 / 19:02

2 respostas

1

Há um recurso que permite que uma string seja substituída por outra string com apenas um caractere extra:

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

Se você realmente não quer definir uma variável, uma alternativa é definir um diretório nomeado, que só é expandido após um til no início de uma palavra. Isso funciona no seu exemplo, mas pode não generalizar para todos os casos em que você deseja.

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

OK, encontrei uma solução adequada, ilustrada abaixo

# /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
    
por 12.11.2015 / 20:44