นี่เป็นคำถามที่ฉันจะโพสต์ที่นี่ไม่กี่สัปดาห์ที่ผ่านมา เช่นเดียวกับterdonฉันเข้าใจว่า a .bashrc
นั้นมาจากเชลล์ Bash แบบโต้ตอบเท่านั้นดังนั้นจึงไม่จำเป็นต้อง.bashrc
ตรวจสอบว่ามันทำงานในเชลล์เชิงโต้ตอบหรือไม่ พลุกพล่านทั้งหมดกระจายที่ผมใช้ (อูบุนตู RHEL และ Cygwin) มีประเภทของการตรวจสอบ (การทดสอบบางส่วน$-
หรือ$PS1
) เพื่อให้แน่ใจเปลือกปัจจุบันมีการโต้ตอบ ฉันไม่ชอบการเขียนโปรแกรมสินค้าศาสนา.bashrc
ดังนั้นผมจึงตั้งค่าเกี่ยวกับการทำความเข้าใจวัตถุประสงค์ของรหัสนี้ในของฉัน
Bash มีเคสพิเศษสำหรับเชลล์ระยะไกล
หลังจากค้นคว้าปัญหาฉันพบว่าเปลือกระยะไกลได้รับการปฏิบัติแตกต่างกัน แม้ว่าโดยปกติแล้วเปลือก Bash แบบเชลล์จะไม่เรียกใช้~/.bashrc
คำสั่งเมื่อเริ่มต้น แต่จะมีกรณีพิเศษเกิดขึ้นเมื่อเชลล์ถูกเรียกใช้โดย remote shell daemon :
ทุบตีพยายามที่จะตรวจสอบเมื่อมันจะถูกเรียกใช้ด้วยการป้อนข้อมูลมาตรฐานการเชื่อมต่อกับเชื่อมต่อเครือข่ายเช่นเมื่อดำเนินการโดยภูตระยะไกลเปลือกมักหรือภูตเปลือกที่เชื่อถือได้rshd
sshd
หาก Bash ระบุว่ากำลังรันในโหมดนี้มันจะอ่านและดำเนินการคำสั่งจาก ~ / .bashrc หากไฟล์นั้นมีอยู่และอ่านได้ sh
มันจะไม่ทำเช่นนี้หากเรียกว่าเป็น --norc
ตัวเลือกที่อาจจะถูกใช้ในการยับยั้งการทำงานนี้และ--rcfile
ตัวเลือกที่อาจถูกใช้เพื่อบังคับให้ไฟล์อื่นจะอ่าน แต่ไม่rshd
ว่ามิได้sshd
ทั่วไปเรียกเปลือกที่มีตัวเลือกเหล่านั้นหรือช่วยให้พวกเขามีการระบุ
ตัวอย่าง
.bashrc
ใส่ต่อไปนี้ที่จุดเริ่มต้นของระยะไกลได้ (หาก.bashrc
มีที่มาจาก.profile
หรือ.bash_profile
ปิดใช้งานสิ่งนี้ชั่วคราวขณะทดสอบ):
echo bashrc
fun()
{
echo functions work
}
รันคำสั่งต่อไปนี้แบบโลคัล:
$ ssh remote_host 'echo $- $0'
bashrc
hBc bash
- ไม่มี
i
ใน$-
ระบุว่าเปลือกเป็นที่ไม่ใช่แบบโต้ตอบ
- ไม่มีชั้นนำ
-
ในการ$0
แสดงให้เห็นว่าเปลือกไม่ได้เป็นเปลือกเข้าสู่ระบบ
ฟังก์ชันเชลล์ที่กำหนดในรีโมต.bashrc
สามารถรันได้:
$ ssh remote_host fun
bashrc
functions work
ผมสังเกตเห็นว่า~/.bashrc
เป็นเพียงssh
มาเมื่อมีคำสั่งระบุเป็นอาร์กิวเมนต์สำหรับ สิ่งนี้สมเหตุสมผล: เมื่อssh
ใช้เพื่อเริ่มเชลล์การเข้าสู่ระบบปกติ.profile
หรือ.bash_profile
ถูกเรียกใช้ (และ.bashrc
จะจัดหาเฉพาะเมื่อทำโดยหนึ่งในไฟล์เหล่านี้อย่างชัดเจน)
ประโยชน์หลักที่ฉันเห็นว่ามี.bashrc
ที่มาเมื่อเรียกใช้คำสั่งระยะไกล (ไม่โต้ตอบ) คือสามารถใช้ฟังก์ชันเชลล์ได้ อย่างไรก็ตามคำสั่งส่วนใหญ่ในแบบทั่วไป.bashrc
นั้นจะเกี่ยวข้องเฉพาะในเชลล์แบบโต้ตอบเท่านั้นเช่นนามแฝงจะไม่ถูกขยายเว้นแต่ว่าเชลล์เป็นแบบโต้ตอบ
การถ่ายโอนไฟล์ระยะไกลอาจล้มเหลว
นี่ไม่ใช่ปัญหาเมื่อใช้rsh
หรือssh
เริ่มใช้เชลล์ล็อกอินแบบโต้ตอบหรือเมื่อใช้เชลล์เพื่อเรียกใช้คำสั่ง แต่ก็อาจจะมีปัญหาสำหรับโปรแกรมเช่นrcp
, scp
และsftp
ที่ใช้เปลือกหอยระยะไกลสำหรับการถ่ายโอนข้อมูล
ปรากฎว่าเชลล์เริ่มต้นของผู้ใช้ระยะไกล (เช่น Bash) เริ่มต้นโดยปริยายเมื่อใช้scp
คำสั่ง ไม่มีการพูดถึงเรื่องนี้ใน man page - มีเพียงการกล่าวถึงที่scp
ใช้ssh
สำหรับการถ่ายโอนข้อมูล นี้มีผลที่ตามมาว่าถ้า.bashrc
มีคำสั่งใด ๆ ที่พิมพ์ไปออกมาตรฐานการถ่ายโอนไฟล์จะล้มเหลวเช่น
SCP ล้มเหลวไม่มีข้อผิดพลาด
ดูเพิ่มเติมที่รายงานข้อผิดพลาด Red Hat ที่เกี่ยวข้องจาก 15 ปีที่ผ่านมาscp พักเมื่อมีคำสั่ง echo ใน / etc / bashrc (ซึ่งปิดในที่สุดWONTFIX
)
ทำไมscp
และsftp
ล้มเหลว
SCP (Secure copy)และSFTP (Secure File Transfer Protocol)มีโปรโตคอลของตัวเองสำหรับ Local และ Remote ที่สิ้นสุดเพื่อแลกเปลี่ยนข้อมูลเกี่ยวกับไฟล์ที่ถูกถ่ายโอน ข้อความที่ไม่คาดคิดใด ๆ จากปลายรีโมตนั้นตีความผิด ๆ ว่าเป็นส่วนหนึ่งของโปรโตคอลและการถ่ายโอนล้มเหลว ตามคำถามที่พบบ่อยจาก Snail Book
สิ่งที่มักจะเกิดขึ้น แต่เป็นว่ามีงบทั้งในระบบหรือแฟ้มเริ่มต้นเปลือกต่อผู้ใช้บนเซิร์ฟเวอร์ ( .bashrc
, .profile
,
/etc/csh.cshrc
, .login
ฯลฯ ) ซึ่งข้อความการส่งออกในการเข้าสู่ระบบตั้งใจจะอ่านได้โดยมนุษย์ (เช่นfortune
, echo "Hi there!"
, ฯลฯ )
รหัสดังกล่าวควรสร้างผลลัพธ์ในการเข้าสู่ระบบแบบโต้ตอบเท่านั้นเมื่อมีสิ่งที่
tty
แนบมากับอินพุตมาตรฐาน ถ้ามันไม่ได้ทำให้การทดสอบนี้ก็จะใส่ข้อความเหล่านี้ที่พวกเขาไม่ได้อยู่ในกรณีนี้ก่อให้เกิดมลพิษกระแสโปรโตคอลระหว่างscp2
/ และsftp
sftp-server
เหตุผลที่ไฟล์เริ่มต้นของเชลล์มีความเกี่ยวข้องเลยก็คือsshd
ใช้เชลล์ของผู้ใช้เมื่อเริ่มต้นโปรแกรมใด ๆ ในนามของผู้ใช้
(ใช้เช่น / bin / sh -c "คำสั่ง") นี่เป็นประเพณี Unix และมีข้อดี:
- การตั้งค่าปกติของผู้ใช้ (นามแฝงคำสั่งตัวแปรสภาพแวดล้อม umask ฯลฯ ) จะมีผลเมื่อเรียกใช้คำสั่งระยะไกล
- การปฏิบัติโดยทั่วไปของการตั้งค่าเชลล์ของบัญชีเป็น / bin / false เพื่อปิดการใช้งานจะเป็นการป้องกันเจ้าของไม่ให้รันคำสั่งใด ๆ หากการพิสูจน์ตัวตนยังคงประสบความสำเร็จโดยไม่ได้ตั้งใจด้วยเหตุผลบางประการ
รายละเอียดโปรโตคอล SCP
สำหรับผู้ที่สนใจรายละเอียดเกี่ยวกับวิธีการทำงานของ SCP ฉันพบข้อมูลที่น่าสนใจในวิธีการทำงานของ SCPซึ่งรวมถึงรายละเอียดเกี่ยวกับการเรียกใช้ scp ด้วยโปรไฟล์เชลล์แบบพูดคุยที่ด้านไกล :
ตัวอย่างเช่นสิ่งนี้สามารถเกิดขึ้นได้หากคุณเพิ่มสิ่งนี้ลงในโปรไฟล์เชลล์ของคุณบนระบบรีโมต:
echo ""
ทำไมมันถึงหยุด ที่มาจากวิธีการที่scp
ในแหล่งโหมดรอการยืนยันจากข้อความโปรโตคอลแรก หากไม่ใช่ไบนารี 0 คาดว่าจะเป็นการแจ้งเตือนปัญหาระยะไกลและรอให้อักขระเพิ่มขึ้นเพื่อสร้างข้อความแสดงข้อผิดพลาดจนกว่าจะถึงบรรทัดใหม่ เนื่องจากคุณไม่ได้พิมพ์อีกบรรทัดใหม่หลังจากบรรทัดแรกท้องถิ่นของคุณscp
ก็ยังคงวนซ้ำถูกบล็อกread(2)
ไว้ ในระหว่างนี้หลังจากที่ประมวลผลโปรไฟล์เชลล์บนรีโมตแล้วscp
ในโหมด sink เริ่มต้นซึ่งยังบล็อกอยู่read(2)
โดยรอเป็นศูนย์ไบนารี่ซึ่งแสดงถึงการเริ่มการถ่ายโอนข้อมูล
สรุป / TLDR
ส่วนใหญ่ของงบในทั่วไป.bashrc
จะมีประโยชน์สำหรับเปลือกโต้ตอบ - ไม่ได้เมื่อใช้คำสั่งระยะไกลด้วยหรือrsh
ssh
ในสถานการณ์เช่นนี้ส่วนใหญ่การตั้งค่าตัวแปรเปลือกนามแฝงและการกำหนดฟังก์ชั่นไม่ได้ต้องการ - และการพิมพ์ข้อความใด ๆที่จะออกมาตรฐานเป็นอันตรายอย่างแข็งขันถ้าการถ่ายโอนไฟล์โดยใช้โปรแกรมเช่นหรือscp
การออกหลังจากการตรวจสอบว่าเปลือกปัจจุบันคือไม่โต้ตอบเป็นพฤติกรรมที่ปลอดภัยที่สุดสำหรับsftp
.bashrc