소스에서 컴파일할 때 Bash가 다르게 동작하는 이유는 무엇입니까?

소스에서 컴파일할 때 Bash가 다르게 동작하는 이유는 무엇입니까?

나는 달렸다

git clone https://git.savannah.gnu.org/git/bash.git
cd bash/
./configure
make
./bash

새로 시작된 Bash 인스턴스는 상위 셸, 특히 셸 프롬프트를 정의하는 PS1 변수에서 환경을 상속받지 않은 것으로 나타났습니다. 상속이 적용됩니다/bin/bash

소스 파일 목록/bin/bash와 같다./bash

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

편집: aviro가 언급했듯이 PS1은 내보내지 않고 정의되었으므로 내보내려고 하면 상속되었으므로 원래 질문이 잘못되었습니다. 내 컴퓨터에서 PS1은 두 개의 파일에 정의되어 있습니다. /etc/bash/bashrc

# If not running interactively, don't do anything
[[ $- != *i* ]] && return
[[ $DISPLAY ]] && shopt -s checkwinsize
PS1='[\u@\h \W]\$ '

그리고/etc/bash/bashrc.d/artix.bashrc

if ${use_color} ; then
    if [[ ${EUID} == 0 ]] ; then
        PS1='\[\033[01;31m\][\h\[\033[01;36m\] \W\[\033[01;31m\]]\$\[\033[00m\] '
    else
        PS1='\[\033[01;36m\][\u@\h\[\033[01;37m\] \W\[\033[01;36m\]]\$\[\033[00m\] '
    fi
else
    if [[ ${EUID} == 0 ]] ; then
        # show root@ when we don't have colors
        PS1='\u@\h \W \$ '
    else
        PS1='\u@\h \w \$ '
    fi
fi

./bashPS1을 실행할 때 \s-\v\$이유를 모르겠습니다.

모든 소스 파일을 나열하는 명령은 run을 사용할 때 두 파일이 모두 source files 여야 ./bash하지만 어떤 이유로 그렇지 않거나 쉘이 다른 유형/모드로 시작되었음을 보여줍니다. 왜?

답변1

PS1먼저, 이것이 일반적이라는 것을 이해해야 합니다.쉘 변수, 이는 자녀에게 상속되지 않음을 의미합니다. 따라서 환경 변수를 명시적으로 실행 export PS1=...하고 생성 하지 않는 한, 각각의 새로운 프로세스는 PS1상위 프로세스 대신 rc 파일에서 bash(및 기타 쉘 변수)를 가져옵니다 . 따라서 먼저 PS1정확한 정의가 PS1어디에 있는지 알아내야 합니다.

다음 방법으로 내보낼 수 있습니다 PS1.

export PS1

그런 다음 를 실행하면 이 경우 새 쉘이 상속되는 ./bash것을 볼 수 있습니다 .PS1


그렇다면 컴파일이 bashrc 파일에서 기대하는 쉘 변수를 얻지 못하는 이유는 무엇입니까?PS1

내 추측은 다음과 같습니다. 많은 시스템에서는 PS1그렇습니다 /etc/bash.bashrc. 그러나 모든 bash버전에서 이 파일을 읽을 수 있는 것은 아닙니다. bash컴파일 방법에 따라 다릅니다 . 좋은 경험 법칙은 bash매뉴얼 페이지를 확인하는 것입니다. 예를 들어,우분투당신이 볼 수 있는 것:

로그인 쉘이 아닌 대화형 쉘을 시작하면 bash는 다음 명령을 읽고 실행합니다./etc/bash.bashrc~/.bashrc이러한 파일이 존재하는 경우. --norc 이 옵션을 사용하면 이를 억제할 수 있습니다. file 옵션은 bash가 및 대신 파일에서 --rcfile명령을 읽고 실행하도록 합니다./etc/bash.bashrc~/.bashrc

하지만 /etc/bash.bashrc본문에는 언급조차 되지 않습니다.bash매뉴얼 페이지[git]에서 다운로드한 것:

로그인 쉘이 아닌 대화형 쉘을 시작하면 bash는 ~/.bashrc파일이 존재하는 경우 명령을 읽고 실행합니다. --norc이 옵션을 사용하면 이를 억제할 수 있습니다. file --rcfile옵션은 bash가 ~/.bashrc.

또한,README데비안 문서에서 다음 bash을 볼 수 있습니다:

5. 은 무엇입니까 /etc/bash.bashrc? 기록이 없는 것 같습니다.

데비안 버전의 bash는 읽기 우선 오류를 발생시키는 특수 옵션( )을 사용하여 -DSYS_BASHRC컴파일 됩니다.bash/etc/bash.bashrc~/.bashrc

따라서 git사용중인 저장소에서 볼 수 있습니다 config-top.h정의 라인은 SYS_BASHRC기본적으로 주석 처리됩니다.

/* System-wide .bashrc file for interactive shells. */
/* #define SYS_BASHRC "/etc/bash.bashrc" */

따라서 기본 빌드는 시작 시 이를 읽지 bash않으며 , 거기에서 정의해도 가져오지 않습니다./etc/bash.bashrcPS1

이 줄의 주석을 제거하는 경우:

#define SYS_BASHRC "/etc/bash.bashrc"

다시 실행해 보면 새 콘텐츠에 예상한 변수가 표시될 것 make같습니다 .bashPS1

관련 정보