Pesquisa recursiva de um binário nos pais do diretório atual por meio de $PATH hierárquico

Pesquisa recursiva de um binário nos pais do diretório atual por meio de $PATH hierárquico

Quero ter alguns binários/comandos extras disponíveis quando estiver no terminal, acionados pelo CWD.

Vamos seguir a estrutura de diretórios como um exemplo

├── P1
|   ├── mybin
|   │   └── cmd1
|   ├── S1
|   │   └── mybin
|   │       └── cmd2
|   ├── S2
└── P2
    └── S3

Então nesta estrutura de diretório

  • cmd1e cmd2estão disponíveis em P1/S1.
  • cmd1está disponível em P1ou P1/S2.
  • nem está disponível em P2ouP2/S3

Em geral, quero que isso funcione com qualquer estrutura de diretórios. Isso é semelhante a como o git detecta se você está em um repositório git. É equivalente a colocar ./mybin, ../mybin, ../../mybinon $PATH.

Como devo modificar meu PATHpara que isso funcione? Estou usando o shell de peixe, mas ficarei feliz em transferir uma solução de qualquer outro shell para o meu.

Responder1

Eu entendo que você não está feliz apenas com

PATH="./mybin:../mybin:../../mybin:../../../mybin:$PATH"

até algum limite como 8 ou mais subdiretórios.

Em vez de poluir e quebrar sua pesquisa regular de comandos, sugiro que você use um wrapper curto, de forma que a pesquisa recursiva seja feita apenas para os comandos prefixados por ele.

Por exemplo. k footentará ./mybin/foo, ../mybin/foo, etc. mas simplesmente fooserá pesquisado em $PATH, como de costume.

Mas não estou usando peixe e não tenho ideia de como isso poderia ser escrito na linguagem da casca do peixe. Com bash/ksh/zsh, poderia ser algo como:

function k {
    typeset p=. cmd=$1; shift
    while
        typeset e=$p/mybin/$cmd
        if [ -x "$e" ]; then "$e" "$@"; return; fi 
        [ ! "$p" -ef / ]
    do
        p=../$p
    done
    echo >&2 "k: not found: $cmd"; return 1
}

Se isso funcionar, você poderá transformá-lo em um script executável independente, em vez de tentar traduzi-lo para pescar:

#! /bin/bash
p=. cmd=$1; shift
while
    e=$p/mybin/$cmd
    if [ -x "$e" ]; then exec "$e" "$@"; fi
    [ ! "$p" -ef / ]
do
    p=../$p
done
echo >&2 "k: not found: $cmd"; exit 1

informação relacionada