เหตุใดคำสั่งระยะไกล SSH จึงได้รับตัวแปรสภาพแวดล้อมน้อยลงเมื่อทำงานด้วยตนเอง [ปิด]


239

ฉันมีคำสั่งที่ทำงานได้ดีถ้าฉัน ssh กับเครื่องและเรียกใช้ แต่ล้มเหลวเมื่อฉันพยายามเรียกใช้โดยใช้คำสั่ง ssh จากระยะไกลเช่น:

ssh user@IP <command>

การเปรียบเทียบผลลัพธ์ของ "env" โดยใช้ทั้งสองวิธีจะดำเนินการต่อในสภาพแวดล้อมที่แตกต่างกัน เมื่อฉันเข้าสู่ระบบด้วยตนเองและเรียกใช้ env ฉันจะได้รับตัวแปรสภาพแวดล้อมมากขึ้นเมื่อฉันเรียกใช้:

ssh user@IP "env"

มีความคิดอะไรบ้าง


30
เพราะเหตุใดคำถามนี้จึงถูกปิดเป็นหัวข้อปิด
jottr

13
อาจเป็นเพราะมันไม่ได้เกี่ยวข้องกับการเขียนโปรแกรม ควรย้ายไปที่ Super User แทนที่จะปิด
Daniel H

8
bashไม่ใช่ภาษาสคริปต์?
Dan Nissenbaum

ใน Debian 8 ฉันต้องเปลี่ยนเชลล์เป็นทุบตีใน / etc / passwd ด้วยเหตุผลบางอย่าง แม้แต่การกำหนดค่าขีดกลางใหม่เพื่อให้ / bin / sh ชี้ไปที่ทุบตีก็ไม่ได้ช่วยอะไร
user1050755

คำตอบ:


173

เชลล์มีหลายประเภท เชลล์การดำเนินการคำสั่ง SSH เป็นเชลล์แบบไม่โต้ตอบในขณะที่เชลล์ปกติของคุณเป็นเชลล์ล็อกอินหรือเชลล์แบบโต้ตอบ คำอธิบายดังนี้จากการทุบตีมนุษย์:

       เชลล์ล็อกอินคือหนึ่งที่มีอาร์กิวเมนต์ตัวแรก
       ศูนย์คือ - หรือเริ่มด้วยตัวเลือก --login

       เชลล์เชิงโต้ตอบเริ่มต้นหนึ่งโดยไม่มีตัวเลือก
       อาร์กิวเมนต์และไม่มีตัวเลือก -c ซึ่งมีอินพุตมาตรฐาน
       และข้อผิดพลาดทั้งสองเชื่อมต่อกับขั้ว (ตามที่กำหนด
       โดย isatty (3)) หรือเริ่มต้นด้วยตัวเลือก -i PS1 คือ
       กำหนดและ $ - รวมถึงฉันถ้าทุบตีเป็นแบบโต้ตอบการอนุญาต
       เชลล์สคริปต์หรือไฟล์เริ่มต้นเพื่อทดสอบสถานะนี้

       ย่อหน้าต่อไปนี้อธิบายถึงวิธีการทุบตีรัน
       ไฟล์เริ่มต้น หากมีไฟล์ใด ๆ อยู่ แต่ไม่สามารถทำได้
       อ่านทุบตีรายงานข้อผิดพลาด Tildes ถูกขยายในไฟล์
       ชื่อตามที่อธิบายไว้ด้านล่างภายใต้ Tilde Expansion ใน
       ส่วนการขยาย

       เมื่อ bash ถูกเรียกใช้เป็นเชลล์ล็อกอินแบบโต้ตอบหรือเป็น
       เชลล์ที่ไม่มีการโต้ตอบพร้อมด้วยตัวเลือก --login เป็นเชลล์ก่อน
       อ่านและดำเนินการคำสั่งจากไฟล์ / etc / profile ถ้า
       มีไฟล์นั้นอยู่ หลังจากอ่านไฟล์นั้นแล้วมันจะค้นหา
       ~ / .bash_profile, ~ / .bash_login และ ~ / .profile ในนั้น
       สั่งซื้อและอ่านและดำเนินการคำสั่งจากคนแรก
       ที่มีอยู่และสามารถอ่านได้ ตัวเลือก - ไม่มีโปรไฟล์อาจ
       ใช้เมื่อเชลล์เริ่มยับยั้งพฤติกรรมนี้
       IOR

       เมื่อเชลล์ล็อกอินออกจาก bash จะอ่านและดำเนินการคำสั่ง
       จากไฟล์ ~ / .bash_logout หากมีอยู่

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

       เมื่อ bash เริ่มทำงานแบบไม่โต้ตอบให้เรียกใช้ shell
       ตัวอย่างเช่นสคริปต์ค้นหาตัวแปร BASH_ENV ใน
       สภาพแวดล้อมขยายค่าถ้ามันปรากฏขึ้นที่นั่น
       และใช้ค่าที่ขยายเป็นชื่อของไฟล์ที่จะอ่าน
       และดำเนินการ Bash ทำตัวเหมือนคำสั่งต่อไปนี้
       ถูกประหารชีวิต:
              ถ้า [-n "$ BASH_ENV"]; จากนั้น "$ BASH_ENV"; Fi
       แต่ค่าของตัวแปร PATH ไม่ได้ถูกใช้เพื่อค้นหา
       สำหรับชื่อไฟล์


7
คำตอบที่ดีนี่เป็นปัญหาอย่างแน่นอนตัวแปรสภาพแวดล้อมที่จำเป็นต้องมีอยู่ใน / etc / bashrc ซึ่งไม่ได้มีแหล่งที่มาในโหมดที่ไม่โต้ตอบ การย้ายไปยัง / etc / profile ช่วยแก้ปัญหา ขอบคุณมาก!
Tom Feiner

1
คำตอบนี้มีเพียงบางส่วนเท่านั้น ต่อไปนี้เป็นข้อมูลเพิ่มเติม: เพิ่มตัวแปรสภาพแวดล้อมที่แตกต่างกัน (เช่นส่งออก SOURCED_SYSTEM_ETC_BASHRC) ไปยังไฟล์ต่างๆที่ได้รับแหล่งที่มา: / etc / profile, etc / bashrc, ~ / .profile, ~ / .bash_profile, ~ / bashrc จากนั้นมองหาตัวแปรที่ไม่เหมือนใครในเอาต์พุตเจนกินส์ ในกรณีของฉันฉันอัพเดต / etc / bashrc เพื่อให้มี 'export SOURCED_SYSTEM_ETC_BASHRC = ใช่' และตัวแปรนั้นปรากฏในบันทึก Jenkins สำหรับโหนด ดังนั้นในกรณีของฉันการตั้งค่าตัวแปรสภาพแวดล้อมสำหรับทาสเจนกินส์พวกเขาต้องไปใน / etc / bashrc Jenkins ssh เข้าสู่ระบบเท่านั้นที่มา / etc / bashrc
Coder Roadie

การแก้ไข: ฉันหมายถึง /etc/bash.bashrc ไม่ใช่ / etc / bashrc
Coder Roadie

37
นั่นเป็นกำแพงข้อความฉันคิดว่ามันจะเป็นการเน้นที่คุ้มค่าที่ssh user@host "bash --login -c 'command arg1 ...'"จะทำให้เชลล์ระยะไกลตั้งค่าสภาพแวดล้อมการเข้าสู่ระบบ ส่วนที่คุณอ้างถึงไม่พูดถึง--loginแต่จะง่ายต่อการมองข้ามนี้
codebeard

ขอบคุณสำหรับการโพสต์นี้ฉันใช้ssh <ssh options> <IP> bash --login my_script.shในการเรียกใช้สคริปต์บนเครื่องระยะไกลทำงานรักษาและช่วยให้ฉันประสบความสำเร็จในการใช้JAVA_HOME
vv

117

วิธีการเกี่ยวกับการหารายละเอียดก่อนที่จะใช้คำสั่ง?

ssh user@host "source /etc/profile; /path/script.sh"

คุณอาจพบมันที่ดีที่สุดที่จะเปลี่ยนที่ไป~/.bash_profile, ~/.bashrcหรืออะไรก็ตาม

(ตามที่นี่ (linuxquestions.org) )


1
หากมีปัญหานี้วิธีนี้ใช้ได้ดี
Sam152

10
ต้องพิมพ์รหัสพิเศษทุกครั้งเพื่อแหล่งสภาพแวดล้อมนั้นไร้สาระ!
Michael

4
สิ่งหนึ่งที่ไม่ค่อยพิมพ์สิ่งต่าง ๆ เหล่านี้ซ้ำ ๆ โดยปกติมันจะอยู่ในสคริปต์และเช่นนั้นไม่สำคัญว่าจะมี "รหัสพิเศษ" ที่มีอยู่ตราบเท่าที่มันใช้งานได้: tm:
Ian Vaughan

1
หากฉันแหล่งที่มาทั้ง / etc / profile และ ~ / .bash_profile (เพื่อให้ผู้ใช้เพิ่มไปยังเส้นทาง) มันใช้งานได้ แต่มันน่าเกลียด จะต้องมีวิธีที่ง่ายกว่าในการบอกคำสั่ง (ในกรณีของฉัน xterm) เพื่อใช้การเข้าสู่ระบบ "แบบโต้ตอบ" และจบลงด้วยเส้นทางแบบผู้ใช้เฉพาะบนเครื่องระยะไกลหรือไม่
เจส

ssh $ 1 "source ~ / .bashrc; ~ / temp_unix.sh" ที่นี่ temp_unix.sh ส่งออก MANI_HOME = "mani deepak" แต่มันไม่ทำงาน
มณี Deepak

90

สภาพแวดล้อมของเชลล์ไม่โหลดเมื่อใช้คำสั่ง ssh จากระยะไกล คุณสามารถแก้ไขไฟล์สภาพแวดล้อม ssh:

vi ~/.ssh/environment

รูปแบบของมันคือ:

VAR1=VALUE1
VAR2=VALUE2

ตรวจสอบsshdการกำหนดค่าสำหรับPermitUserEnvironment=yesตัวเลือก


1
ความสมบูรณ์แบบ! +100 ถ้าฉันทำได้ :)
Dexter

VisualGDB ล้มเหลวโดยมีข้อผิดพลาด "ไม่พบคำสั่ง bash: gcc:" และวิธีการแก้ไขนี้ได้แก้ไขแล้ว
KalenGi

น่าอัศจรรย์ หวังว่าฉันจะรู้เรื่องนี้เมื่อหลายปีก่อน
ความโน้มถ่วง

นี่คือคำตอบที่สมบูรณ์แบบ!
จิราพงษ์

1
@ pg2455 ในขณะที่คุณไม่สามารถกำหนดค่า sshd บนเซิร์ฟเวอร์ของคุณได้เสมอ (หรือไม่ต้องการเปิดใช้งานทั้งหมด) คุณยังสามารถแก้ไขสภาพแวดล้อมผู้ใช้ของคุณได้
dpedro

63

ฉันมีปัญหาที่คล้ายกัน แต่ในที่สุดฉันก็พบว่า ~ / .bashrc เป็นสิ่งที่ฉันต้องการ

อย่างไรก็ตามใน Ubuntu ฉันต้องแสดงความคิดเห็นในบรรทัดที่หยุดการประมวลผล ~ / .bashrc:

#If not running interactively, don't do anything
[ -z "$PS1" ] && return

8
หรือคุณสามารถวางโค้ด "ไม่โต้ตอบ" ทั้งหมดไว้ด้านบนบรรทัดนั้น
machineghost

สวยช่วยฉันได้เยอะ :) ขอบคุณ
แลนซ์พอลลาร์

ขอบคุณ /etc/bash.bashrcเพียงแค่เพิ่มว่าไฟล์ที่มีคำสั่งกลับสามารถพบได้ที่
adarshr

อย่างไรก็ตามมีการเลี่ยงรหัสนี้ในเซิร์ฟเวอร์โดยไม่เปลี่ยนหรือไม่
Yoni

ฉันใช้เวลามากมายในการพยายามทำความเข้าใจว่าทำไมสคริปต์ของฉันจึงไม่ทำงาน ใครคิดว่าเป็นความคิดที่ดีที่จะใส่บรรทัดเหล่านี้ใน. bashrc ???
Sharcoux

4

ฉันพบวิธีแก้ไขปัญหาที่ง่ายสำหรับปัญหานี้คือการเพิ่ม source / etc / profile ไว้ด้านบนของไฟล์ script.sh ที่ฉันพยายามเรียกใช้บนระบบเป้าหมาย บนระบบที่นี่สิ่งนี้ทำให้เกิดตัวแปรสภาวะแวดล้อมที่ script.sh ต้องการเพื่อกำหนดค่าราวกับว่ากำลังทำงานจากล็อกอินเชลล์

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


ที่สมบูรณ์แบบ! วิธีแก้ไขปัญหาแบบบรรทัดเดียวที่ดี
corpico

3

เพียงแค่ส่งออกตัวแปรสภาพแวดล้อมที่คุณต้องการเหนือการตรวจสอบเชลล์ที่ไม่มีการโต้ตอบใน ~ / .bashrc

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.