계층적 $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내 재능이 제대로 작동하려면 어떻게 수정해야 하나요 ? 나는 Fish 셸을 사용하고 있지만 다른 셸 솔루션을 내 셸에 이식할 수 있어서 기쁩니다.

답변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

관련 정보