เรียกใช้คำสั่ง Remote ssh ด้วย Full Login Shell


48

ฉันต้องการทำบางสิ่งเช่นssh example.com 'ls'อย่างไรก็ตามตาม mansh ssh:

หากระบุคำสั่งคำสั่งจะถูกดำเนินการบนรีโมตโฮสต์แทนที่จะเป็นเชลล์ล็อกอิน

ดังนั้นสิ่งที่เกิดขึ้นก็คือlsมันแสดงว่ามันเป็นเอาต์พุตแล้วออกจาก ssh

สิ่งที่ฉันไม่สามารถหาได้คือทำอย่างไรถึงจะเปิดเชลล์การเข้าสู่ระบบแบบเต็มจากนั้นให้รันคำสั่งภายในเชลล์นั้น ปล่อยให้เชลล์เปิดค้างไว้หลังจากรันคำสั่ง ราวกับว่าฉันได้ทำต่อไปนี้ด้วยตนเอง:

  localhost$ ssh example.com 
example.com$ ls
             /folder1 
             /folder2 
example.com$ _

ความคิดใด ๆ


นี่เป็นคำถามที่คล้ายกันsuperuser.com/questions/261617/…แต่ไม่มีคำตอบใดที่ดูเหมือนจะพอดีกับสิ่งที่ฉันพยายามทำ
matthew

แล้วไงssh example.com 'ls;bash'ล่ะ
Andrejs Cainikovs

คุณต้องการ -i บนระบบของฉันเพื่อทำให้เชลล์ตัวที่สองเป็นแบบอินเตอร์แอคทีฟ
เฟล็กโซ

ตัวเลือก -t คือคำตอบสำหรับคำถามของคุณ มีตัวเลือกอื่น ๆ (เช่นพวงกุญแจ) แต่ขึ้นอยู่กับความต้องการที่แท้จริงของคุณซึ่งไม่ชัดเจนพอสำหรับฉัน
Hornetbzz

@hornetbzz ให้ฉันหลอก -tty แต่อย่างอื่นพฤติกรรมก็เหมือนกัน ฉันต้องการเปิดใช้เชลล์แบบโต้ตอบเรียกใช้คำสั่งภายในเชลล์นั้นและให้เชลล์ยังคงเปิดอยู่หลังจากรันคำสั่ง
matthew

คำตอบ:


40

เพียงแค่บอกว่าทุบตีเพื่อดำเนินการlsแล้วตัวเองในเปลือกเข้าสู่ระบบ

$ ssh user@host  -t 'bash -l -c "ls;bash"'

2
screenแต่น่าเสียดายที่นี้ไม่ปรากฏขึ้นในการทำงานในขณะที่ใช้ มิฉะนั้นดูเหมือนว่ามันจะเป็นสิ่งที่ฉันพยายามจะทำ
matthew

31
ssh user@host -t 'ls; exec $SHELL -l'

-tบังคับการจัดสรรเทอร์มินัลเทียม สิ่งนี้สามารถใช้เพื่อรันโปรแกรมบนหน้าจอโดยพลการบนเครื่องระยะไกล มีความเหมาะสมมากกว่าbash -iเล็กน้อย

exec ไม่มีการสร้างกระบวนการใหม่

-lค้นหา ~ / .bash_profile, ~ / .bash_login และ ~ / .profile ตามลำดับและอ่านและดำเนินการคำสั่งจาก ... หากไม่มีสิ่งนี้คุณอาจไม่สามารถเรียกใช้สคริปต์ / คำสั่งจากไดเรกทอรี ~ / bin ได้เนื่องจากรหัสนี้ จาก ~ / .profile จะไม่ถูกดำเนินการโดยไม่มีการ-lตั้งค่าสถานะ:

if [ -d "$HOME/bin" ] ; then
    PATH="$HOME/bin:$PATH"
fi

@grawity @Alan สิ่งนี้อาจทำงานเป็นวิธีแก้ปัญหา แต่ฉันต้องการให้คำสั่งทำงานในเชลล์และไม่เพียงแค่เปิดเชลล์ใหม่หลังจากรันคำสั่งแล้ว
matthew

+1, -t เป็นวิธีที่ถูกต้องที่จะไป -i ฉันลืมไปแล้ว
เฟล็กโซ

@ matthew: คุณจะต้องแก้ไขbashด้วยตัวเองเพื่อให้มัน
grawity

@grawity ไม่ได้จริงๆดูคำตอบของฉันด้านล่าง
fons

@ matthew ใช้exec bashหรือexec $SHELL
Eugen Konkov

1

ในความคิดเห็นของคุณกับคำตอบ Fons screenของคุณบอกว่ามันไม่ทำงานในขณะที่ใช้

คุณช่วยอธิบายเรื่องนี้ให้ละเอียดหน่อยได้ไหม? ดูซอร์สโค้ดสำหรับ openssh, sshd ดำเนินการคำสั่งโดยการเรียก

YOUR_DEFAULT_SHELL -c COMMAND

ดังนั้นสำหรับตัวอย่างเช่นถ้าเปลือกเริ่มต้นของคุณscreenแล้วนี้จะไม่ทำงานทั้งหมดที่ดีเพราะscreen's ธงเพียงแทนที่ของมัน-c .scrreenrcดังนั้นจึงไม่มีวิธีการส่งคำสั่งไปยังหน้าจอหากเป็นเชลล์เริ่มต้นของคุณ คุณจะต้องทำงานหน้าจอจริงเป็นคำสั่งที่กำหนดให้ SSH แต่มีเปลือกเริ่มต้นที่ไม่ได้อยู่หน้าจอ

ถ้านั่นคือสิ่งที่คุณกำลังพยายามทำฉันคิดว่าสิ่งต่าง ๆ จะแปลกจริง ๆ เนื่องจากscreenจะปิดหน้าต่างด้วยโปรแกรมที่ไม่โต้ตอบดังนั้นคุณจะต้องใช้กลอุบายที่คล้ายกันกับแฟน ๆ ดังนั้นด้วย, เช่น / bin / bash (ไม่ใช่หน้าจอ)เป็นเชลล์เริ่มต้นของคุณสิ่งที่ชอบ:

ssh user@host -t 'screen bash -l -c "ls;bash"'

ซึ่งควร - สูดหายใจเข้าลึก ๆ - ssh เข้าไปในโฮสต์รัน bash -c ด้วยคำสั่งของหน้าจอซึ่งจะสร้างหน้าต่างใหม่ หากหน้าต่างนี้เพิ่งเปิดขึ้น LS มันจะจบลงและหน้าจอจะยุติดังนั้นเราจึงใช้เคล็ดลับ Fons ของภายในหน้าต่างหน้าจอใหม่

ฉันคิดว่ามันจะได้ผลถ้านั่นคือสิ่งที่คุณพยายามทำ;)


ผมคิดว่าปัญหาที่ผมมีกับscreenในสถานการณ์เช่นนี้เป็นที่ฉันตามปกติโหลดด้วยจากฉันexec screen -RR .profileซึ่งหมายความว่าbash -lพยายามโหลดหน้าจอซึ่งทำให้ส่วนที่เหลือของหน้าจอหลุดออก ดูเหมือนว่าฉันสามารถแก้ไขได้โดยลบ '-l' ทั้งในโซลูชันของคุณและ @fons (ของคุณจะทิ้งฉันไว้screen) แม้ว่ามันจะสกปรก แต่อย่างใด
matthew

0

อ็อพชัน -t หลายตัวบังคับให้จัดสรร tty แม้ว่า ssh จะไม่มี tty โลคัล:

ssh -tt user@host 'bash -l -c "/path/to/command'
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.