ฉันเข้าใจถึงความแตกต่างพื้นฐานระหว่างเชลล์แบบโต้ตอบและเชลล์แบบไม่โต้ตอบ แต่สิ่งที่แตกต่างกันอย่างแท้จริงของเปลือกเข้าสู่ระบบจากเปลือกไม่ใช่ - เข้าสู่ระบบ?
คุณสามารถให้ตัวอย่างสำหรับการใช้งานของเปลือกโต้ตอบที่ไม่ได้เข้าสู่ระบบได้หรือไม่?
ฉันเข้าใจถึงความแตกต่างพื้นฐานระหว่างเชลล์แบบโต้ตอบและเชลล์แบบไม่โต้ตอบ แต่สิ่งที่แตกต่างกันอย่างแท้จริงของเปลือกเข้าสู่ระบบจากเปลือกไม่ใช่ - เข้าสู่ระบบ?
คุณสามารถให้ตัวอย่างสำหรับการใช้งานของเปลือกโต้ตอบที่ไม่ได้เข้าสู่ระบบได้หรือไม่?
คำตอบ:
ล็อกอินเชลล์เป็นกระบวนการแรกที่ดำเนินการภายใต้ ID ผู้ใช้ของคุณเมื่อคุณเข้าสู่ระบบสำหรับเซสชันแบบโต้ตอบ กระบวนการเข้าสู่ระบบบอกให้เปลือกทำงานเป็นเปลือกเข้าสู่ระบบด้วยการประชุม: ผ่านการโต้แย้ง 0 ซึ่งโดยปกติจะเป็นชื่อของเปลือกที่ปฏิบัติการได้ด้วย-
ตัวอักษรที่เตรียมไว้ (เช่น-bash
ในขณะที่มันจะเป็นปกติbash
เปลือกหอยเข้าสู่ระบบโดยทั่วไปอ่านไฟล์ที่ สิ่งเช่นการตั้งค่าตัวแปรสภาพแวดล้อม: /etc/profile
และ~/.profile
สำหรับแบบดั้งเดิมบอร์นเปลือก~/.bash_profile
นอกจากนี้สำหรับทุบตี† , /etc/zprofile
และ~/.zprofile
สำหรับ zsh † , /etc/csh.login
และ~/.login
สำหรับ csh ฯลฯ
เมื่อคุณเข้าสู่ระบบในคอนโซลข้อความหรือผ่าน 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
และ~/.zshrc
สำหรับ zsh, /etc/csh.cshrc
และ~/.cshrc
สำหรับ csh แฟ้มที่ระบุโดยENV
ตัวแปรสำหรับเปลือกหอย POSIX / XSI สอดคล้องเช่นประ ksh และทุบตีเมื่อเรียกเป็นsh
, $ENV
ถ้าตั้งค่าและ~/.mkshrc
สำหรับ mksh ฯลฯ )
เมื่อเปลือกรันสคริปต์หรือคำสั่งผ่านในบรรทัดคำสั่งของมันก็เป็นไม่โต้ตอบไม่เข้าสู่ระบบเปลือก เชลล์ดังกล่าวทำงานตลอดเวลา: เป็นเรื่องธรรมดามากที่เมื่อโปรแกรมเรียกโปรแกรมอื่นมันรันสคริปต์เล็ก ๆ ในเชลล์เพื่อเรียกใช้โปรแกรมอื่น เชลล์บางตัวอ่านไฟล์เริ่มต้นในกรณีนี้ (ทุบตีรันไฟล์ที่ระบุโดยBASH_ENV
ตัวแปร, zsh รัน/etc/zshenv
และ~/.zshenv
), แต่สิ่งนี้มีความเสี่ยง: เชลล์สามารถถูกเรียกใช้ในทุกประเภทของบริบทและแทบจะไม่สามารถทำอะไรได้เลย ทำลายบางสิ่งบางอย่าง
†ฉันลดความซับซ้อนลงเล็กน้อยดูคู่มือสำหรับรายละเอียดเต็มไปด้วยเลือด
bash
เป็นเชลล์ล็อกอินแบบไม่โต้ตอบได้หรือไม่?
echo $- | bash -lx
FOO
เป็นตัวแปรสภาพแวดล้อม (เช่น.profile
มีexport FOO=something
) foo.sh
แล้วก็สามารถใช้ได้กับกระบวนการย่อยทั้งหมดรวมทั้ง ถ้าคุณเปลี่ยน.profile
ไปexport FOO=something_else
แล้ว./foo.sh
จะยังคงพิมพ์something
ครั้งต่อไปที่คุณเข้าสู่ระบบ.
หากต้องการทราบว่าคุณอยู่ในเชลล์ล็อกอินหรือไม่:
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
(ค้นหาคำขอร้อง) นี่คือข้อความที่ตัดตอนมา:
เปลือกเข้าสู่ระบบเป็นหนึ่งที่มีอักขระตัวแรกของศูนย์อาร์กิวเมนต์เป็น - หรือหนึ่งเริ่มต้นด้วยตัวเลือก --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 อาจจะใช้เมื่อเปลือกจะเริ่มต้นในการยับยั้งการทำงานนี้."
ในเปลือกเข้าสู่ระบบ, argv[0][0] == '-'
. นี่คือวิธีที่มันรู้ว่ามันเป็นเปลือกเข้าสู่ระบบ
และในบางสถานการณ์มันจะทำงานแตกต่างกันไปขึ้นอยู่กับสถานะ "ล็อกอินเชลล์" เช่นเชลล์ที่ไม่ใช่เชลล์ล็อกอินจะไม่เรียกใช้คำสั่ง "logout"
man bash
มีการเน้นเพิ่ม"เปลือกเข้าสู่ระบบเป็นหนึ่งที่มีอักขระตัวแรกของศูนย์อาร์กิวเมนต์เป็น - หรือหนึ่งเริ่มต้นด้วยตัวเลือก --login "
เชลล์เริ่มต้นในเทอร์มินัลใหม่ใน GUI จะเป็นเชลล์แบบไม่ล็อกอิน มันจะมา. bashrc ของคุณ แต่ไม่ใช่. profile ของคุณ
ฉันจะอธิบายอย่างละเอียดเกี่ยวกับคำตอบที่ยอดเยี่ยมของ Gilles รวมกับวิธีการของ Timothy สำหรับการตรวจสอบประเภทเชลล์ล็อกอิน
หากคุณต้องการที่จะเห็นสิ่งต่าง ๆ สำหรับตัวคุณเองลองเกร็ดเล็กเกร็ดน้อยและสถานการณ์สมมติ
ตรวจสอบว่าเชลล์เป็นแบบโต้ตอบ (ไม่ใช่ -) หรือไม่
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 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 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 โดยใช้-t
สวิตช์
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
ข้อมูลเพิ่มเติมที่นี่