로그인 쉘은 어디에 정의되어 있습니까?


16

나는 sudo -i/-s 여기의 차이점을 읽고 있었습니다 . 명령 shopt을 사용한 후 all ( sudo su/sudo -i/sudo -s)은 $SHELL동일한 결과를 제공하지만 shopt명령 결과는 다릅니다.

그렇다면 로그인과 비 로그인 쉘은 어떻게 정의됩니까?

어디 shopt에서 결과를 얻습니까?

왜 관련이 $SHELL없습니까?

수도

givinv@87-109:~$ sudo su
root@87-109:/home/givinv# 
root@87-109:/home/givinv# 
root@87-109:/home/givinv# shopt -q login_shell && echo 'Login shell' || echo 'No login shell'
No login shell
root@87-109:/home/givinv# echo $SHELL
/bin/bash
root@87-109:/home/givinv# 
root@87-109:/home/givinv# exit
givinv@87-109:~$ 

sudo -i

givinv@87-109:~$ sudo -i
root@87-109:~# 
root@87-109:~# shopt -q login_shell && echo 'Login shell' || echo 'No login shell'
Login shell
root@87-109:~# echo $SHELL
/bin/bash
root@87-109:~# 

sudo -s

root@87-109:~# sudo -s
root@87-109:~# shopt -q login_shell && echo 'Login shell' || echo 'No login shell'
No login shell
root@87-109:~# echo $SHELL
/bin/bash
root@87-109:~# 

7
하나의 문제는 "로그인 쉘"은 두 가지 의미를 갖는다는 것입니다. 1. 특정 방식으로 시작된 쉘의 인스턴스입니다 (읽기 .profile또는 동등한 것 등). 2. 로그인시 시작되는 쉘 정의 된 /etc/passwd또는 이와 동등한 사용자 . $SHELL후자를 포함하고, shopt출력은 전자를 처리합니다. 일반적으로 (2)의 셸이 로그인시 시작되면 (1)에 필요한 특정 방식으로 시작되므로 의미의 혼동이 발생합니다.
muru

1
@muru의 설명은 좋은 것입니다. 예를 들어 원격 시스템에서 컴퓨터로 SSH 연결하는 경우. 시스템의 / usr / sbin / sshd $SHELL는 / etc / passwd 항목에 정의 된 쉘을 포크 (의사 터미널에 연결)로 포크합니다 . 이 쉘은 로그인 쉘이며로 테스트 할 수 있습니다 if [[ -o login ]]; then echo "I am a login shell"; fi. 로그인 쉘이기 때문에 새로운 세션에 적합한 작업을 수행합니다. 예를 들어 ~/.zprofile환경 변수와 현재 실행하고 싶은 커스텀 쉘 코드를 설정하는 소스 또는 유사
the_velour_fog

답변:


17

TL; DR :

  • 로그인 쉘은 어디에 정의되어 있습니까? 에서 /etc/passwd.
  • 인가 sudo su/ sudo su -/ sudo -i/ sudo -s같은? 아니, 그들은 모두 껍질을 뿌렸지만 다르게, 상황에 따라 다릅니다.
  • 무엇을 $SHELL합니까? 에서와 같이 기본 쉘에 알려주십시오 /etc/passwd.

실제 답변 :

우선, shoptbash 고유의 것을 언급하는 것이 중요합니다 . 예를 들어, 나는 mksh쉘 사용자이며 그렇지 않은 shopt것처럼을 가지고 ksh있지 않습니다.

다음으로 정확히 무엇 login_shell을 나타내야합니까? 보낸 사람 man bash:

login_shell

로그인 쉘로 시작된 경우 쉘은이 옵션을 설정합니다.

이것이 핵심입니다. sudo -i이전 답변에서 이미 알고 있듯이 초기 로그인을 시뮬레이션해야합니다. 이것이이 옵션에 대한 shopt보고서 login_shell on입니다. sudo -i로그인 프로세스 중에 만 표시되는 파일 (대화식 쉘에서 제공하지 않음)을 쉘 이 강제로 통과하는 것처럼 생각하십시오.

다른 경우에는 이미 쉘 인스턴스를 실행 중이므로 처음에는 로그인 쉘이 될 수 없으며 옵션의 목적이 다릅니다. 변수를 sudo -s읽고 $SHELL(기본 쉘을 설정하기 위해 /etc/passwd) 변수를 루트 권한으로 실행합니다. 이것은 sudo $SHELL또는 sudo mksh또는 sudo bash( 또는 사용 중) 수행하는 것과 같습니다 .

내가 mksh사용자 라고 언급 한 것을 기억 하십니까? 이것 좀 봐 :

$ bash --posix
bash-4.3$ sudo -s
[sudo] password for xieerqi: 

DIR:/xieerqi|01:53|skolodya@ubuntu:
$ id 
uid=0(root) gid=0(root) groups=0(root)

DIR:/xieerqi|01:53|skolodya@ubuntu:
$ echo $-
imsU

당신이 보는 것은 내가 설정 한 특성 프롬프트와 함께 내 껍질로 sudo -s뛰어 들었다는 것입니다. 물론 로그인 작업이 아니기 때문에 셸이 비 로그인 셸 인스턴스로 생성되었다고보고 하기 때문입니다. 그러나 필자의 경우 로그인 셸 인스턴스 인 경우 거기 에 문자가없는 것을 알 수 있습니다.bashmkshbash$-l

마지막으로 동일한 아이디어가 sudo su및에 적용됩니다 sudo su -. 나중에 하나는 로그인 셸 인스턴스를 생성하고 (즉, 로그인에 필요한 특정 파일이 실행 됨) 이전 하나는 대화식 셸만 생성합니다 (즉, 로그인 파일이 실행되지 않음).

bash-4.3$ sudo su
[sudo] password for xieerqi: 
root@eagle:/home/xieerqi# shopt login_shell
login_shell     off
root@eagle:/home/xieerqi# exit
bash-4.3$ sudo su -
[sudo] password for xieerqi: 
$ shopt login_shell
login_shell     on

따라서 기술적으로 shopt login_shell는 아무 관련이 $SHELL없습니다. 이런 식으로 생각하십시오 : 그것의 목적은 bash가 어떻게 실행 되는지 를 보여주는 것입니다 . $SHELL에 할당 한 내용 만 반영해야합니다 /etc/passwd.

로그인 쉘과 비 로그인 쉘의 차이점에 대해서는 이 답변 에서 unix.stackexchange.com의 존경받는 Gilles가 설명했습니다 .


추가 재미

시도해 볼 수있는 재미가 있습니다. 아시다시피 로그인 쉘은 실행 되지만 .profile( .bashrc우분투 .profile 는 그렇게 설정되어 있기 때문에 ) 로그인하지 않은 지옥은 .bashrc파일 만 실행 합니다. 따라서 우리는 echo이 명령 들 중 어느 것이 로그인 쉘을 실행하고 그렇지 않은지를 테스트 할 수 있으며 , 로그인 쉘에는 두 줄, echo비 로그인에는 한 줄만 예상 됩니다.

$ echo "echo 'hi,i am .profile'"  >> .profile
$ echo "echo 'hi, i am .bashrc'" >> .bashrc
$ sudo -i
hi, i am .bashrc
hi,i am .profile
$ sudo su
hi, i am .bashrc
root@eagle:~# sudo su -
hi, i am .bashrc
hi,i am .profile
$ sudo -s
hi, i am .bashrc
root@eagle:~# 

적절하게도, 두 줄의 출력을 가진 사람들은로 login_shell설정 될 것 입니다 on.


@Serg와 @Zanna에게 감사합니다. 이제 약 $SHELLlogin_shell/non-login_shell명확하게되었다. 그러나 어디에서 shopt자세한 정보를 얻을 수 있습니까? 에서 echo $0왔습니까?
prado

1
@prado 나는 yes라고 말할 것이다. 왜냐하면 첫 번째 문자 $0는 쉘이 로그인 쉘인지 아닌지를 지정하는데 사용되기 때문에 shopt변수를 확인 한다면 완벽하게 수용 가능하다. 그러나 아마도 눈을 맞추는 것 이상이있을 것입니다. shopt아마이 질문에 대해서는 bash의 소스 코드에 익숙하지 않기 때문에 어려운 대답이 없습니다.
Sergiy Kolodyazhnyy

@prado Bash는 $ 0의 첫 문자를 -갖거나 -l옵션 을 사용하여 로그인 쉘로 시작할 수 있습니다 .
muru

@prado 맨 페이지에서 bash의 호출 및 옵션에 대해 읽을 수 있습니다. 예를 들어 SHELL BUILTIN COMMAND의 섹션은 bash가 시작하는 방법을 프로그래밍 방식으로 알 수있는 한 가지 방법으로 bash를 찾을 수 login_shell The shell sets this option if it is started as a login shell (see INVOCATION above). The value may not be changed.있는 shopt login_shell것처럼 보입니다. 다른 방법은 다음과 같습니다[[ -o login ]]
the_velour_fog

11

@Serg의 설명에 실행중인 쉘 무엇을 이야기하는 방법에 대한이 답변에서SHELL변수는 현재 사용자의입니다 기본 에서 읽을 쉘 /etc/passwd:

$ grep zanna /etc/passwd
zanna:x:1000:1000:Zanna,,,:/home/zanna:/bin/bash

그래서 내가 echo $SHELL항상 반환합니다 /bin/bash:

$ zsh
% echo $SHELL
/bin/bash

여부 쉘, 로그인 쉘이다 인 옵트 이온 쉘이 시작되는 시점에 결정했다. 쉘 프로그램은이 정보를 다른 모든 설정 및 변수와 함께 저장합니다. 이 shopt명령은이 정보를보고 가능한 경우 해당 옵션을 설정하거나 설정 해제 할 수있는 방법을 제공합니다 ( login_shell물론 쉘을 시작하는 데 사용 된 프로세스에 따라 다릅니다)

sudo프로그램의 옵션은 루트 쉘의 서로 다른 유형의 시작 방법을 결정 :

여기에 이미지 설명을 입력하십시오


1
좋은 설명입니다. 나는 당신이 무엇을 설명했다고 생각 shopt하고 login_shell내 대답에 훨씬 더 그 대표로되어있다.
Sergiy Kolodyazhnyy

@ Serg thanks :) 당신의 설명이 더 철저하다고 생각합니다 :)
Zanna

3

man bash:

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

man login:

$HOME, $SHELL[...] 의 값 은 비밀번호 입력의 해당 필드에 따라 설정됩니다.

한마디로 :

  • 쉘은 로그인 쉘로 호출 된 경우 로그인 쉘입니다.
  • 환경 변수 $SHELLlogin예를 들어 호출 프로그램에 의해 또는 호출 프로그램에 의해 설정됩니다 su. 쉘 자체는 그것을 설정하지 않습니다.
  • shopt 현재 유효한 쉘 옵션을 보여줍니다.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.