通过分层 $PATH 在当前目录的父目录中递归查找二进制文件

通过分层 $PATH 在当前目录的父目录中递归查找二进制文件

当我在终端上时,我希望有一些额外的二进制文件/命令可用,由 CWD 触发。

下面以目录结构为例

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

然后在这个目录结构中

  • cmd1并可cmd2P1/S1.
  • cmd1适用于P1P1/S2
  • 两者都不可用P2P2/S3

一般来说,我希望它适用于任何目录结构。这类似于 git 检测您是否位于 git 存储库中的方式。相当于把./mybin, ../mybin,../../mybin放在 上$PATH

我应该如何修改我的PATH才能使其正常工作?我正在使用 Fish shell,但我很乐意将任何其他 shell 的解决方案移植到我的 shell 中。

答案1

我明白你只是不高兴

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

直到某个限制,例如 8 个左右的子目录。

我建议您使用一个简短的包装器,而不是污染和破坏您的常规命令查找,这样递归查找将仅针对其前缀的命令进行。

例如。k foo将尝试./mybin/foo../mybin/foo等,但只会像往常一样foo在 中查找。$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

相关内容