shell에서 interactive, non-interactive, login, non-login 차이는?

3 minute read

시작하며

BashZshstartup 파일을 로드하는 방법에 대한 글을 읽었다. 표로 깔끔하게 startup 파일을 읽는 방법을 설명한다. 명쾌하고 좋은 글이었다. interactive login, interactive non-login, script 로 비교해서 startup 파일을 읽는 걸 설명한다. 궁금하다. 여기서 scriptnon-interactive login/non-login 을 설명하는 걸까? non-interactive 도 있을텐데 이건 어떤 상황에서 실행되는 shell일까?

interactive shell vs non-interactive shell

interactive shell 은 프롬프트가 나오는 셸이다. 명령을 입력하고 응답을 보고 다시 입력하고. macOS에서 터미널을 실행하면 입력할 수 있는 프롬프트가 나오는데, interactive shell 을 실행한 거다.

$ [[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'
Interactive

interactive shell 에서 실행하면 기대한대로 Interactive가 출력된다.

$ cat is_interactive
#!/bin/bash

[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'

이런 스크립트 파일을 만들었다. 실행하면 어떤 결과가 나올까?

$ ./is_interactive
Not interactive

Non interactive가 나온다. interactive shell에서 실행한 게 아니라 #!/bin/bash shebang interpreter 프로그램 지시자가 가리키는 Bash 프로그램으로 스크립트 파일을 실행하기 때문이다. 새로 Bash 프로그램을 실행해서 스크립트를 다 실행하면 종료한다. 거기에 프롬프트가 뜨고 사용자 입력을 받을까? 안 받는다. 실행을 다 하면 바로 종료한다. 즉, Non interactive shell 이다.

[[ $- == *i* ]] && echo 'Interactive' || echo 'Not interactive'

이런 스크립트로 구별할 수 있다.

login shell vs non-login shell

보통 shell을 시작할 때는 login shell 로 시작한다. macOS에서 터미널 앱을 실행해서 shell을 띄우던지 할 때 말이다.

Typically, most users will encounter a login shell only if either:

  • they logged in from a tty, not through a GUI
  • they logged in remotely, such as through ssh.

zprofile bash_profile zshrc bashrc bash_aliases - macOS - SS64.com - ss64.com

macOS에서 터미널 앱을 실행해서 login shell 인지를 확인해본다.

$ shopt -q login_shell && echo 'Login shell' || echo 'Non-login shell'
Login shell

Login shell이 출력된다. 그럼 non-login shell 은 어떨 때, 사용될까?

$ cat is_login
#!/bin/bash

shopt -q login_shell && echo 'Login shell' || echo 'Non-login shell'

Bash script 파일을 만들어서 실행하면 어떻게 될까?

$ ./is_login
Non-login shell

non-login shell 이다. 위에서 본 non-interactive shell 과 이유는 비슷하다. shebang으로 !/bin/bash 프로그램으로 실행했기 때문이다. 아무 인자도 없이 Bash 프로그램을 실행해서 non-login shell 이 된다.

interactive shell 로 테스트를 해보자.

$ shopt -q login_shell && echo 'Login shell' || echo 'Non-login shell'
Login shell

macOS의 터미널 같은 앱을 실행해서 shell을 시작해서 입력하면 login shell 이다. Bash 프로그램을 실행해서 입력한다면?

$ shopt -q login_shell && echo 'Login shell' || echo 'Non-login shell'
Login shell
$ bash

The default interactive shell is now zsh.
To update your account to use zsh, please run `chsh -s /bin/zsh`.
For more details, please visit https://support.apple.com/kb/HT208050.

$ shopt -q login_shell && echo 'Login shell' || echo 'Non-login shell'
Non-login shell

non-login shell 이 된다. 어떻게 하면 bash login shell 을 실행할 수 있을까?

$ shopt -q login_shell && echo 'Login shell' || echo 'Non-login shell'
Login shell
$ bash --login

The default interactive shell is now zsh.
To update your account to use zsh, please run `chsh -s /bin/zsh`.
For more details, please visit https://support.apple.com/kb/HT208050.

$ shopt -q login_shell && echo 'Login shell' || echo 'Non-login shell'
Login shell

Bash 프로그램을 실행할 때, --login 옵션을 추가하면 login shell 로 실행할 수 있다.

물론 #!/bin/bash --login 과 같이 shebang에도 --login 옵션을 추가하면 login shell 로 실행할 수 있다. 물론 이게 필요한 경우는 한 번도 없었다. shebang을 이렇게 쓴 스크립트도 보지 못했다.

정리

입력할 수 있는 프롬프트가 있으면 interactive shell 이고 스크립트 파일을 실행한다던지 해서 프롬프트가 없다면 non-interactive shell 이다.

macOS의 터미널처럼 프로그램을 실행해서 shell에 들어가면 login shell 이다. Bash로 예를 든다면 --login 같은 옵션을 붙어서 shell을 실행한다. --login 옵션 없이 실행하면 non-login shell 이다.

예를 들어 shebang이 #!/bin/bash 로 되어 있는 스크립트를 실행한다면 Bash 프로그램 실행해서 스크립트를 실행하므로 non-interactive shell 이다. --login 옵션이 없으므로 non-login shell 이다.

링크