wrapper executável, execute o executável original da cauda do PATH

2

Há um executável /usr/bin/foo que eu e outros scripts usamos, mas ele se comporta mal, então eu fiz um wrapper Bash com o mesmo nome de arquivo em /usr/local/bin/foo onde eu consertei o mau comportamento. Meu PATH é /usr/local/bin:/usr/bin . No script wrapper, eu tenho que executar o executável original pelo 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 para Zsh ou Bash) de executar o próximo foo em PATH , ou seja, os diretórios foo que estão em PATH que estão após o diretório do qual o foo atual foi executado, de modo que eu não teria que usar o caminho absoluto para o executável original?

Eu poderia fazer uma função para ele em /etc/zshenv e isso não é grande coisa. Eu só estou querendo saber se existe alguma coisa padrão. Eu não quero usar o alias ou consertar 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 strings no PATH ( ${path/...} ) que correspondem totalmente ( #% ) ao diretório absoluto ( :A ) ( :h ) do executável atual ( $0 ). TBH, eu montei do StackExchange e não o entendi totalmente. Espero que não vá me morder.

EDIT 2:

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

$path[(i)foo] encontra o índice de foo na matriz path ou 1 mais o comprimento da matriz.

    
por woky 26.03.2016 / 22:52

2 respostas

2

Você pode descobrir em qual diretório o script está ( $0:h em 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 PATH contiver 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 fazendo apenas a pesquisa de caminho com um caminho modificado.

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

Em vez disso, faço a consulta PATH manualmente e pulo 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
    
por 27.03.2016 / 23:54
1

Exemplo:
 Para mim type -a egrep imprime um alias definido pelo usuário e o comando egrep real, adicionando ainda outro egrep no meu $ HOME / bin / também mostra ... No pedido; primeiro, depois os itens restantes na mesma ordem que o PATH os tem.

$ cd # go home

$ mkdir -p bin

$ PATH=$HOME/bin:$PATH

$ type -a egrep
egrep is aliased to 'egrep --color=auto'
egrep is /bin/egrep

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

$ chmod 755 bin/egrep

$ type -a egrep
egrep is aliased to 'egrep --color=auto'
egrep is /home/$USER/bin/egrep
egrep is /bin/egrep

# assuming you're sure it is the only one not in /home and not an alias
$ type -a egrep | grep -Ev '/home|alias' | cut -d' ' -f3
/bin/egrep

$ rm $HOME/bin/egrep
    
por 28.03.2016 / 12:58

Tags