เชลล์ล็อกอินถูกกำหนดไว้ที่ไหน?


16

ผมอ่านความแตกต่างระหว่างที่นี่sudo -i/-s หลังจากใช้คำสั่งshoptจะมีการบันทึกไว้ว่า all ( sudo su/sudo -i/sudo -s) $SHELLจะให้ผลลัพธ์เดียวกัน แต่shoptผลลัพธ์ของคำสั่งจะแตกต่างกัน

ดังนั้นเข้าสู่ระบบและเปลือกเข้าสู่ระบบที่ไม่ได้กำหนดไว้อย่างไร

จากการที่shoptได้รับผลหรือไม่

ทำไมมันไม่เกี่ยวข้องกับ$SHELL?

sudo su

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เพียงแค่บอกเปลือกเริ่มต้นของคุณเช่นเดียวกับใน

คำตอบจริง :

ก่อนอื่นสิ่งสำคัญคือต้องระบุว่าshoptเป็นการเฉพาะสำหรับทุบตี ตัวอย่างเช่นฉันเป็น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กระโดดลงมาจากเปลือกbashของฉันmkshพร้อมกับคุณสมบัติที่ฉันตั้งไว้ และแน่นอนเพราะมันไม่ใช่การกระทำการเข้าสู่ระบบเพราะbashมันจะรายงานว่าเชลล์นั้นกลับกลายเป็นอินสแตนซ์ของเชลล์ที่ไม่ใช่การเข้าสู่ระบบ อย่างไรก็ตามในกรณีของฉันคุณจะเห็นว่า$-ไม่มีตัวอักษร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ใด ๆ ทั้งสิ้น คิดแบบนี้: จุดประสงค์คือเพื่อแสดงให้เห็นว่าการทุบตีทำงานอย่างไร $SHELLควรสะท้อนให้เห็นถึงสิ่งที่คุณได้รับมอบหมาย/etc/passwdเท่านั้น

สำหรับความแตกต่างระหว่างล็อกอินเชลล์และเชลล์ที่ไม่ใช่ล็อกอินเชลล์นั้นถูกอธิบายโดย Gilles ที่ได้รับการยอมรับอย่างสูงบน unix.stackexchange.com ในคำตอบนี้


ความสนุกเพิ่มเติม

นี่คือสิ่งที่คุณสามารถลองได้ ดังที่คุณอาจทราบแล้วว่าเชลล์การเข้าสู่ระบบจะทำงาน.profile(และ.bashrcเนื่องจาก Ubuntu ได้.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_shellon


ขอบคุณ @Serg และ @Zanna ตอนนี้เกี่ยวกับ$SHELLและlogin_shell/non-login_shellได้ชี้แจง แต่จากที่shoptรับรายละเอียด? มันมาจากecho $0ไหน
Prado

1
@prado ฉันจะบอกว่าใช่เนื่องจากตัวอักษรตัวแรกของที่$0ใช้ในการกำหนดว่าเปลือกเป็นเปลือกเข้าสู่ระบบดังนั้นถ้าshoptจะตรวจสอบตัวแปรที่ - แน่ใจว่ามันเป็นที่ยอมรับอย่างสมบูรณ์ อย่างไรก็ตามอาจมีมากกว่าตา shoptอาจสำหรับคำถามนี้ฉันไม่มีคำตอบที่ยากเนื่องจากฉันไม่คุ้นเคยกับซอร์สโค้ดของ bash ที่ดี
Sergiy Kolodyazhnyy

@prado Bash สามารถเริ่มต้นเป็นเชลล์การเข้าสู่ระบบโดยให้อักขระตัวแรกเป็น $ 0 -หรือโดยใช้-lตัวเลือก
muru

@prado คุณสามารถอ่านเกี่ยวกับการร้องขอของ bash และตัวเลือกใน man page ตัวอย่างเช่นส่วนของคำสั่ง SHELL BUILTIN บัญชากล่าว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

ไม่ว่าเชลล์จะเป็นล็อกอินเชลล์หรือไม่จะเป็นsh ell opt ion ที่กำหนดในเวลาที่เชลล์เริ่มทำงาน โปรแกรมเชลล์เก็บข้อมูลนี้พร้อมกับการตั้งค่าและตัวแปรอื่น ๆ ทั้งหมด shoptคำสั่งมีวิธีการดูข้อมูลนี้และถ้าเป็นไปได้สำหรับตัวเลือกในคำถามการตั้งค่าหรือล้างมัน (กรณีนี้ไม่ได้สำหรับlogin_shellที่แน่นอนขึ้นอยู่กับกระบวนการที่ใช้ในการเริ่มต้นเปลือก)

sudoตัวเลือกของโปรแกรมกำหนดวิธีการที่แตกต่างกันเหล่านี้ของเปลือกรากจะเริ่มต้น:

ป้อนคำอธิบายรูปภาพที่นี่


1
คำอธิบายที่ดี ฉันคิดว่าคุณอธิบายshoptแล้วและlogin_shellควรจะเป็นตัวแทนที่ดีกว่านั้นในคำตอบของฉัน
Sergiy Kolodyazhnyy

@Serg ขอบคุณ :) ผมคิดว่าคำอธิบายของคุณอย่างละเอียดมากขึ้น :)
Zanna

3

man bash:

เปลือกเข้าสู่ระบบเป็นหนึ่งที่มีอักขระตัวแรกของศูนย์อาร์กิวเมนต์เป็น-หรือหนึ่งเริ่มต้นด้วย--loginตัวเลือก

man login:

ค่าสำหรับ$HOME, $SHELL[ ... ] มีการตั้งค่าตามช่องที่เหมาะสมในการป้อนรหัสผ่าน

ในระยะสั้น:

  • เชลล์คือเชลล์ล็อกอินหากถูกเรียกใช้เป็นเชลล์ล็อกอิน
  • ตัวแปรสภาพแวดล้อม$SHELLถูกกำหนดโดยหรือโดยโปรแกรมกล่าวอ้างเช่นlogin suเชลล์ไม่ได้ตั้งค่าเอง
  • shopt แสดงให้เห็นถึงตัวเลือกเชลล์ที่มีผลบังคับใช้ในปัจจุบัน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.