로그인 셸과 비 로그인 셸의 차이점은 무엇입니까?


318

대화식 셸과 비 대화식 셸의 기본 차이점을 이해합니다. 그러나 로그인 쉘과 비 로그인 쉘을 정확히 구별하는 것은 무엇입니까?

비 로그인 대화식 쉘 사용에 대한 예제를 제공 할 수 있습니까 ?


45
" 로그인과 비 로그인 쉘을 구별해야하는 이유무엇 입니까?" 웹상의 많은 곳에서 이미 읽은 시작 파일의 관점에서 차이점이 무엇인지 알려줍니다 . 그러나 그들 중 누구도 만족스럽고 설득력있는 방법으로 "왜"에 대답하지 않는 것 같습니다. 하나 또는 다른 동작을 원하지 않는 사용 사례의 예 는 훌륭합니다.
Kal

2
@Kal 여기에 실제로 답변이 없기 때문에 이것은 다른 질문이어야합니다. 편집 : 실제로, 여기 있습니다 : 로그인 하지 않은 쉘을 통해 로그인 쉘입니까? .
Skippy le Grand Gourou

답변:


304

로그인 쉘은 대화식 세션에 로그인 할 때 사용자 ID로 실행되는 첫 번째 프로세스입니다. 로그인 프로세스는 쉘이 다음과 같은 규칙을 사용하여 로그인 쉘처럼 동작하도록 지시합니다. 인수 0 (일반적으로 쉘 실행 파일의 이름이며 -앞에 문자 가 붙어 있음) (예 : -bash일반적으로 bash.) 로그인 쉘은 일반적으로 : 환경 변수를 설정 같은 것들 /etc/profile~/.profile, 기존의 Bourne 쉘에 대한 ~/.bash_profile추가 배쉬에 대한 , /etc/zprofile~/.zprofilezsh을에 대한 , /etc/csh.login~/.loginCSH에 대한 등

텍스트 콘솔이나 SSH를 통해 또는로 로그인su - 하면 대화 형 로그인 셸이 나타납니다. X 디스플레이 관리자 에서 그래픽 모드 로 로그인하면 로그인 셸이 아닌 세션 관리자 또는 창 관리자가 나타납니다.

비 대화식 로그인 쉘 을 실행하는 경우는 거의 없지만 일부 X 설정은 디스플레이 관리자로 로그인 할 때 프로파일 파일을 읽도록 정렬합니다. 다른 설정 (배포판과 디스플레이 관리자에 따라 다름)은 읽 /etc/profile거나 ~/.profile명시 적으로 읽 거나 읽지 않습니다. 비 대화식 로그인 셸을 얻는 또 다른 방법은 터미널이 아닌 표준 입력을 통해 전달 된 명령 ssh example.com <my-script-which-is-stored-locally( 예 : ssh example.com my-script-which-is-on-the-remote-machine비 대화식, 비 로그인 셸을 실행하는 것과 달리)을 통해 원격으로 로그인하는 것입니다.

기존 세션의 터미널에서 쉘 (화면, X 터미널, Emacs 터미널 버퍼, 다른 쉘 내의 쉘 등)을 시작하면 대화식의 비 로그인 쉘이 나타납니다. 즉, 쉘 (쉘 설정 파일을 읽을 수 ~/.bashrc떠들썩한 파티로 호출을 위해 bash, /etc/zshrc그리고 ~/.zshrczsh을 위해, /etc/csh.cshrc그리고 ~/.cshrcCSH를 들어, 파일에 의해 표시 ENV로 호출 할 때와 같은 대시, KSH, 그리고 bash는 등의 POSIX / XSI 호환 쉘에 대한 변수 sh, $ENV설정 한 경우 ~/.mkshrcmksh 등의 경우).

쉘이 스크립트를 실행하거나 명령 행에 전달 된 명령은 비 대화식, 비 로그인 쉘입니다. 이러한 셸은 항상 실행됩니다. 프로그램이 다른 프로그램을 호출 할 때 실제로 다른 프로그램을 호출하기 위해 셸에서 작은 스크립트를 실행하는 것이 매우 일반적입니다. 이 경우 일부 셸은 시작 파일을 읽습니다 (bash는 BASH_ENV변수로 표시된 파일 , zsh runs /etc/zshenv~/.zshenv). 그러나 위험합니다. 셸은 모든 종류의 컨텍스트에서 호출 될 수 있으며 수행 할 수있는 작업이 거의 없습니다. 무언가를 끊으십시오.

조금 단순화하고 있습니다. 자세한 내용은 설명서를 참조하십시오.


2
bash비 대화식 로그인 셸로 실행하는 방법을 예를 들어 주 시겠습니까?
Piotr Dobrogost

13
@PiotrDobrogostecho $- | bash -lx
Gilles

1
이것이 일반적인 것인지는 모르겠지만 기본 설정을 사용하여 osx에서 새 터미널을 열면 사용자 이름이나 암호를 입력하지 않아도 로그인 쉘이 나타납니다.
Kevin Wheeler

4
@KevinWheeler OSX에서 기본적으로 터미널 응용 프로그램은 로그인 셸을 실행합니다. (설명 할 때, 셸을 시작하는 프로그램은 셸이 로그인 쉘 역할을하는지 여부를 결정합니다.) 일반적인 방법은 아닙니다.
Gilles

2
@IAmJulianAcosta FOO환경 변수 인 경우 (예 :)를 .profile포함 export FOO=something하여 모든 하위 프로세스에서 사용할 수 있습니다 foo.sh. 로 변경 .profile하면 export FOO=something_else다음에 로그인 할 때까지 ./foo.sh계속 인쇄 something됩니다.
Gilles

48

로그인 쉘에 있는지 확인하려면 다음을 수행하십시오.

prompt> echo $0
-bash # "-" is the first character. Therefore, this is a login shell.

prompt> echo $0
bash # "-" is NOT the first character. This is NOT a login shell.

Bash에서는 다음을 사용할 수도 있습니다 shopt login_shell.

prompt> shopt login_shell
login_shell     off

(또는 on로그인 쉘에서).

정보는 man bash(호출 검색) 에서 찾을 수 있습니다 . 발췌문은 다음과 같습니다.

로그인 쉘은 인수 0의 첫 문자가-이거나 --login 옵션으로 시작된 문자입니다.

이것을 직접 테스트 할 수 있습니다. SSH를 할 때마다 로그인 쉘을 사용하고 있습니다. 예를 들어 :

prompt> ssh user@localhost
user@localhost's password:
prompt> echo $0
-bash

로그인 쉘 사용의 중요성은 모든 설정 /home/user/.bash_profile이 실행된다는 것입니다. 당신이 관심이 있다면 여기에 좀 더 정보 (출신 man bash)

"bash가 대화식 로그인 쉘 또는 --login 옵션을 사용하는 비 대화식 쉘로 호출 될 때 파일이 존재하는 경우 먼저 / etc / profile 파일에서 명령을 읽고 실행합니다. 해당 파일을 읽은 후에는 찾습니다 ~/.bash_profile, ~/.bash_login그리고 ~/.profile, 순서대로, 그리고 읽고 존재하고 읽을 수 있습니다. 쉘이 동작을 억제하기 위해 시작될 때 --noprofile 옵션을 사용할 수 있습니다 첫 번째에서 명령을 실행합니다. "


23

로그인 쉘에서 argv[0][0] == '-'. 이것이 로그인 쉘임을 아는 방법입니다.

그런 다음 "로그인 쉘"상태에 따라 다르게 작동합니다. 예를 들어, 로그인 쉘이 아닌 쉘은 "logout"명령을 실행하지 않습니다.


4
에 따르면 man bash, "로그인 쉘은 인수 0의 첫 문자가- 이거나 --login 옵션으로 시작한 문자입니다 . "
Wildcard

18

GUI의 새 터미널에서 시작된 쉘은 대화식 비 로그인 쉘입니다. 예를 들어 .bashrc는 소스로 만들지 만 .profile은 소스로 만들지 않습니다.


4

로그인 쉘 유형을 확인하는 Timothy의 방법과 결합 된 Gilles의 훌륭한 답변에 대해 자세히 설명하겠습니다.

직접보고 싶은 내용이 있으면 스 니펫과 시나리오를 시도해보십시오.

쉘이 (비) 대화식인지 확인

if tty -s; then echo 'This is interactive shell.'; else echo 'This is non-interactive shell.'; fi

쉘이 (비) 로그인 지 확인

출력이로 echo $0시작 하면 -로그인 셸 ( echo $0출력 예 :) -bash입니다. 그렇지 않으면 비 로그인 쉘입니다 ( echo $0출력 예 :) bash.

if echo $0 | grep -e ^\- 2>&1>/dev/null; then echo "This is login shell."; else echo "This is non-login shell."; fi;

위의 두 정보를 결합하여 두 정보를 한 번에 가져 오십시오.

THIS_SHELL_INTERACTIVE_TYPE='non-interactive'; 
THIS_SHELL_LOGIN_TYPE='non-login'; 
if tty -s; then THIS_SHELL_INTERACTIVE_TYPE='interactive'; fi; 
if echo $0 | grep -e ^\- 2>&1>/dev/null; then THIS_SHELL_LOGIN_TYPE='login'; fi;
echo "$THIS_SHELL_INTERACTIVE_TYPE/$THIS_SHELL_LOGIN_TYPE"

시나리오 :

특별한 옵션이없는 일반적인 SSH 세션

ssh ubuntu@34.247.105.87
Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.4.0-1083-aws x86_64)

ubuntu@ip-172-31-0-70:~$ THIS_SHELL_INTERACTIVE_TYPE='non-interactive';
ubuntu@ip-172-31-0-70:~$ THIS_SHELL_LOGIN_TYPE='non-login';
ubuntu@ip-172-31-0-70:~$ if tty -s; then THIS_SHELL_INTERACTIVE_TYPE='interactive'; fi;
ubuntu@ip-172-31-0-70:~$ if echo $0 | grep -e ^\- 2>&1>/dev/null; then THIS_SHELL_LOGIN_TYPE='login'; fi;
ubuntu@ip-172-31-0-70:~$ echo "$THIS_SHELL_INTERACTIVE_TYPE/$THIS_SHELL_LOGIN_TYPE"

interactive/login

스크립트를 실행하거나 새 셸을 통해 명시 적으로 실행

ubuntu@ip-172-31-0-70:~$  bash -c 'THIS_SHELL_INTERACTIVE_TYPE='non-interactive'; THIS_SHELL_LOGIN_TYPE='non-login'; if tty -s; then THIS_SHELL_INTERACTIVE_TYPE='interactive'; fi; if echo $0 | grep -e ^\- 2>&1>/dev/null; then THIS_SHELL_LOGIN_TYPE='login'; fi; 
echo "$THIS_SHELL_INTERACTIVE_TYPE/$THIS_SHELL_LOGIN_TYPE"'

interactive/non-login

로컬 스크립트를 원격으로 실행

ssh ubuntu@34.247.105.87 < checkmy.sh
Pseudo-terminal will not be allocated because stdin is not a terminal.
Welcome to Ubuntu 16.04.5 LTS (GNU/Linux 4.4.0-1083-aws x86_64)

non-interactive/login

ssh를 통해 원격으로 명령 실행

ssh ubuntu@34.247.105.87 'THIS_SHELL_INTERACTIVE_TYPE='non-interactive'; THIS_SHELL_LOGIN_TYPE='non-login'; if tty -s; then THIS_SHELL_INTERACTIVE_TYPE='interactive'; fi; if echo $0 | grep -e ^\- 2>&1>/dev/null; then THIS_SHELL_LOGIN_TYPE='login'; fi; echo "$THIS_SHELL_INTERACTIVE_TYPE/$THIS_SHELL_LOGIN_TYPE"'

non-interactive/non-login

-t스위치를 사용 하여 ssh를 통해 원격으로 명령 실행

-tswitch 를 사용하여 ssh를 통해 원격으로 명령을 실행하려는 경우 대화식 쉘을 명시 적으로 요청할 수 있습니다 .

ssh ubuntu@34.247.105.87 -t 'THIS_SHELL_INTERACTIVE_TYPE='non-interactive'; THIS_SHELL_LOGIN_TYPE='non-login'; if tty -s; then THIS_SHELL_INTERACTIVE_TYPE='interactive'; fi; if echo $0 | grep -e ^\- 2>&1>/dev/null; then THIS_SHELL_LOGIN_TYPE='login'; fi; echo "$THIS_SHELL_INTERACTIVE_TYPE/$THIS_SHELL_LOGIN_TYPE"'

interactive/non-login

참고 : 명령을 원격으로 실행하는 이유에 login shell대한 자세한 정보는 여기를 참조 하십시오 .

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