การใช้ SSH เพื่อเริ่มกระบวนการจากระยะไกล


18

ฉันได้เขียนสคริปต์ที่ฉันใช้เพื่อผลักดันและปรับใช้บริการใหม่ให้กับหลาย ๆ เครื่องภายใต้การควบคุมของฉันและเพื่อดำเนินการตามกระบวนการที่ฉันใช้โดยใช้ ssh เพื่อเริ่มกระบวนการจากระยะไกล น่าเสียดายที่เมื่อใดก็ตามที่ฉันใช้ SSH เพื่อเริ่มต้นกระบวนการคำสั่ง SSH ดูเหมือนจะไม่กลับมาทำให้สคริปต์หยุดทำงาน

คำสั่งถูกระบุเป็น: ssh $ user @ $ host "/ root / command &" เมื่อใดก็ตามที่ฉันรันคำสั่งง่าย ๆ เช่น ps หรือใครคำสั่ง SSH จะกลับมาทันที แต่เมื่อฉันลองและเริ่มกระบวนการของฉันมันจะไม่กลับมา ฉันได้ลองใช้เทคนิคต่าง ๆ เช่นห่อกระบวนการของฉันในสคริปต์ทุบตีง่ายที่เริ่มต้นกระบวนการและจากนั้นออกอย่างไรก็ตามสิ่งนี้ยังแฮงค์คำสั่ง SSH (แม้ว่าสคริปต์ทุบตี echos ข้อความความสำเร็จและออกตามปกติ)

ใครบ้างมีความเข้าใจอย่างถ่องแท้ถึงสิ่งที่ทำให้เกิดพฤติกรรมนี้และฉันจะรับคำสั่ง SSH ให้กลับมาทันทีที่เริ่มกระบวนการได้อย่างไร

ขอบคุณสำหรับข้อมูลเชิงลึกของคุณ!


โพสต์บรรทัดคำสั่งที่แน่นอนที่คุณกำลังใช้ ... งดรหัสผ่าน / ชื่อผู้ใช้ / IP ที่
โจเซฟเคอร์

ssh $ SSH_USER @ $ HOST_ADDR "/ root / AppName &"
rmrobins

ฉันควรพูดถึงว่าฉันได้ตั้งค่าคีย์ SSH ดังนั้นจึงไม่จำเป็นต้องใช้รหัสผ่านเพื่อเรียกใช้คำสั่งในระบบระยะไกล
rmrobins

@rmrobins เป็นขั้นตอนที่ดีมาก - ตั้งค่าคีย์สาธารณะรับรองความถูกต้อง
nik

คำตอบ:


28

SSH เชื่อมต่อ stdin, stdout และ stderr ของ remote shell เข้ากับเทอร์มินัลท้องถิ่นของคุณเพื่อให้คุณสามารถโต้ตอบกับคำสั่งที่ทำงานบนด้านรีโมต

เป็นผลข้างเคียงมันจะทำงานต่อไปจนกว่าการเชื่อมต่อเหล่านี้จะถูกปิดซึ่งเกิดขึ้นเมื่อคำสั่งระยะไกลและลูก ๆ ของมันทั้งหมด (!) ได้ยกเลิก (เพราะเด็ก ๆ ซึ่งเป็นสิ่งที่ "&" เริ่มต้นสืบทอด std * จากพวกเขา กระบวนการหลักและเปิดไว้)

ดังนั้นคุณต้องใช้สิ่งที่ชอบ

ssh user@host "/script/to/run < /dev/null > /tmp/mylogfile 2>&1 &"

<,> และ 2> & 1 เปลี่ยนเส้นทาง stdin / stdout / stderr ห่างจากเทอร์มินัลของคุณ เครื่องหมาย "&" ทำให้สคริปต์ของคุณเป็นพื้นหลัง ในการผลิตแน่นอนว่าคุณต้องการเปลี่ยนเส้นทาง stdin / err ไปยังล็อกไฟล์ที่เหมาะสม

ดู

http://osdir.com/ml/network.openssh.general/2006-05/msg00017.html

แก้ไข:

เพิ่งค้นพบว่า< /dev/nullข้างต้นไม่จำเป็น (แต่การเปลี่ยนเส้นทาง stdout / err เป็น ) ไม่รู้เลยว่าทำไม ...


ขอบคุณนี่คือสิ่งที่ฉันกำลังมองหา - มันไม่ได้เกิดขึ้นกับฉันว่ากระบวนการจะสืบทอด std * แม้ว่าจะใช้ & เพื่อเปิดในพื้นหลัง
rmrobins

+1! ใช้งานได้สำหรับฉัน และคุณยังสามารถพิมพ์เอาต์พุตโดย echo ไฟล์บันทึก: ssh user@host "/script/to/run > /tmp/ssh.stdout 2>&1 && cat /tmp/ssh.stdout && rm -f /tmp/ssh.stdout"
Fishdrowned

5

คุณอาจจะลองnohup ไม่มีคนสำหรับรายละเอียดเพิ่มเติม

ssh host "nohup script &"

หากคุณต้องการที่จะทำให้การส่งออกบนเครื่องระยะไกล, นี่เป็นตัวแปร

ssh user@host 'export REMOTE=myname; nice nohup ./my-restart >
logfile.log 2>&1 &'

5

อีกทางเลือกหนึ่งคือใช้ไฟที่แยกออกscreen(1)มาเช่น:

ssh -l user host "screen -d -m mycommand"

นี้จะเริ่มต้นหน้าจอเดี่ยว (ซึ่งจับการโต้ตอบทั้งหมดภายในของมัน) จากนั้นกลับทันทียุติเซสชั่น ssh

ด้วยความเฉลียวฉลาดมากขึ้นคุณสามารถแก้คำสั่งระยะไกลที่ค่อนข้างซับซ้อนเรียกวิธีนี้ได้


4
 -f      Requests ssh to go to background just before command execution.
         This is useful if ssh is going to ask for passwords or
         passphrases, but the user wants it in the background.  This
         implies -n.  The recommended way to start X11 programs at a
         remote site is with something like ssh -f host xterm.

         If the ExitOnForwardFailure configuration option is set to “yes”,
         then a client started with -f will wait for all remote port for‐
         wards to be successfully established before placing itself in the
         background.

1
ปัญหาด้วยวิธีนี้คือคำสั่ง SSH ไม่ได้ถูกยกเลิกจริง ๆ มันถูกซ่อนอยู่ในพื้นหลังดังนั้นโฮสต์ที่รันสคริปต์จะมีคำสั่ง SSH จำนวนมากในพื้นหลังที่ไม่กลับมาเพราะคำสั่ง SSH ไม่กลับมา ( เช่นปัญหารากผมหวังที่จะแก้ปัญหา)
rmrobins

-1

ฉันคิดว่าวิธีที่ถูกต้องจะเป็น

ssh user@host exec script.sh &

ไม่นั่นไม่ได้ผลสำหรับฉัน ทำไมจึงเป็นเช่นนั้น?
sleske

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