보다! 산업적으로 강력한 12 줄 ... 기술적으로 bash 및 zsh-portable 쉘 기능 은 선택의 시작 스크립트 ~/.bashrc
또는 ~/.zshrc
시작 스크립트 를 전적으로 사랑합니다 .
# void +path.append(str dirname, ...)
#
# Append each passed existing directory to the current user's ${PATH} in a
# safe manner silently ignoring:
#
# * Relative directories (i.e., *NOT* prefixed by the directory separator).
# * Duplicate directories (i.e., already listed in the current ${PATH}).
# * Nonextant directories.
+path.append() {
# For each passed dirname...
local dirname
for dirname; do
# Strip the trailing directory separator if any from this dirname,
# reducing this dirname to the canonical form expected by the
# test for uniqueness performed below.
dirname="${dirname%/}"
# If this dirname is either relative, duplicate, or nonextant, then
# silently ignore this dirname and continue to the next. Note that the
# extancy test is the least performant test and hence deferred.
[[ "${dirname:0:1}" == '/' &&
":${PATH}:" != *":${dirname}:"* &&
-d "${dirname}" ]] || continue
# Else, this is an existing absolute unique dirname. In this case,
# append this dirname to the current ${PATH}.
PATH="${PATH}:${dirname}"
done
# Strip an erroneously leading delimiter from the current ${PATH} if any,
# a common edge case when the initial ${PATH} is the empty string.
PATH="${PATH#:}"
# Export the current ${PATH} to subprocesses. Although system-wide scripts
# already export the ${PATH} by default on most systems, "Bother free is
# the way to be."
export PATH
}
순간적인 영광을 위해 자신을 준비하십시오. 그런 다음이 작업을 수행하고 최선을 다하기를 바랍니다.
export PATH=$PATH:~/opt/bin:~/the/black/goat/of/the/woods/with/a/thousand/young
당신이 정말로 원하든 원하지 않든, 대신 이것을하고 최선을 다할 것을 보장하십시오 :
+path.append ~/opt/bin ~/the/black/goat/of/the/woods/with/a/thousand/young
"최고"를 정의하십시오.
전류를 안전하게 추가하고 추가 ${PATH}
하는 것은 일반적으로 이루어지는 사소한 일이 아닙니다. 편리하고 겉으로는 합리적이지만 양식의 한 라이너는 다음 export PATH=$PATH:~/opt/bin
과 같은 끔찍한 합병증을 유발합니다.
실수로 상대 dirnames (예 export PATH=$PATH:opt/bin
). 동안 bash
과 zsh
자동으로 받아들이고 주로 상대 dirnames 무시 대부분의 경우를, 상대 dirnames 중 하나를 접두어 h
또는 t
부끄럽게 모두에 원인 (그리고 아마도 다른 사악한 자) 마사키 고바야시의 람 자신을 토막 정액 1,962 걸작 Harakiri :
# Don't try this at home. You will feel great pain.
$ PATH='/usr/local/bin:/usr/bin:/bin' && export PATH=$PATH:harakiri && echo $PATH
/usr/local/bin:/usr/bin:arakiri
$ PATH='/usr/local/bin:/usr/bin:/bin' && export PATH=$PATH:tanuki/yokai && echo $PATH
binanuki/yokai # Congratulations. Your system is now face-up in the gutter.
실수로 중복 된 디렉토리 이름. 중복 ${PATH}
디렉토리 이름은 크게 무해 하지만 , 원치 않거나 번거롭고 약간 비효율적이며 디버깅 가능성을 방해하며 드라이브 마모를 촉진합니다. NAND 스타일 SSD는 물론 마모에 영향을받지 않지만 HDD는 그렇지 않습니다. 모든 시도 된 명령 에 대한 불필요한 파일 시스템 액세스 는 동일한 템포에서 불필요한 읽기 헤드 마모를 의미합니다. 중복은 중첩 된 서브 프로세스에서 중첩 된 쉘을 호출 할 때 특히 어색하지 않습니다.이 시점에서 무해한 1- 라이너 export PATH=$PATH:~/wat
는 7 번째 ${PATH}
지옥의 원으로 빠르게 폭발합니다 PATH=/usr/local/bin:/usr/bin:/bin:/home/leycec/wat:/home/leycec/wat:/home/leycec/wat:/home/leycec/wat
. 당신이 그것에 추가 디렉토리 이름을 추가하면 Beelzebubba만이 당신을 도울 수 있습니다. (소중한 아이들에게 이런 일이 일어나지 않도록하십시오. )
- 실수로 dirname이 누락되었습니다. 다시 말해 누락 된
${PATH}
dirname은 무해하지만, 일반적으로 원치 않거나 번거롭고 약간 비효율적이며 디버깅 가능성을 방해하고 드라이브 마모를 촉진합니다.
Ergo, 위에서 정의한 쉘 기능과 같은 친숙한 자동화. 우리는 자신을 구해야합니다.
하지만 ... 왜 "+ path.append ()"? 왜 append_path ()가 아닌가?
(현재 외부 명령을 예를 들어, disambiguity를 들어 ${PATH}
다른 곳에서 정의 또는 시스템 전체 쉘 기능), 사용자 정의 쉘 기능이 이상적으로 접두사 또는 고유 지원 하위 접미사 bash
와 zsh
, 말, 같은 -하지만 그렇지 않으면 표준 명령의 basename 금지 +
.
안녕 작동합니다. 나를 판단하지 마십시오.
하지만 ... 왜 "+ path.append ()"? 왜 "+ path.prepend ()"가 아닙니까?
current에 추가하는 것이 current ${PATH}
앞에 추가하는 것보다 안전 하기 때문에 ${PATH}
모든 것이 동일하며 결코 존재하지 않습니다. 사용자 별 명령을 사용하여 시스템 전체 명령을 재정의하는 것은 최선이 아니고 최악의 경우 미친 짓을 할 수 있습니다. 예를 들어 Linux에서 다운 스트림 응용 프로그램은 일반적으로 사용자 지정 비표준 파생 제품이나 대안이 아닌 GNU coreutils 명령 변형을 기대합니다 .
즉, 그렇게하는 데 유효한 유스 케이스가 절대적으로 있습니다. 동등한 +path.prepend()
기능을 정의하는 것은 쉽지 않습니다. Sans prolix nebulosity, 그와 그녀의 공유 된 정신력 :
+path.prepend() {
local dirname
for dirname in "${@}"; do
dirname="${dirname%/}"
[[ "${dirname:0:1}" == '/' &&
":${PATH}:" != *":${dirname}:"* &&
-d "${dirname}" ]] || continue
PATH="${dirname}:${PATH}"
done
PATH="${PATH%:}"
export PATH
}
하지만 ... 왜 질이 아닌가?
Gilles 의 다른 곳에서 받아 들여진 대답 은 일반적인 경우에 "쉘과 무관 한 append 등식 부록" 으로서 인상적으로 최적이다 . 그러나, 바람직하지 않은 심볼릭 링크 가 없는 일반적인 경우에 bash
, 그렇게하기 위해 필요한 성능 불이익은 젠투 라이저 를 슬프게합니다 . 바람직하지 않은 심볼릭 링크가 존재하더라도 인수 당 하나의 서브 쉘을 포크하는 것이 심볼릭 링크 복제본을 삽입 할 가치 가 있는지 여부는 논란의 여지가 있습니다.zsh
add_to_PATH()
symlink 복제본도 제거해야하는 엄격한 사용 사례의 경우이 zsh
특정 변형은 비효율적 인 포크가 아닌 효율적인 내장을 통해 수행됩니다.
+path.append() {
local dirname
for dirname in "${@}"; do
dirname="${dirname%/}"
[[ "${dirname:0:1}" == '/' &&
":${PATH}:" != *":${dirname:A}:"* &&
-d "${dirname}" ]] || continue
PATH="${PATH}:${dirname}"
done
PATH="${PATH#:}"
export PATH
}
원본 이 *":${dirname:A}:"*
아니라 참고하십시오 *":${dirname}:"*
. :A
를 zsh
포함하여 대부분의 다른 껍질에는 슬프게도 존재하지 않는 놀라운 현상 bash
입니다. 인용 man zshexpn
:
A : a
수정 자 처럼 파일 이름을 절대 경로로 바꾼 다음 realpath(3)
라이브러리 함수를 통해 결과를 전달하여 심볼릭 링크를 확인합니다. 참고 :이없는 시스템에서 realpath(3)
라이브러리 기능을 심볼릭 링크가 있으므로 이러한 시스템에서 해결되지 a
와 A
동일합니다.
추가 질문이 없습니다.
천만에요. 안전한 포격을 즐기십시오. 이제 그럴 자격이 있습니다.