นี่คือสิ่งที่เกิดขึ้นเมื่อฉันดำเนินการsudo su
ตามด้วยexit
$ sudo su
# exit
exit
$
คำสั่ง exit ไม่ปิดโปรแกรมจำลองเทอร์มินัลของฉัน
มันเป็นสถานีเด็กหรือไม่?
นี่คือสิ่งที่เกิดขึ้นเมื่อฉันดำเนินการsudo su
ตามด้วยexit
$ sudo su
# exit
exit
$
คำสั่ง exit ไม่ปิดโปรแกรมจำลองเทอร์มินัลของฉัน
มันเป็นสถานีเด็กหรือไม่?
คำตอบ:
เมื่อคุณเรียกใช้งานsudo su
หรือมีการสร้างเชลล์ใหม่su user
การดำเนินการexit
(หรือCtrl+ D) จะออกจากเชลล์สร้างใหม่และจะนำคุณกลับสู่เชลล์ก่อนหน้า
จุดเริ่มต้น - bash shell ทำงานบน PID 25050:
$ ps
PID TTY TIME CMD
25050 pts/17 00:00:00 bash
25200 pts/17 00:00:00 ps
การรันsudo su
สร้างกระบวนการทุบตีใหม่ซึ่งทำงานบน PID 25203:
$ sudo su
# ps
PID TTY TIME CMD
25201 pts/17 00:00:00 sudo
25202 pts/17 00:00:00 su
25203 pts/17 00:00:00 bash
25213 pts/17 00:00:00 ps
# exit
การออกsudo su
และกลับสู่จุดเริ่มต้น - เชลล์ bash ทำงานบน PID 25050:
$ ps
PID TTY TIME CMD
25050 pts/17 00:00:00 bash
25214 pts/17 00:00:00 ps
$
กระบวนการลูกที่คุณเรียกใช้จากเชลล์รวมถึงเปลือกลูกใช้เทอร์มินัลเดียวกันโดยอัตโนมัติ นี่ไม่ได้เฉพาะเจาะจง แต่อย่างsudo
ใด - โดยทั่วไปแล้วมันทำงานอย่างไรเมื่อคุณรันโปรแกรมจากเชลล์
เชลล์และเทอร์มินัลเป็นสิ่งที่แตกต่างกัน เปลือกคือสิ่งที่คุณใช้ในการคำสั่งการทำงานในสถานี เชลล์สามารถทำงานได้แบบโต้ตอบ - ให้คุณพร้อมรับคำสั่งรันคำสั่งหรือแสดงข้อผิดพลาดเกี่ยวกับสาเหตุที่มันไม่สามารถทำได้และกระบวนการทำซ้ำจนกว่าคุณจะออกจากเชลล์ หรือมันสามารถทำงาน noninteractively วิ่งสคริปต์
แม้ว่าขั้วของคุณ (อาจ) เทิดทูนไม่ทางกายภาพกระนั้นUnix เหมือนระบบเช่น Ubuntu กำหนดปฏิบัติการโหนดอุปกรณ์แต่ละขั้วของคุณและคุณสามารถตรวจสอบสิ่งที่ขั้วคุณกำลังใช้กับtty
คำสั่ง มันมักจะเป็น/dev/pts/0
, /dev/pts/1
, /dev/pts/2
, ฯลฯสำหรับหน้าต่าง terminalหรือการเชื่อมต่อ SSHหรือ/dev/tty1
, /dev/tty2
, ฯลฯสำหรับคอนโซลเสมือน จริงๆแล้วอะไรtty
คือการบอกคุณว่าเทอร์มินัลใดถ้ามีจะถูกนำมาจากอินพุต ; ดูรายละเอียดด้านล่าง
ek@Io:~$ tty
/dev/pts/1
ek@Io:~$ bash
ek@Io:~$ tty
/dev/pts/1
ek@Io:~$ exit
exit
ek@Io:~$ sudo su
[sudo] password for ek:
root@Io:/home/ek# tty
/dev/pts/1
root@Io:/home/ek# exit
exit
ek@Io:~$
คุณสามารถเห็นได้ว่าแม้ว่าsudo su
จะสร้างเชลล์ใหม่ตามที่ Yaron อธิบายไว้อย่างดีแต่เทอร์มินัลที่คุณใช้ไม่ได้เปลี่ยนแปลง
แน่นอนว่ายังมีวิธีอื่นที่จะสังเกตว่าเครื่องเทอร์มินัลเหมือนกัน: คุณยังคงเขียนอินพุตในแบบเดียวกันและในที่เดียวกันและอ่านเอาต์พุตในแบบเดียวกันและในที่เดียวกัน
ส่วนใหญ่คำสั่งคุณทำงานในเปลือก - เช่นls
, cp
, mv
, rm
, touch
, wc
, du
, df
, ssh
, su
, sudo
, sh
, bash
และหลายมากขึ้น - ทำให้เกิดกระบวนการเด็กที่จะสร้าง กระบวนการย่อยนี้มีเชลล์ของคุณเป็นพาเรนต์ แต่เป็นโปรแกรมแยกต่างหาก โดยค่าเริ่มต้นมันจะเชื่อมต่อกับเดียวกันมินัลเป็นเปลือกของคุณ
เชลล์ของคุณยังคงทำงานอยู่ แต่จะรอในพื้นหลังเพื่อให้โปรแกรมยุติการทำงาน (หรือให้คุณหยุดการทำงานชั่วคราว ) เมื่อโปรแกรมสิ้นสุดลงเชลล์จะยังคงทำงานอยู่และจะทำงานต่อเพื่อให้คุณพร้อมรับคำสั่งครั้งต่อไป
นี่คือข้อยกเว้นที่สำคัญ:
cd
ไม่ได้สร้างกระบวนการใหม่ที่ทุกคนจนกว่าพวกเขาจะใช้ในการสร้างที่มีพนักงานที่subshell ( อธิบายที่นี่ ) เช่น(
)
การจัดกลุ่มและท่อ&
คุณทำได้โดยการสิ้นสุดคำสั่งด้วย ( your-command arguments... &
)disown
แม้ว่าฉันจะไม่คิดว่านี่เป็นข้อยกเว้นสำหรับกระบวนการลูกที่กำลังเชื่อมต่อกับเทอร์มินัลเดียวกันกับพาเรนต์โปรดทราบว่ากระบวนการที่คุณเรียกใช้จากเชลล์ในเทอร์มินัลจะไม่รับอินพุตจากเทอร์มินัลนั้นเสมอ :
<
, >
และ>>
ผู้ประกอบการ|
ด้วยเนื่องจากtty
คำสั่งตรวจสอบเพียงเทอร์มินัลอินพุตมาตรฐานของมันคืออะไรคุณจึงสามารถ "หลอก" ได้:
ek@Io:~$ tty
/dev/pts/1
ek@Io:~$ tty </dev/pts/0
/dev/pts/0
หรือน้อยกว่าคดเคี้ยว:
ek@Io:~$ tty </dev/null # not a terminal
not a tty
ek@Io:~$ tty <&- # closes the input stream
not a tty