
$PATH
현재 작업 디렉토리에 따라 환경 변수를 변경하고 싶습니다 .
내가 참여했고 /foo/bar/baz
디렉토리 /foo/node_modules/.bin
와 /foo/bar/baz/node_modules/.bin
. 가능한 모든 것을 ./node_modules/.bin
재귀적으로 추가하고 싶습니다 $PATH
.
하지만 cd
다른 디렉토리(예: )에 들어가면 원래의 깨끗한 파일을 복원한 다음 다시 재귀적으로 찾기 시작하기를 /foo/bar
원합니다 .$PATH
./node_modules/.bin
(npm의 이슈 트래커에서 내 질문을 해결하고 싶습니다.로컬에 설치된 패키지도 PATH에 추가할 수 있나요?)
참고: 저는 Mac을 사용하고 있지만 일반적인 솔루션에 관심이 있습니다.
답변1
소개
내가 올바르게 이해했다면 이나 그 조상이 있는 "$X/node_modules/.bin"
디렉터리 를 추가하고 싶을 것입니다 .$X
$PWD
이 게시물 끝에 있는 스크립트는 원하는 동작을 제공해야 합니다. 원하는 모든 세션에서 소스를 제공해야 합니다. 파일 이름을 으로 지정하는 경우 augment_path.sh
다음 줄을 추가하면 .bashrc
충분합니다.
source augment_path.sh
논의
내 생각에 garyjohn은 기본적인 접근 방식이 옳다고 생각하지만 그는 모든 조상이 아닌 모든 후손을 검색하고 있습니다.
변수 $PROMPT_COMMAND
를 사용하면 프롬프트가 표시될 때마다 실행할 명령을 지정할 수 있습니다. 원본을 복원할 $PROMPT_COMMAND_OLD
수 있도록 변수 를 추가했습니다.$PROMPT_COMMAND
꼭 필요한 것은 아니지만 좋은 형식을 위해 $LAST_WD
변수를 추가하고 디렉터리가 변경되지 않았을 때 경로를 다시 계산하지 않도록 테스트합니다. LAST_WD
원하는 경우 포함된 세 줄을 모두 제거할 수 있습니다 .
이 augment_path
함수는 위쪽에서 스캔하여 $PWD
각 조상에서 대상 디렉터리를 찾고 찾은 항목을 경로에 추가합니다.
경로에 순서대로 배치되므로 충돌이 있는 경우 가장 깊은 디렉터리가 우선적으로 적용됩니다. 나는 이것이 바람직한 행동이라고 생각합니다. 그렇지 않다면 변경하세요.
PATH_ADDITION="$PATH_ADDITION:$resolved_target"
에게
PATH_ADDITION="$resolved_target:$PATH_ADDITION"
그러나 이러한 디렉터리는 모두 나머지 경로보다 우선합니다. 나머지 경로가 우선 적용되도록 하려면 다음을 변경하십시오.
PATH="$PATH_ADDITION:$RAW_PATH"
에게
PATH="$RAW_PATH:$PATH_ADDITION"
스크립트
RAW_PATH="$PATH"
LAST_WD=`pwd`
augment_path() {
target="node_modules/.bin"
if [ "$PWD" = "$LAST_WD" ]; then return 0; fi;
PATH_ADDITION=""
scandir="$PWD"
until [ "$scandir" = "" ]; do
resolved_target="$scandir"/"$target"
if [ -d "$resolved_target" ]; then
PATH_ADDITION="$PATH_ADDITION:$resolved_target"
fi
scandir="${scandir%/*}"
done
PATH="$PATH_ADDITION:$RAW_PATH"
LAST_WD=`pwd`
}
PROMPT_COMMAND_OLD="${PROMPT_COMMAND%; augment_path}"
PROMPT_COMMAND="$PROMPT_COMMAND_OLD; augment_path"
답변2
bash로 작업할 수 있습니다.PROMPT_COMMAND
:
PROMPT_COMMAND='[ -z "$X" ] && X=$PATH; PATH=$X:$(pwd)/node_modules/.bin'
해당 명령은 프롬프트가 나타날 때마다 실행됩니다. 따라서 명령이 완료될 때마다 PATH
변수가 변경됩니다. 끝에 추가 디렉터리가 추가됩니다.
./node_modules/.bin
현재 작업 디렉토리에 디렉토리가 없으면 경로가 추가됩니다. 하지만 그건 문제가 되지 않습니다. (존재하지 않기 때문에) 여물통에서는 검색되지 않습니다.
데모 보기:
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
$ PROMPT_COMMAND='[ -z "$X" ] && X=$PATH; PATH=$X:$(pwd)/node_modules/.bin'
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/node_modules/.bin
$ cd test
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/test/node_modules/.bin
$ cd /etc/
$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/etc/node_modules/.bin
답변3
~/.bashrc
나는 당신이 원하는 것을 다음과 같이 넣으면 될 것이라고 생각합니다 .
bash 환경 변수가 PROMPT_COMMAND
일부 명령으로 설정된 경우 bash가 기본 프롬프트를 표시하기 전에 해당 명령이 실행됩니다.
아래 코드에서는 PROMPT_COMMAND
함수 이름으로 가 설정되어 있습니다 doit
. 이 함수는 현재 작업 디렉터리가 변경되었는지 여부를 확인하고 변경된 경우 먼저 PATH
원래 값으로 설정한 다음 이름이 지정된 하위 디렉터리가 있는지 확인합니다 node_modules/.bin
. 해당 하위 디렉터리가 존재하는 경우 함수는 해당 하위 디렉터리의 이름과 그 아래의 모든 하위 디렉터리를 에 추가합니다 PATH
.
orig_path="$PATH"
prev_pwd=""
doit() {
if [ "$PWD" != "$prev_pwd" ]; then
PATH="$orig_path"
if [ -d "node_modules/.bin" ]; then
PATH="$PATH$(find $PWD/node_modules/.bin -type d -printf ':%p')"
# For POSIX compatibility (macOS or other), use:
# PATH="$PATH$(find $PWD/node_modules/.bin -type d -exec echo -n :{} \;)"
fi
prev_pwd="$PWD"
fi
}
PROMPT_COMMAND=doit