ทำไม Bash ไม่พบคำสั่งแม้ว่าจะระบุ $ PATH อย่างถูกต้องหรือไม่


9

ฉันกำลังระบุพา ธ ไปยังคำสั่งของฉันในไฟล์/ etc / profile :

export PATH=$PATH:/usr/app/cpn/bin

คำสั่งของฉันอยู่ใน:

$ which ydisplay 
/usr/app/cpn/bin/ydisplay

ดังนั้นเมื่อฉันแสดงเอาต์พุต "echo $ PATH" ดูเหมือนว่า:

$ echo $PATH
...:/usr/app/cpn/bin

และทุกอย่างก็โอเค แต่เมื่อฉันพยายามที่จะเปิดคำสั่งของฉันผ่าน SSH ฉันได้รับข้อผิดพลาด:

$ ssh 127.0.0.1 ydisplay
$ bash: ydisplay: command not found

แต่เส้นทางของฉันยังคงอยู่:

$ ssh 127.0.0.1 echo $PATH
...:/usr/app/cpn/bin

โปรดอธิบายฉันว่าเหตุใด Bash ไม่สามารถหา ydisplay ในระหว่างเซสชัน SSH และวิธีกำหนดค่า SSH ให้เหมาะสมเพื่อหลีกเลี่ยงปัญหานี้

ยิ่งกว่านั้นหากฉันระบุ $ PATH ในไฟล์. bashrc ในผู้ใช้ปัจจุบันทำงานได้อย่างถูกต้อง แต่ฉันต้องการแก้ไขเพียงหนึ่งไฟล์แทนการระบุไฟล์จำนวนมากสำหรับผู้ใช้แต่ละคน นี่คือเหตุผลที่ฉันถาม


1
ทำงานแค่ydisplayไหน ไม่ssh 127.0.0.1 /usr/app/cpn/bin/ydisplayทำงานหรือไม่
Bananguin

@ user1129682 ใช่ ydisplay ที่มีชื่อเต็มตามที่ระบุและ ydisplay ทำงาน
SIGSEGV

เมื่อคุณไม่ได้เข้าสู่ระบบ (คุณไม่มีเซสชันระยะไกล) แต่เพียงส่งคำสั่งจากระยะไกลคุณไม่ต้องเข้าถึงตัวแปรสภาพแวดล้อมในลักษณะเดียวกันเพราะไฟล์. bashrc / .profile ของคุณจะไม่ถูกเรียกใช้งาน นี่คือเหตุผลเนื่องจากรับผิดชอบการตั้งค่าตัวแปรสำหรับเซสชันปัจจุบัน
mnmnc

14
แค่ข้อความด้านข้าง: ssh 127.0.0.1 echo $PATHไม่ได้ทำในสิ่งที่คุณอาจคิดว่ามันทำ: เชลล์ขยาย $ PATH ก่อนที่ ssh จะถูกเรียกใช้งานดังนั้นแม้จะไม่ได้พิสูจน์หรือพิสูจน์อะไรเลย
Ulrich Schwarz

2
คำถาม StackOverflow นี้อาจจะมีบางความช่วยเหลือ
BSD

คำตอบ:


5

TL; DR

เล่นssh 127.0.0.1 ydisplayแหล่งที่มามากกว่า~/.bashrc /etc/profileเปลี่ยนเส้นทางของคุณ~/.bashrcแทน

รายละเอียด

การ/etc/profileอ่านครั้งเดียวเท่านั้นคือเมื่อเชลล์ของคุณเป็น "เชลล์การเข้าสู่ระบบ"

จากคู่มืออ้างอิง Bash :

เมื่อ bash ถูกเรียกใช้เป็นเชลล์การเข้าสู่ระบบ ... มันจะอ่านและเรียกใช้คำสั่งจากไฟล์ / etc / profile ก่อน

แต่เมื่อคุณทำงานssh 127.0.0.1 ydisplay, bashไม่ได้เริ่มต้นเป็นเปลือกเข้าสู่ระบบ แต่มันจะอ่านไฟล์เริ่มต้นที่แตกต่างกัน คู่มือทุบตีอ้างอิงพูดว่า:

เมื่อ ... ดำเนินการโดย ... sshd ... มันอ่านและดำเนินการคำสั่งจาก~/.bashrc

ดังนั้นคุณควรใส่ของคุณการตั้งค่าในPATH~/.bashrc

ในระบบส่วนใหญ่~/.bash_profileแหล่งที่มา~/.bashrcดังนั้นคุณสามารถตั้งค่าได้เฉพาะใน~/.bashrcแทนที่จะวางไว้ในไฟล์ทั้งสอง

ไม่มีวิธีมาตรฐานในการเปลี่ยนการตั้งค่าสำหรับผู้ใช้ทั้งหมด แต่ระบบส่วนใหญ่มี/etc/bashrc, /etc/bash.bashrcหรือที่คล้ายกัน

ความล้มเหลวที่ตั้งค่าpam_envและใส่การตั้งค่าในPATH/etc/environment

ดูสิ่งนี้ด้วย:


1

ในอดีตไฟล์โปรไฟล์ ( /etc/profileและ~/.profile) ถูกเรียกใช้เมื่อคุณเข้าสู่ระบบ (บนคอนโซลข้อความมีอะไรอีกบ้าง) และรับใช้จุดประสงค์มากมาย:

  • ตั้งค่าตัวแปรสภาพแวดล้อมและพารามิเตอร์อื่น ๆ (เช่น umask) สำหรับเซสชัน
  • เรียกใช้โปรแกรมพิเศษเมื่อเริ่มต้นเซสชัน (เช่นการแจ้งเตือนทางอีเมล)
  • เรียกใช้โปรแกรมสำหรับเซสชันหากแตกต่างจากเชลล์ (เช่นเชลล์อื่นหรือ X Window)
  • ตั้งค่าพารามิเตอร์เทอร์มินัล (เช่นstty)
  • ตั้งค่าพารามิเตอร์ของเชลล์ (เช่นนามแฝง)

วัตถุประสงค์ทั้งหมดเหล่านี้ไม่ได้ระบุว่าแยกกันจนกระทั่งภายหลัง เนื่องจากสคริปต์โปรไฟล์อาจทำสิ่งต่าง ๆ ที่เหมาะสมในเซสชันแบบโต้ตอบเท่านั้น (การโต้ตอบเทอร์มินัลเริ่มโปรแกรมอื่น ๆ ) เมื่อเปิดใช้การเรียกใช้เชลล์ระยะไกล ( rsh ) การใช้ rsh จึงตัดสินใจที่จะไม่เรียกใช้เชลล์ระยะไกลเป็นเชลล์ล็อกอิน เพื่อไม่ให้สคริปต์โปรไฟล์ทำงาน (บางรุ่นrshdมีตัวเลือกในการเรียกใช้เปลือกระยะไกลเป็นเปลือกเข้าสู่ระบบ) Ssh คัดลอกพฤติกรรมนี้เพื่อที่จะแทนที่แบบหล่นในสำหรับ rsh

หากคุณต้องการให้สคริปต์โปรไฟล์ทำงานคุณสามารถเรียกใช้งานสคริปต์เหล่านั้นอย่างชัดเจน

ssh 127.0.0.1 '. /etc/profile; . ~/.profile; ydisplay'

หมายเหตุคำสั่ง.เพื่อโหลดสคริปต์โปรไฟล์ภายในเชลล์: เป็นคำสั่งที่ต้องดำเนินการภายในเชลล์นั้นไม่ใช่โปรแกรมภายนอก

หากคุณต้องการตั้งค่าตัวแปรสภาพแวดล้อมทั่วโลกสำหรับผู้ใช้ทุกคนมีวิธีอื่นในระบบหลายแทนการกำหนดไว้ในกำหนดไว้ใน/etc/profile /etc/environmentไฟล์นี้อ่านผ่านpam_envโมดูล ลีนุกซ์ส่วนใหญ่ถูกตั้งค่าให้อ่าน

หากเชลล์ล็อกอินของคุณทุบตีจะมีความเป็นไปได้อีก โดยปกติคุณไม่ควรตั้งค่าตัวแปรสภาพแวดล้อมเป็น.bashrc (เพราะจะไม่ถูกตั้งค่าในเซสชัน X ยกเว้นว่าคุณผ่านเทอร์มินัลที่มีเชลล์แบบโต้ตอบเพราะมันจะไม่ถูกตั้งค่าหากคุณเข้าสู่ระบบแบบโต้ตอบบนคอนโซลข้อความหรือบน ssh, เพราะมันจะแทนที่การตั้งค่าแบบกำหนดเองหากคุณเรียกใช้เชลล์ภายในโปรแกรมอื่น) อย่างไรก็ตามทุบตีมีคุณสมบัติแปลกที่ฉันไม่เคยเข้าใจ: มันอ่าน~/.bashrcในสองสถานการณ์ที่ไม่เกี่ยวข้อง:

  • ในเชลล์เชิงโต้ตอบที่ไม่ใช่ล็อกอินเชลล์
  • ในเปลือกหอยที่ไม่ใช่แบบโต้ตอบที่ไม่ได้เข้าสู่ระบบหอยถ้าทุบตีคิดว่ามันได้รับการเรียกโดยหรือrshdsshd

เมื่อคุณเรียกใช้คำสั่งผ่าน ssh คุณจะอยู่ในกรณีที่สอง คุณสามารถจัดให้มีรายละเอียดของคุณอ่านด้วยการอ่าน/etc/profileและจาก.profile .bashrcรวมรหัสต่อไปนี้ในของคุณ~/.bashrc:

case $- in
  *i*) :;; # this is an interactive shell, fine
  *) # This is not an interactive shell! This must be a non-interactive remote shell session.
    . /etc/profile; . ~/.profile
    return;;
esac
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.