로그인 시 bash가 실행 중인 스크립트를 확인하세요.

로그인 시 bash가 실행 중인 스크립트를 확인하세요.

bash 터미널을 시작한 후 PATH 변수에 중복된 항목이 포함되어 있음을 발견했습니다. 내 터미널이 시작되었습니다로그인 쉘, ~/.bash_profile소스도 마찬가지이고 그 뒤에는 ~/.profile및 가 있습니다 ~/.bashrc. ~/.profile중복된 경로 항목을 생성하는 경우에만 해당됩니다 .

현명하게 말하면 파일을 가져와야 하는 순서는 다음과 같습니다.

Sourced /etc/profile
Sourced /etc/bash.bashrc
Sourced .bash_profile
Sourced .profile
Sourced .bashrc

누군가 이것을 "PATH 변수에 중복 항목이 포함되어 있습니다"의 중복으로 표시하기 전에 계속 읽어 보십시오.

처음에는 ~/.profile두 번 가져오는 것과 관련이 있다고 생각하여 파일을 가져올 때마다 로그 파일에 파일을 썼는데 놀랍게도 항목이 하나만 기록되어 한 번만 가져왔다고 했습니다. 더욱 놀라운 점은 의 항목을 주석 처리해도 해당 항목 이 여전히 변수 ~/.profile에 나타난다는 것입니다 . PATH이로 인해 나는 세 가지 결론에 도달하게 되었는데, 그 중 하나는 금방 배제되었습니다.

  1. Bash는 유효한 bash 주석을 무시하고 주석 처리된 코드를 계속 실행합니다.
  2. ~/.profile출력(예: 로그 파일)을 인쇄하는 모든 코드를 읽고 무시하는 스크립트가 있습니다.
  3. 내 다른 사본은 ~/.profile다른 곳에서 얻었습니다.

첫 번째는 빠른 테스트 덕분에 사실이 아니라는 결론을 빠르게 내릴 수 있었습니다. 두 번째와 세 번째 옵션은 도움이 필요한 곳입니다.

터미널이 시작될 때 실행되는 스크립트 목록을 어떻게 수집합니까?나는 echobash에서 왔는지 확인하기 위해 검사 중인 파일에서 이것을 사용하고 있지만 터미널이 입력을 시작할 준비가 되었을 때 실행을 추적하는 결정적인 방법을 찾아야 합니다.

위의 방법이 가능하지 않은 경우 실행 중인 스크립트를 볼 수 있는 다른 곳을 제안할 수 있는 사람이 있나요?.


향후 참조

이것은 내 경로에 추가하기 위해 지금 사용하고 있는 스크립트입니다.

function add_to_path() {
    for path in ${2//:/ }; do
        if ! [[ "${!1}" =~ "${path%/}" ]]; then # ignore last /
            new_path="$path:${!1#:}"
            export "$1"="${new_path%:}" # remove trailing :
        fi
    done
}

나는 이것을 다음과 같이 사용합니다 :

add_to_path 'PATH' "/some/path/bin"

스크립트는 경로를 추가하기 전에 변수에 경로가 이미 존재하는지 확인합니다.

zsh 사용자의 경우 동일한 방법을 사용할 수 있습니다.

# prepends the given path(s) to the supplied PATH variable
# ex. add_to_path 'PATH' "$(go env GOPATH)/bin"
function add_to_path() {
    # (P)1 path is expanded from $1
    # ##: Removes leading :
    local -x pth="${(P)1##:}"
    # (s.:.) splits the given variable at :
    for p in ${(s.:.)2}; do
        # %%/ Remove trailing /
        # :P Behaves similar to realpath(3)
        local p="${${p%%/}:P}"
        if [[ ! "$pth" =~ "$p" ]]; then
            pth="$p:$pth"
        fi
    done
    export "$1"="${pth%%:}"
}

2018년 8월 28일 수정

이 스크립트로 할 수 있는 또 다른 일은 경로 수정이었습니다. 그래서 내 파일 시작 부분에서 .bashrc다음과 같이 했습니다.

_temp_path="$PATH"
PATH='/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/sbin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin'
add_to_path 'PATH' "$_temp_path"
unset _temp_path

PATH무엇부터 시작해야 하는지 에 따라 다릅니다 . 결정하기 전에 확인해 PATH보세요.

답변1

시스템에 있는 경우 strace셸에서 열린 파일을 나열할 수 있습니다.

echo exit | strace bash -li |& grep '^open'

( 대화형 로그인 쉘을 나타냅니다. 대화형 비로그인 쉘 -li에만 사용됩니다 .)-i

그러면 쉘이 열었거나 열려고 시도한 파일 목록이 표시됩니다. 내 시스템에서는 다음과 같습니다.

  1. /etc/profile
  2. /etc/profile.d/*(의 다양한 스크립트 /etc/profile.d/)
  3. /home/<username>/.bash_profile(실패했습니다. 해당 파일이 없습니다.)
  4. /home/<username>/.bash_login(실패했습니다. 해당 파일이 없습니다.)
  5. /home/<username>/.profile
  6. /home/<username>/.bashrc
  7. /home/<username>/.bash_history(명령줄의 기록; 이것은 스크립트가 아닙니다)
  8. /usr/share/bash-completion/bash_completion
  9. /etc/bash_completion.d/*(자동 완성 기능을 제공하는 다양한 스크립트)
  10. /etc/inputrc(키 바인딩 정의; 이것은 스크립트가 아닙니다)

자세한 man strace내용은.

답변2

strace이 질문 은 여기에서 너무 멀기 때문에 다시 묻습니다 .

bash를 실행하고 출력에서 ​​추출합니다. bash가 내부적으로 무엇을 하고 있는지 출력하고 bash에게 즉시 종료하라고 지시하는 -li대화형 로그인입니다 . 명령이나 별칭을 필터링 하는 데 사용됩니다 .-x-c exitsedsource.

/bin/bash -lixc exit 2>&1 | sed -n 's/^+* \(source\|\.\) //p'

답변3

~/.profile이 두 번 로드되는 이유에 대한 설명을 고려하십시오.

GUI를 실행하는 대부분의 Linux 시스템에서 ~/.profile 파일은 GUI를 통해 로그인할 때 처리됩니다. 이후에 터미널 창을 열 때 매우 구체적인 사용 사례가 없으면 일반적으로 셸을 로그인 셸로 시작해서는 안 됩니다. Linux 배포판의 대부분의 GUI는 기본적으로 이 동작을 올바르게 구현합니다.

참고로 답변의 두 번째 단락을 읽을 수 있습니다https://unix.stackexchange.com/a/119675/521859이것이 설명됩니다.

GUI에서 터미널을 시작하고 쉘에 로그인 옵션이 필요하다고 지정하면 ~/.profile이 다시 로드될 가능성이 높습니다.

TTY 또는 SSH 로그인을 통해 비교하여 이러한 경우인지 확인한 다음 중복 구성 문제가 해결되었는지 확인할 수 있습니다. 또는 GUI 터미널 프로그램에서 쉘 로그인 옵션을 확인/비활성화할 수 있습니다.

감사합니다, 제프리

관련 정보