
Мне нужно, чтобы при работе в терминале были доступны дополнительные двоичные файлы/команды, запускаемые CWD.
В качестве примера приведем следующую структуру каталогов:
├── P1
| ├── mybin
| │ └── cmd1
| ├── S1
| │ └── mybin
| │ └── cmd2
| ├── S2
└── P2
└── S3
Затем в этой структуре каталогов
cmd1
иcmd2
доступны в форматеP1/S1
.cmd1
доступен только вP1
илиP1/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/foo
и т.д., но просто foo
будем искать в $PATH
, как обычно.
Но я не использую fish, и я не представляю, как это можно написать на языке оболочки fish. С 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