wrapper executável, execute o executável original a partir do final do PATH

2

Há um executável /usr/bin/fooque eu e outros scripts usamos, mas que se comporta um pouco mal, então criei um wrapper Bash com o mesmo nome de arquivo no /usr/local/bin/fooqual corrigi seu comportamento inadequado. Meu PATHé /usr/local/bin:/usr/bin. No script wrapper, eu tenho que executar o executável original por caminho absoluto para não entrar em um loop infinito:

$ cat /usr/local/bin/foo
#/bin/zsh
/usr/bin/foo | grep -v "^INFO" # stfu, really

Existe alguma maneira simples (talvez específica Zsh ou Bash) para executar próximo fooem PATH, que é o fooque está em PATHdiretórios que são depois o diretório do qual atual foofoi executado, para que eu não teria que usar o caminho absoluto para o executável original?

Eu poderia fazer uma função para isso /etc/zshenve não é um problema. Só estou me perguntando se existe algo padrão. Não quero usar alias ou corrigir o executável original.


EDIT 1:

$ cat /usr/local/bin/foo
#/bin/zsh
path=(${path/#%$0:A:h}) foo | grep -v "^INFO" # stfu, really

Isso deve esvaziar (mas manter) todas as seqüências de caracteres em PATH ( ${path/...}) que correspondem totalmente ( #%) ao :Adiretório absoluto ( ) ( :h) do executável atual ( $0). TBH, eu o montei no StackExchange e não o entendo completamente. Espero que não me morda.

EDIT 2:

$ cat /usr/local/bin/foo
#/bin/zsh
path[${path[(i)$0:A:h]}]=() foo | grep -v "^INFO" # stfu, really

$path[(i)foo]localiza o índice de foona matriz pathou mais 1 comprimento da matriz.

woky
fonte
11
Eu imagino o seu script wrapper PATH auto-mutilando removendo seu diretório pai antes de chamar foo novamente
Jeff Schaller
@JeffSchaller Thanks. Você está certo. Eu atualizei a pergunta.
27516 woky
Ele poderia mordê-lo se o diretório passa a ser um substring de algum outro nome do diretório. Provavelmente é bom o suficiente para uso pessoal, mas não para o código que você espera que outros usem.
Thomas Dickey

Respostas:

2

Você pode descobrir em qual diretório o script está ( $0:hem zsh, "${0%/*}"em sh) e remover esse diretório de PATH( path=(${path:#$0:h})em zsh, mais complicado em sh . Isso pode falhar se PATHcontiver o mesmo diretório duas vezes, por exemplo, através de um link simbólico.

Uma desvantagem da abordagem direta é que isso remove o diretório do caminho, mas outros programas no mesmo diretório podem ser desejáveis. Você pode resolver esse problema executando apenas a pesquisa de caminho com um caminho modificado.

next=$(path=(${path:#$0:h}); print -lr -- =$0:t)
$next

Em vez disso, eu faria a PATHpesquisa manualmente e pularia qualquer ocorrência do script em execução.

for d in $path; do
  if [[ -x $d/$0:t && ! $d/$0:t -ef $0 ]]; then
    exec $d/$0:t
  fi
done
Gilles
fonte
1

Exemplo:
Para mim, type -a egrepimprime um alias definido pelo usuário e o egrepcomando real , adicionando outro egrepno meu $ HOME / bin / também mostra ... Na ordem; primeiro, depois os itens restantes na mesma ordem que PATH os possui.

$ cd # voltar para casa

$ mkdir -p bin

$ PATH = $ HOME / bin: $ PATH

$ type -a egrep
egrep é alias de `egrep --color = auto '
O egrep é / bin / egrep

$ echo -e> bin / egrep '#! / bin / bash \ necho TEST'

$ chmod 755 bin / egrep

$ type -a egrep
egrep é alias de `egrep --color = auto '
O egrep é / home / $ USER / bin / egrep
O egrep é / bin / egrep

# supondo que você tenha certeza de que é o único que não está em / home e não é um alias
$ type -a egrep | grep -Ev '/ home | alias' | cut -d '' -f3
/ bin / egrep

$ rm $ HOME / bin / egrep
Hannu
fonte