기본적으로 OSX 로그인 쉘에 대화식 쉘이있는 이유는 무엇입니까?


43

리눅스와 모든 유닉스 시스템에서 터미널 에뮬레이터는 기본적으로 대화식의 비 로그인 쉘을 실행합니다. 이것은 bash의 경우 시작된 쉘이 다음을 수행함을 의미합니다.

로그인 쉘이 아닌 대화식 쉘이 시작되면 bash는 /etc/bash.bashrc~/.bashrc이 파일이 존재하는 경우 및 에서 명령을 읽고 실행 합니다. 이 --norc 옵션 을 사용하여 금지 할 수 있습니다 .

--rcfile 파일 옵션을 읽고 대신 파일에서 명령을 실행하는 bash는 강제로 /etc/bash.bashrc~/.bashrc.

그리고 로그인 쉘의 경우 :

bash가 대화식 로그인 쉘 또는 --login옵션이 있는 비 대화식 쉘로 호출되면 /etc/profile파일이 존재하는 경우 먼저 파일에서 명령을 읽고 실행 합니다. 해당 파일을 읽은 후, 그것은을 찾습니다 ~/.bash_profile, ~/.bash_login그리고 ~/.profile, 순서대로, 그리고 읽고 존재하고 읽을 수있는 첫 번째에서 실행하는 명령을.

--noprofile쉘이 동작을 억제하기 시작할 때 옵션을 사용할 수있다.

OSX에, 그러나, 기본 쉘 (bash는 인) 기본 터미널 (Terminal.app) 실제로 소스에서 시작 ~/.bash_profile또는 ~.profile등 즉,이 로그인 쉘과 같은 역할을합니다.

주요 질문 : 왜 기본 대화식 쉘이 OSX에서 로그인 쉘입니까? OSX가 왜 이것을 선택 했습니까? 즉, 변경 사항을 언급하는 쉘 기반 항목에 대한 모든 지침 / 자습은 ~/.bashrcOSX 에서 실패하거나 그 반대의 경우도 마찬가지입니다 ~/.profile. 그럼에도 불구하고 애플에서 많은 고발이 제기 될 수 있지만, 무능하거나 바보 같은 개발자를 고용하는 것은 그들 중 하나가 아닙니다. 아마도 이것에 대한 충분한 이유가 있었을 것입니다. 왜 그렇습니까?

하위 질문 : Terminal.app은 실제로 대화 형 로그인 셸을 실행합니까, 아니면 bash의 동작을 변경 했습니까? 이것은 Terminal.app에만 해당됩니까, 아니면 터미널 에뮬레이터와 무관합니까?


2
Terminal.app는 로그인 쉘을 실행합니다. 애플이 왜 그렇게했는지 모르겠다.
Gilles 'SO- 악의를 멈추십시오'1

답변:


33

그것의 방법 가정 하면 쉘 프롬프트 얻을, 둘 때 작업이 시점에서, 그이다 .profile하고 .bashrc있었다 실행해야합니다. 해당 지점에 도달하는 방법에 대한 특정 세부 사항은 보조 관련이 있지만 파일 중 하나가 전혀 실행되지 않으면 설정이 불완전한 셸이 있습니다.

Linux (및 기타 X 기반 시스템)의 터미널 에뮬레이터 가 스스로 실행될 필요 가없는 .profile이유는 X에 로그인 할 때 이미 실행되었을 것이기 때문입니다 .profile. 서브 프로세스에 의해 상속되므로 로그인 할 때 (예 :를 통해 .Xsession) 한 번만 실행되는 한 추가 서브 쉘은 다시 실행할 필요가 없습니다.

현상태대로 데비안 위키 페이지 앨런 Shutko 씨에 의해 연결이 설명 :

"왜 .bashrc다른 파일 .bash_profile입니까? 그렇다면 이것은 오늘날의 워크 스테이션에 비해 머신 속도가 매우 느 렸을 때 주로 역사적 이유로 이루어집니다. 특히 많은 작업을 수행하는 머신에서 명령을 처리 .profile하거나 .bash_profile시간이 오래 걸릴 수 있습니다. 자식 명령으로 전달 될 수있는 환경 변수를 생성하는 어려운 초기 설정 명령이 입력됩니다 .bash_profile. 상속되지 않은 임시 설정과 별칭은 입력됩니다. 에 .bashrc그래서 그들은 할 수있는 모든 서브 쉘에 의해 다시 읽어보십시오. "

OSX GUI는 .profile전역 설정을로드하는 자체 방법이 있기 때문에 로그인 할 때 OSX GUI가 실행되지 않습니다 . 그러나 수단 OSX에 터미널 에뮬레이터가 있다는 것을 하지 실행할 필요를 .profile(그것이 로그인 쉘이 있다고 쉘에게 그것을 출시를 말함으로써), 그렇지 않으면 당신은 잠재적 불구 쉘로 끝날 것입니다.


이제 대부분의 다른 쉘과 공유하지 않는 일종의 바보 같은 bash .bashrc는 로그인 쉘로 시작하면 자동으로 실행되지 않는다는 것입니다 . 이에 대한 표준 해결 방법은 다음과 같은 명령을 포함시키는 것입니다 .bash_profile.

[[ -e ~/.profile ]] && source ~/.profile    # load generic profile settings
[[ -e ~/.bashrc  ]] && source ~/.bashrc     # load aliases etc.

또는 전혀 없을 수도 .bash_profile있고 필요한 경우 일반 .profile파일 에 bash 특정 코드를 포함시켜 실행할 수도 .bashrc있습니다.

OSX가 기본값 .bash_profile이거나 .profile 그렇지 않으면 버그 일 것입니다. 어쨌든 적절한 해결 방법은 해당 행을에 추가하는 것 .bash_profile입니다.


편집 : strugee notes 에서와 같이 OSX의 기본 쉘은 tcsh였습니다.이 점에서 동작은 훨씬 더 안전합니다. 대화식 로그인 쉘로 실행될 때 tcsh는 자동으로 .profile .tcshrc /를 읽으 .cshrc므로 .bash_profile트릭 과 같은 해결 방법이 필요하지 않습니다. 위에 표시됩니다.

이를 바탕으로 OSX가 적절한 기본값을 제공하지 못하면 .bash_profiletcsh에서 bash로 전환했을 때 Apple의 사람들은 bash의 시작 동작 에서이 작은 사마귀를 알지 못했기 때문에 99 % 확신합니다 . tcsh를 사용하면 OSX 터미널 에뮬레이터 인 Just Plain Works에서 로그인 쉘로 tcsh를 시작하는 등의 트릭이 필요하지 않으며 그러한 문제없이 올바른 작업을 수행합니다.


1
고마워, 나는 모든 것을 알고 있었다. 내 질문은 OSX가 .bashrc관련이없는 방식으로 설정하도록 선택 했 습니까? 왜 모든 쉘이 쉘을 로그인하도록 선택 했습니까? 내가 알 수있는 한, 당신의 마지막 문장만이 그것을 해결하고 단지 버그라고 말합니다.
terdon

1
아니요, 문제는 터미널 에뮬레이터에서 로그인 쉘을 시작한다는 것입니다. 도트 파일은 기본 bash 동작이며, 로그인 쉘을 시작하면 bashrc 등이 ​​아닌 프로파일 등을 읽습니다. 문제는 로그인 쉘이 아닌 쉘을 실행하는 이유입니다.
terdon

2
예, 앨런 둘 다 리눅스와는 달리, OSX가 실행되지 않습니다, 그것 때문에 고 설명했다 .profile때 GUI로 사용자가 로그인, 그들은 같은 환경 변수를 얻기 위해 나중에 실행해야하므로 $PATH일반적으로 설정되어, .profile올바르게, 구성을 . 부작용으로, 이로 인해 .bashrc소스가 생성 되지 않는다는 사실 은 버그입니다. bash 또는 OSX의 버그인지 여부에 대해서는 논쟁 할 수 있지만 환경 변수 와 bash 구성 설정이 모두로드 되도록 올바른 동작을 한다는 사실은 변경되지 않습니다 . .profile.bashrc
Ilmari Karonen

1
.bashrc소스 를 갖는 .profile것은 모든 서브 쉘이 다시 실행되도록하기 때문에 나쁜 생각 .profile입니다. 다른 것이 없으면 일반적인 .profile관용구가 export PATH = "$HOME/bin:$PATH"중복 항목을 앞에 추가하는 것과 같습니다 $PATH. .profile소스 .bashrc를 갖는 것이 훨씬 더 합리적이지만, 실행중인 쉘이 실제로 bash인지 확인한 후에 만 ​​가능합니다. 갖는 .bash_profile소스를 모두 .profile .bashrc 나는 위의 제안,,, IMO, 가장 현명한 방법입니다.
Ilmari Karonen

2
그리고 "왜 그들이 로그인 쉘을 사용합니까?" .profile"왜 로드해야 합니까?"인데, "왜 소스 .bashrc를 제공 하지 .profile않습니까?" 이다 "그것은 버그 때문에!" 진지하게, 그것은 의도적 인 결정이 될 수 없습니다. Mac 생태계에서 쉘은 대부분의 사용자가 다루지 않아도되는 2 급 시민이기 때문에 아마도 간과했을 것입니다. (Ps. 역사적 설명 은 strugee의 답변 을 참조하십시오. tcsh에서 bash 로의 전환에서 거의 확실하게 회귀합니다.)
Ilmari Karonen

14

X 터미널 응용 프로그램이 기본적으로 비 로그인 셸을 실행하는 주된 이유는 처음에 .Xsession이 .profile을 실행하여 초기 로그인 항목을 설정했기 때문입니다. 그런 다음 모든 것이 이미 설정되었으므로 터미널 응용 프로그램을 실행할 필요가 없으므로 .bashrc를 실행할 수 있습니다. 이것이 왜 중요한지에 대한 토론은 https://wiki.debian.org/DotFiles에 있습니다 .

xdm을 예로 들어 봅시다. pierre는 어느 날 휴가에서 돌아와서 시스템 관리자가 데비안 시스템에 xdm을 설치했음을 알게됩니다. 그는 제대로 로그인하고 xdm은 .xsession 파일을 읽고 fluxbox를 실행합니다. 그가 잘못된 로케일로 오류 메시지를받을 때까지 모든 것이 정상인 것 같습니다! .bash_profile에서 LANG 변수를 대체하고 xdm이 .bash_profile을 읽지 않으므로 LANG 변수는 이제 fr_CA 대신 en_US로 설정됩니다.

이 문제에 대한 순진한 해결책은 "xterm"을 시작하는 대신 "xterm -ls"를 시작하도록 창 관리자를 구성 할 수 있다는 것입니다. 이 플래그는 xterm에게 일반 쉘을 시작하는 대신 로그인 쉘을 시작해야 함을 알려줍니다. 이 설정에서 xterm은 / bin / bash를 생성하지만 인수 벡터에 "-/ bin / bash"(또는 "-bash")를 넣으므로 bash는 로그인 쉘처럼 작동합니다. 이것은 새 xterm을 열 때마다 / etc / profile 및 .bash_profile (내장 bash 동작)을 읽은 다음 .bashrc (.bash_profile이 그렇게하기 때문에)를 읽습니다. 이것은 처음에는 잘 작동하는 것처럼 보일 수 있습니다. 그의 도트 파일은 무겁지 않으므로 지연조차도 알지 못하지만 더 미묘한 문제가 있습니다. 또한 플럭스 박스 메뉴에서 직접 웹 브라우저를 시작합니다. 웹 브라우저는 플럭스 박스에서 LANG 변수를 상속받습니다. 이제는 잘못된 로케일로 설정됩니다. 따라서 그의 xterm은 훌륭하고 xterm에서 시작된 것은 괜찮을 수 있지만 웹 브라우저는 여전히 잘못된 로케일의 페이지를 제공합니다.

OS X에서 사용자 환경은 여러 개의 셸 스크립트로 시작되지 않으며 시작시 언제든지 .profile을 제공하지 않습니다. (환경 변수를 설정하는 것이 훨씬 성가시다는 것을 의미하기 때문에 부끄러운 일이지만, 그런 것은 인생입니다.) 그것이 아니기 때문에 언제 .profile을 실행합니까? 당신이 ssh'd 경우 에만 ? 많은 상자가 ssh의 대상이 될 수 없기 때문에 무의미 해 보입니다. 터미널이 기본적으로 로그인 쉘을 실행하도록하여 .profile이 언젠가 실행되도록 할 수 있습니다.

그렇다면 .bashrc는 어떻습니까? 쓸모 없습니까? 아닙니다. VT100 시절에는 그 ​​목적이 여전히 남아 있습니다. 터미널 창을 여는 것 이외의 쉘을 열 때마다 사용됩니다. 따라서 Emacs 또는 vi에서 쉘을 제거하거나 su 사용자를 수행하는 경우.


1
인용하고있는 데비안 페이지는 OSX가 기본적으로 모든 쉘에 쉘을 로그인하기로 결정한 이유가 아니라 왜 데비안의 .profile소스를 설명합니다 .bashrc. 실제로, 당신은 내 또 다른 질문에 대답 하고 있습니다. 감사합니다! 그러나 귀하의 답변은 OSX 선택을 설명하지 않으며 데비안 인용문은 내가 말할 수있는 한 여기와 완전히 관련이 없습니다 (단지 요점을 놓친 경우 알려주십시오). OSX 방식은 .bashrc등을 쓸모 없게 만들고 .profile더 이상 유용 하지 않습니다 .
terdon

4

그들이 왜 그런 짓을했는지 모르겠습니다. 그러나 여기 내 추측이 있습니다.

우선 GNU / Linux 시스템에서는 물론 vt1, vt2 등으로 전환 할 수 있습니다. 로그인 쉘을 얻을 수 있습니다. OS X 시스템에서는 이에 상응하는 것이 없습니다. 유닉스 기반에 접근하는 유일한 방법은 터미널 에뮬레이터 또는 단일 사용자 모드를 통한 것입니다. 따라서 OS X에서 에뮬레이터의 기본값은 전체 시스템의 기본값입니다.

자, 왜 디폴트를 로그인 쉘로 만들겠습니까? 내가 이것을 생각할 수있는 몇 가지 이유 (읽기 : 많지 않음)가 있습니다.

  • 상자에 SSH를 설치하면 일관된 사용자 경험을 제공합니다. (특히 OS X 서버 에디션에 중요합니다. 아마도 OS X 서버를 실행하고 있다면 초보자 일 것입니다.)
  • 이전에 OS X의 기본 쉘은이었습니다 tcsh. 이것은 당신이 얻을 수있는 것처럼 추측이지만, tcsh일반적으로 로그인 쉘로 실행될 때 무언가를하고 역사적인 패턴이 붙어있을 수 있습니다. (그러나 나는 의심합니다. 어쩌면 더 오래된 규칙 중 하나가 우리에게 말할 수 있습니다.)
  • "우리는 애플입니다. 우리는 지구상에서 가장 큰 유닉스 배포판의 공급 업체입니다. 우리의 결정이 사소한 이유는 중요하지 않습니다. 결정을 내리면 도구가이를 처리해야합니다."

솔직히, 나는 ~ 6 년 동안 다윈을 사용해 왔는데이 질문에 제대로 대답 할 수 없습니다. 나에게도 의미가 없습니다.

귀하의 하위 질문에 답변하기 위해 bash패치 또는 기타 사항이 없습니다 (적어도 이것에 대해서는). 기본 터미널 에뮬레이터는 기본적으로 로그인 쉘을 실행하며 아마도 iTerm이 로그인 쉘을 복사합니다.


1
대화 형 로그인 셸 시작했을 때, tcsh의 소스 : 그 행동이 훨씬 더 온건 배쉬보다이 점에서 때문에, tcsh에서 언급 +1 모두 .profile.tcshrc/ .cshrc내 대답에 준 것과 같은 어떤 kluges을 요구하지 않고. 이를 감안할 때이 동작은 tcsh에서 bash로 전환하여 발생하는 고정되지 않은 회귀라고 생각합니다.
Ilmari Karonen

@IlmariKaronen 당신은 (여기 뜻 ) tcsh의 소스가 .login.tcshrc/ .cshrc? tcsh가 소싱하는 것은 의미가 없습니다 .profile. 일반적으로 받아들이지 않는 sh구문의 명령이 포함되어 있습니다 tcsh. macOS는 없지만 /bin/tcshUbuntu 16.04에서 로그인 쉘을 만들었습니다 . .profile소스가 아닙니다. tcsh의 (1) 해당 파일을 언급하거나이 수행되지 않습니다 tcsh의 (1) .
Eliah Kagan

3

이것은 현재 상태에 대한 업데이트입니다. 새로운 MacOSX 버전이 출시되고 로그인 동작이 변경되어 응답이 오래되었습니다.

이 질문은 2014 년에 질문 및 답변을 받았습니다. 나는 다른 리눅스 배포판과 BSD에서 사용하도록 공통 .bashrc & .bash_profile 세트를 구축하려고 시도하면서 주제를 연구하고 있습니다.

최근에 Sierra가 설치된 중고 Mac Mini를 구입 했으므로 이제 10.6, 10.10, 10.11 및 10.12 시스템이 있습니다. 이전 버전의 단서를 남겨두고 이전 버전을 제거했지만 10.12 Sierra 설치는 그대로 유지됩니다.

결과 : 10.12 Sierra에는 기본 .bashrc, .bash_profile 또는 .profile이 생성되지 않습니다. / etc에는 bashrc, bashrc_Apple_Terminal 및 프로파일이 있습니다. / etc / profile의 내용 :

# System-wide .profile for sh(1)

if [ -x /usr/libexec/path_helper ]; then
    eval `/usr/libexec/path_helper -s`
fi

if [ "${BASH-no}" != "no" ]; then
    [ -r /etc/bashrc ] && . /etc/bashrc
fi

/ etc / bashrc의 내용 :

# System-wide .bashrc file for interactive bash(1) shells.
if [ -z "$PS1" ]; then
   return
fi

PS1='\h:\W \u\$ '
# Make bash check its window size after a process completes
shopt -s checkwinsize

[ -r "/etc/bashrc_$TERM_PROGRAM" ] && . "/etc/bashrc_$TERM_PROGRAM"

/ etc / bashrc_Apple_Terminal 스크립트는 PROMPT_COMMAND 변수를 설정하고 각 터미널의 세션 상태를 유지하기위한 메커니즘을 설정합니다. 터미널 앱이 종료되면 앱이 다시 시작될 때 이전 세션의 상태가 복원됩니다. 그렇지 않으면, 거의 아무것도 (최소 $ PS1) / etc / bashrc에 설정되어 다른 사용자 정의 (실제 $ PS1, 별명, 함수)는 ~ / .bashrc 및 $ PATH 설정에서 .bash_profile (또는 .profile)에 설정됩니다. .bash_profile에 의해 제공됨).

로그인 세션 시작의 기본 동작이 표시되고 편집 될 수 있다는 점을 제외하고 iTerm2가 터미널 앱과 동일한 방식으로 작동 함을 확인했습니다.

X11 (현재 XQuartz) XTerm 터미널 세션을 실행하면 Linux 시스템과 동일한 비 로그인 세션이 표시됩니다. .bash_profile (또는 .profile)을 건너 뛰고 .bashrc를 얻습니다.

그리고 내 대답은 다음과 같습니다.

터미널 앱은 xterm (TERM = xterm-256color)이라고 주장하지만 X11이 설치되어 있지 않으면 $ DISPLAY 변수를 설정하지 않습니다. 우리는 X 환경의 시뮬레이션을보고 있지만 실제 환경은 아닙니다. -X 스위치를 사용하여 다른 시스템에 SSH를 연결하면 (X11 전달 사용) $ DISPLAY 변수가 없으므로 실패합니다. X11을 설치 한 다음 다른 시스템에 SSH를 설치하면 X11 전달이 성공합니다.

결론 (및 짧은 답변) : 터미널 앱은 실제 X11 터미널이 아닙니다 ($ DISPLAY를 설정하지 않음). / etc / profile 및 ~ / .bash_profile 또는 ~ / .profile의 값을 설정하려면 로그인 세션이어야한다는 점에서 XTerm 세션보다 SSH 로그인과 훨씬 유사하게 작동합니다.


0

: 대답은 위의 대화 형 쉘은 로그인 기본적으로 맥 OS에 포탄입니다 이유 설명 의 설정을 /etc/profile, ~/.profile하지만 맥 OS에서, X 기반 시스템에서 비 로그인 쉘에 의해 상속됩니다 . 여기서는 항상 존재하기 때문에 macOS에서 항상 로그인 쉘을 사용해야 한다는 것을 상기하고 싶습니다 path_helper.

 cat /etc/profile # or cat /etc/zprofile
# System-wide .profile for sh(1)

if [ -x /usr/libexec/path_helper ]; then
    eval `/usr/libexec/path_helper -s`
fi

if [ "${BASH-no}" != "no" ]; then
    [ -r /etc/bashrc ] && . /etc/bashrc
fi

path_helper유틸리티는 디렉토리에있는 파일의 내용을 읽어 /etc/paths.d/etc/manpaths.d 와에 내용을 추가 PATH하고 MANPATH각각 환경 변수. 합니다 ( MANPATH이미 환경에서 설정되지 않은 환경 변수는 변경 될 수 없다.)

비 로그인 쉘을 사용하는 경우 일부 경로를 가져 오지 않습니다.

나는 개발자에 파일을 넣어하는 것이 항상 좋은 아이디어라고 생각 /etc/paths.d자신의 경로 값을 가져올 수 있지만, 같은 위치에 호출 바이너리를 심볼릭 링크하지 /usr/bin/bin. (기본값은 PATH입니다 /usr/bin:/bin:/usr/sbin:/sbin. 아니 모두가 브루 또는 MacPorts를에 사용자 정의 값을 추가를 사용합니다 PATH. 그래서 호출 명령의 심볼릭 링크를 넣어 안전한 장소는 항상이 아니다.)

의 파일 예는 다음과 같습니다 /etc/paths.d. 기본적으로 각 줄마다 하나의 값을 지정합니다.

 cat /etc/paths.d/Wireshark
/Applications/Wireshark.app/Contents/MacOS

참고:

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