นี่เป็นคำถามที่ฉันจะโพสต์ที่นี่ไม่กี่สัปดาห์ที่ผ่านมา เช่นเดียวกับ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/ และsftpsftp-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