階層 $PATH を使用して、現在のディレクトリの親ディレクトリで繰り返しバイナリを探します。

階層 $PATH を使用して、現在のディレクトリの親ディレクトリで繰り返しバイナリを探します。

CWDによってトリガされる端末にいるときに、いくつかの追加のバイナリ/コマンドを使用できることを願っています。

以下は、ディレクトリ構造を例に説明する。

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

次に、このディレクトリ構造で

  • cmd1そしてcmd2で利用可能ですP1/S1
  • または にのみcmd1適用されます。P1P1/S2
  • どちらも利用できP2ないか、P2/S3

一般的に言えば、どのディレクトリ構造でも機能したいと思います。これは、gitがgitリポジトリにあるかどうかを検出する方法と似ています。./mybin、、、../mybin../../mybin置くのと同じです$PATH

PATH私の才能が正しく機能するためには、どのように修正する必要がありますか?私はフィッシュシェルを使用していますが、他のシェルソリューションを自分のシェルに移植できてうれしいです。

ベストアンサー1

私はあなたがただ不幸であることを理解しています

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

8つ程度のサブディレクトリなど特定の制限まで可能です。

通常のコマンド照会を汚染して中断するのではなく、接頭辞付きのコマンドに対してのみ再帰照会が実行されるように短いラッパーを使用することをお勧めします。

例えば。などをk foo試してみますが、いつものように見てみましょう。./mybin/foo../mybin/foofoo$PATH

しかし、私は魚を使わずに、魚の殻の言語でどのように書くのかわかりません。 bash/ksh/zsh の場合:

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
}

うまくいけば、Fishに変換するのではなく、スタンドアロンの実行スクリプトにすることができます。

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

おすすめ記事