$ PATH에 중복 된 항목이 문제입니까?


45

나는 bashrc의 친구 중 일부를 소싱합니다. 그래서 $ PATH 변수에 중복 항목이 생깁니다. 명령을 시작하는 데 시간이 오래 걸리는 문제인지 확실하지 않습니다. bash에서 $ PATH는 내부적으로 어떻게 작동합니까? 더 많은 경로가 있으면 시작 시간이 느려 집니까?




답변:


42

더 많은 항목이 $PATH있다고해서 시작 속도가 느려지지는 않지만 셸 세션에서 특정 명령을 처음 실행할 때마다 속도가 느려집니다 (bash가 캐시를 유지하기 때문에 명령을 실행할 때마다는 아닙니다). 특히 느린 파일 시스템 (예 : NFS, Samba 또는 기타 네트워크 파일 시스템 또는 Cygwin)이없는 경우 속도 저하를 거의 감지 할 수 없습니다.

당신이 $PATH시각적으로 검토 할 때 중복 항목도 약간 성가시다 , 당신은 더 부스러기를 통과해야합니다.

중복 항목을 추가하지 않아도됩니다.

case ":$PATH:" in
  *":$new_entry:"*) :;; # already there
  *) PATH="$new_entry:$PATH";; # or PATH="$PATH:$new_entry"
esac

참고 : 다른 사람의 쉘 스크립트를 소싱한다는 것은 그가 작성한 코드를 실행하는 것을 의미합니다. 즉, 친구는 언제든지 친구에게 계정에 대한 액세스 권한을 부여합니다.

참고 사항 : .bashrc설정 $PATH하거나 다른 환경 변수 가 올바른 장소가 아닙니다 . 환경 변수는에서 설정해야합니다 ~/.profile. 참조 어떤 설정 파일은 떠들썩한 파티와 환경 변수를 설정하는 데 사용되어야 하는가? , .bashrc와 .bash_profile의 차이점 .


8
+1 : "친구에게 귀하의 계정에 대한 액세스 권한 부여"가 충분히 강조 될 수 없음 해를 끼치려는 시도가 없더라도 그들의 대본은 그들이 필요로하는 것일 수 있으며 소스를 먹을 때 여전히 점심을 먹을 수 있습니다.
msw 2016 년

이 솔루션의 한 가지 가능한 문제는 $ new_entry가 이미 PATH의 첫 번째 항목 인 경우 ": $ new_entry :"가 일치하지 않는 것입니다. 초기 ':'콜론을 제외하여 내 프로필 에서이 문제를 해결했습니다.
Jeff Bauer

@JeffBauer 문제가 보이지 않습니다. 항목이 처음이거나 마지막 인 경우에도 일치하도록 사용 case :$PATH:하고 사용 하지 않습니다 case $PATH.
Gilles 'SO- 악마 그만'

31

사람들이 PATH 변수에서 다음을 사용하여 복제본을 정리하는 것을 보았습니다 awk.

PATH=$(printf "%s" "$PATH" | awk -v RS=':' '!a[$1]++ { if (NR > 1) printf RS; printf $1 }')

자신의 bashrc에 추가하고 다른 파일을 실행하기 전에 다른 파일을 소스로 만들 수 있습니다.

대안은 유틸리티 를 사용 하는pathmerge 것 입니다.

속도 문제와 관련하여 이것은 쉘의 시작 시간에 큰 영향을 미치지 않지만 특히 명령이 경로에서 발견되지 않고 동일한 경로를 통해 검색을 반복하는 경우 명령에 대한 탭 완성을 수행하는 데 시간을 절약 할 수 있습니다 폴더를 찾고 있습니다.

보안에 대한주의 사항 : 당신이해야 정말 주의 질 '경고 여기에 보안에 대한합니다. 다른 사용자가 소유 한 파일을 소싱함으로써 쉘을 시작할 때마다 해당 사용자에게 자신의 코드를 실행할 수있는 무료 패스를 제공합니다. 암호를 사용하여 해당 사용자를 신뢰하지 않으면 해당 셸 파일을 소싱해서는 안됩니다.


6
나는 awk one-liner를 좋아하지만 후행 ORS ':'를 인쇄합니다. 그래서 읽도록 수정했습니다PATH=$(echo "$PATH" | awk -v RS=':' -v ORS=":" '!a[$1]++{if (NR > 1) printf ORS; printf $a[$1]}')
gkb0986

후행 :은 외관상의 문제가 아닙니다. .경로에 추가하는 것과 동일하며 잠재적으로 위험합니다.
wisbucky

gkb0986의 수정 사항을 포함하도록 답변을 편집했습니다.
Tim Lesher

그 이유 @TimLesher 나는 대답은 나를 위해 일을하지 않는다는 것입니다 의해에보다 편집 없었어요 ....하고 (작업을 포함 않습니다없이 원래 없는 후행 구분을 떠나이. 나는 그 차이가 무엇인지 모르는 .
갈렙

1
@ gkb0986 경로에 PATH = / bin : / foo \ bar : / usr / bin과 같이 이스케이프 된 공간이 포함되어 있으면이 솔루션은 여전히 ​​실패합니다. unix.stackexchange.com/a/124517/106102
maharvey67에서

13

@Gilles 답변에 따라 입력을 최소화하는 함수로 래핑 할 수 있습니다.

function addToPATH {
  case ":$PATH:" in
    *":$1:"*) :;; # already there
    *) PATH="$1:$PATH";; # or PATH="$PATH:$1"
  esac
}

addToPATH /Applications/AIRSDK_Compiler/bin
addToPATH ~/.local/lib/npm/bin

1
가장 실용적으로 사용 가능한 (높은 수준의 답변) 답변입니다.
ijoseph

3

첫 번째 일치 만 $PATH실행되므로 이후의 모든 항목은 처리되지 않습니다. 그렇기 때문에 때때로 $PATH환경이 예상대로 작동하도록 항목의 순서를 수정해야합니다 .

귀하의 질문에 대답하기 위해 : 이것은 느린 시작의 원인이되어서는 안됩니다.


1
그러나 존재하지 않는 명령을 입력하면 시간이 더 걸립니다. 동일한 폴더를 두 번 검색하여 명령을 찾습니다.
balki

@balki TAB? 로 명령을 완료하는 것을 의미 합니까? 이 경우 정의를 완료 한 것이 아닌지 확인해야합니다 complete -c which -a. -a매개 변수를 삭제해야합니다 . 다음 명령을 실행하여이를 확인할 수 있습니다 complete | grep which..
Rajish 2016 년

디렉토리를 찾기 전에 여러 번 있지 않은 동일한 디렉토리를 검색하면 여전히 문제가 될 수 있습니다.
Random832

-1

내 PATH에 중복 항목을 방지하기 위해 ~ / .bash_profile 및 ~ / .bashrc에 다음을 입력해야했습니다.

PATH=$(echo $(sed 's/:/\n/g' <<< $PATH | sort | uniq) | sed -e 's/\s/':'/g')

주요 단점은 PATH 항목을 정렬한다는 것입니다.하지만 나는 그걸로 살 수 있다고 생각합니다.


검색 경로의 순서는 매우 중요합니다.
Steven Shaw
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.