Rekursive Suche nach einer Binärdatei in den übergeordneten Verzeichnissen des aktuellen Verzeichnisses über hierarchischen $PATH

Rekursive Suche nach einer Binärdatei in den übergeordneten Verzeichnissen des aktuellen Verzeichnisses über hierarchischen $PATH

Ich möchte einige zusätzliche Binärdateien/Befehle verfügbar haben, wenn ich am Terminal bin, ausgelöst durch das CWD.

Als Beispiel soll die folgende Verzeichnisstruktur dienen

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

Dann in dieser Verzeichnisstruktur

  • cmd1und cmd2sind in verfügbar P1/S1.
  • ist nur in oder cmd1verfügbar .P1P1/S2
  • weder ist verfügbar in P2oderP2/S3

Im Allgemeinen möchte ich, dass dies mit jeder Verzeichnisstruktur funktioniert. Dies ist ähnlich der Art und Weise, wie Git erkennt, ob Sie sich in einem Git-Repository befinden. Es ist gleichbedeutend mit dem Einfügen von ./mybin, ../mybin, ../../mybinauf $PATH.

Wie muss ich meins ändern, PATHdamit das funktioniert? Ich verwende die Fish-Shell, aber ich portiere gerne eine Lösung von jeder anderen Shell auf meine.

Antwort1

Ich verstehe, dass Sie nicht zufrieden sind mit

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

bis zu einer Grenze von etwa 8 Unterverzeichnissen.

Anstatt Ihre reguläre Befehlssuche zu verunreinigen und zu unterbrechen, schlage ich vor, dass Sie einen kurzen Wrapper verwenden, sodass die rekursive Suche nur für die mit diesem Präfix versehenen Befehle durchgeführt wird.

Z. B. wird , , usw. k fooversucht , aber wie üblich wird einfach in nachgeschlagen ../mybin/foo../mybin/foofoo$PATH

Aber ich verwende nicht fish und habe keine Ahnung, wie das in der Sprache der fish-Shell geschrieben werden könnte. Mit bash / ksh / zsh könnte es etwa so aussehen:

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
}

Wenn das funktioniert, können Sie daraus ein eigenständiges ausführbares Skript machen, anstatt zu versuchen, es in Fish zu übersetzen:

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

verwandte Informationen