내 홈 디렉토리에 로컬로 많은 앱이 설치되어 있습니다. 전 세계적으로 사용할 수 있도록 다음 PATH
위치에 추가했습니다 .bashrc
.
PATH="$PATH:/home/user/apps/app1/bin"
PATH="$PATH:/home/user/apps/app2/bin"
PATH="$PATH:/home/user/apps/appn/bin"
새 항목을 모두 추가할 필요가 없도록 하려면 어떻게 설정해야 합니까? 나는 이것을 시도하고 있지만 작동하지 않습니다.
PATH="$PATH:/home/user/apps/*/bin"
노트:루프를 사용하여 추가할 수 있다는 것을 알고 있지만 PATH
변수가 너무 커지는 것이 걱정되고 어떻게든 와일드카드를 사용할 수 있는지 알고 싶습니다.
답변1
와일드카드 문자는 $PATH
확장되지 않습니다. ~에 따르면배쉬 매뉴얼, 경로는 다음과 같습니다.
콜론으로 구분된 목록목차쉘은 다음에서 명령을 찾습니다.
(내 강조).
반대방향에서 오시는데,명령어 검색 및 실행 부분설명서의 일부는 다음과 같습니다.
이름이 쉘 함수도 내장 함수도 아니고 슬래시를 포함하지 않으면 Bash는 $PATH의 모든 요소를 검색합니다.목차해당 이름의 실행 파일이 포함되어 있습니다.
...(필자의 강조) - 경로 요소의 특별한 처리에 대해서는 언급하지 않고 단지 디렉터리여야 한다는 것입니다(있는 그대로).
bash 변수의 크기 제한이 무엇인지 아직 확실하지 않습니다. 사용 가능한 메모리인 것 같습니다. PATH는 내보낼 필요가 없지만 많은 사람들이 내보낸 경우 다른 환경 변수 및 매개변수와 함께 조정해야 합니다 getconf ARG_MAX
(참조:https://unix.stackexchange.com/a/124422/117549). bash는 해시 테이블을 사용하여 이전에 발견된 명령의 위치를 (세션별로) 기억하기 때문에 큰 PATH 디렉토리는 많은 성능 오버헤드를 발생시키지 않아야 합니다.
각 개별 응용 프로그램 디렉터리를 PATH에 추가하는 데 제한(시각적 또는 기술적)이 발생하는 경우 각 응용 프로그램의 모든 파일을 연결할 수 있는 "symlink" 디렉터리를 PATH에 추가하는 것이 좋습니다.
답변2
추가 는 경로가 다음과 같은 디렉터리에서 실행 파일을 검색하는 것을 /home/user/apps/*/bin
의미합니다 (완전히 유효한 경로, Unix에서는 문자 1이 파일 이름이나 디렉터리 이름에 사용되는 것을 막을 수 없음 ). 경로가 쓰기 내용과 일치할 때 추가할 수 있습니다. 다음을 사용하는 디렉토리:$PATH
/home/user/apps/*/bin
*
/home/user/apps/*/bin
path+=( /home/user/apps/*/bin(N-/) )
zsh에서 변수는 csh의 배열에 바인딩되며 $PATH
glob 한정자를 사용하여 nullglob뿐만 아니라 디렉터리 유형 파일(또는 디렉터리에 대한 기호 링크)로 확장을 제한할 수 있습니다.$path
-/
N
중복 항목을 제거하기 위해 a를 실행할 수도 있습니다 typeset -U path
( U
고유 항목의 경우).
where 는 배열로 노출 fish
되며 nullglob과 유사한 동작은 다음에서 사용되는 glob에 적용됩니다 .$PATH
set
set PATH $PATH /home/user/apps/*/bin
(파일 형식에 국한되지 않음)목차하지만).
POSIXly에서는 언제든지 다음을 수행할 수 있습니다.
for dir in /home/user/apps/*/bin; do
[ -d "$dir" ] && PATH="${PATH:+$PATH:}$dir"
done
그럼에도 불구하고 나중에 /home/user/apps/에 더 많은 디렉토리가 추가되면 해당 디렉토리는 $PATH
.
ksh93에서는 규칙을 사용하여 이러한 마법 같은 효과를 얻을 수 있습니다.
function PATH.get {
typeset dir
for dir in ~(N)/home/user/apps/*/bin; do
[[ :$PATH: = *:"$dir":* || ! -d $dir ]] || PATH=${PATH:+$PATH:}$dir
done
}
$PATH
참조될 때마다 계산되는 값입니다.
zsh에서는 precmd()
후크를 사용하거나 각 프롬프트 전에 bash
다시 계산을 사용할 수 있습니다 $PROMPT_COMMAND
.
¹ 또는 및 NUL 을 제외한 모든 문자 /
또는 해당 문제에 대한 문자가 아닌 경우에도 마찬가지입니다.
답변3
이를 위해 몇 가지 솔루션을 사용했습니다.
1. find
동적 생성 사용$PATH
이를 위해 유사하지만 약간 수정된 여러 가지 방법을 사용했습니다. 다음과 같은 구조가 있다고 가정해 보겠습니다.
~/apps
├── foo
│ └── bin
├── bar
│ └── bin
└── blah
우리는 할 수 있습니다 ...
ㅏ. 기존 추가응용 프로그램/*/bin/폴더$PATH
이것은 무엇이든 검색합니다쓰레기통/디렉토리$HOME
/애플리케이션/*로드할 때 쉘 에 추가하고 $PATH
, 없는 디렉토리는 건너뜁니다.쓰레기통/하위 디렉토리.
#.bashrc
bins=$(
find "$HOME/apps/" -maxdepth 2 -type d -name 'bin' \
| tr '\n' ':' \
| sed 's/:$//'
)
export PATH="$bins:$PATH"
생산:
/home/user/apps/foo/bin:/home/user/apps/bar/bin:...
b.추가특정 디렉토리 /*/bin/도착하다$PATH
...각 폴더 여부에 관계없이디렉토리/실제로 하나 있어요쓰레기통/내부의 하위 디렉토리. 이는 위의 디렉토리 구조에 대해애플리케이션/등/빈추가됩니다 $PATH
- 존재하지 않더라도!
이는 디렉터리 중 하나가 존재하지 않을 때 유용합니다.지금하나 있다쓰레기통/$PATH
하위 디렉터리에 있지만 향후에 있을 가능성이 높으므로 쉘을 생성한 후 쉘에 추가하기 위해 쉘을 다시 로드할 필요 가 없습니다 .
#.bashrc
bins=$(
find "$HOME/apps/" -maxdepth 1 -type d \
| sed 's_$_/bin_' \
| tr '\n' ':' \
| sed 's/:$//'
)
export PATH="$bins:$PATH"
생산:
/home/user/apps/foo/bin:/home/user/apps/bar/bin:/home/user/apps/blah/bin:...
find 명령은 존재하지 않는 디렉토리를 잠시 찾으려고 시도하므로 이는 성능에 터무니없이 무시할 수 있는 영향을 미칠 수 있습니다.느끼다존재하지 않는 디렉토리를 my 에 추가하는 것은 좋지 않지만 $PATH
편의상 이것이 제가 선호하는 옵션입니다.
2. stow
실행 파일을 생성하는 데 사용되는 심볼릭 링크
stow
바로 이 목적을 위해 만들어졌습니다. 저는 현재 이 설정을 사용하여 모든 도트 파일을 git 저장소에 저장하고 홈 디렉토리에 복사하고 있습니다. :)
다음과 같은 디렉토리 구조가 있는 경우:
.
├── bar
│ └── bin
│ ├── bar-executable-1
│ └── bar-executable-2
├── bin
└── foo
└── bin
├── foo-executable-1
└── foo-executable-2
당신은 모든 파일을 원한다바/빈/*그리고부자/빈/*다음으로 연결쓰레기통/, 다음을 실행할 수 있습니다.
cd somedir
stow -v --restow --target bin/ --dir bar/ bin
stow -v --restow --target bin/ --dir foo/ bin
--restow
참고: 새 심볼릭 링크를 다시 만들기 전에 오래된 심볼릭 링크를 모두 삭제하기 때문에 prune을 사용했습니다.
그러면 다음이 생성됩니다.
somedir
├── bar
│ └── bin
│ ├── bar-executable-1
│ └── bar-executable-2
├── bin
│ ├── bar-executable-1 -> ../bar/bin/bar-executable-1
│ ├── bar-executable-2 -> ../bar/bin/bar-executable-2
│ ├── foo-executable-1 -> ../foo/bin/foo-executable-1
│ └── foo-executable-2 -> ../foo/bin/foo-executable-2
└── foo
└── bin
├── foo-executable-1
└── foo-executable-2
그런 다음 간단히 추가하면됩니다.특정 디렉토리 /bin/당신을 위한PATH
더 stow
쉽게 사용하세요
만약에
- 각 디렉토리 내의 고유 디렉토리신청N디렉토리는 단일입니다.쓰레기통/목차그리고
- 컴파일된 내용을 이동할 수 있습니다.쓰레기통/디렉토리 외부의 디렉토리애플리케이션/목차
그런 다음 약간 더 간단한 명령을 사용할 수 있습니다 stow
.
/home/user
├── Desktop
├── Documents
├── Pictures
├── Videos
├── apps
│ ├── bar
│ │ └── bin
│ │ ├── bar-executable-1
│ │ └── bar-executable-2
│ └── foo
│ └── bin
│ ├── foo-executable-1
│ └── foo-executable-2
└── bin
cd
stow -v --restow --target ./ --dir apps/ foo bar
이것은 기본적으로 말한다"apps" 폴더에서 "foo" 및 "bar"라는 "패키지"를 찾고 심볼릭 링크를 사용하여 두 패키지의 전체 내용을 현재 디렉터리에 복사합니다.. 그러니까 다 갖고 있으면응용프로그램/foo/그리고앱/바/싱글이다쓰레기통/폴더를 선택하면 다음과 같은 파일이 생성됩니다.쓰레기통/모든 파일에 대한 링크가 포함된 현재 디렉터리의 폴더응용 프로그램/foo/bin/그리고앱/바/빈/.
하지만 다른 파일/폴더가 많으면응용프로그램/foo/그리고앱/바/단 하나를 제외하고쓰레기통/디렉터리를 삭제하면 홈 폴더에도 이 모든 콘텐츠가 다시 생성됩니다. 이는 바람직하지 않을 수 있으므로 첫 번째 예를 따라야 합니다 stow
.
https://www.gnu.org/software/stow/manual/html_node/Installing-Packages.html