กระบวนการ java ยังคงถูกฆ่า


11

ฉันต้องเรียกใช้โปรแกรมจาวาบนเซิร์ฟเวอร์มหาวิทยาลัยของฉัน ฉันลงชื่อเข้าใช้ผ่านเซิร์ฟเวอร์จากระยะไกลผ่าน ssh

ดังนั้นฉันจึงใช้ nohup อย่างนั้น:

nohup java -jar project.jar &

อย่างไรก็ตามเมื่อฉันออกจากระบบและปิดเทอร์มินัลจากนั้นกลับเข้าสู่เซิร์ฟเวอร์กระบวนการของฉันหายไป / ถูกปิด


ลองเปลี่ยนเส้นทางstdoutและstderrบางไฟล์ - ขั้นตอนของคุณอาจจะถูกฆ่าโดยสัญญาณอื่น ๆ กว่า SIGHUP เมื่อพยายามที่จะเขียนไปยังสถานีปิด/stdout stderrเช่นเพิ่ม>/dev/null 2>&1คำสั่งของคุณก่อนที่จะ&ลงนามในงาน
Boris Burkov

1
@Bob ไม่ควรจะเป็นสิ่งที่จำเป็นกับnohup- การใช้งานส่วนใหญ่จะทำเช่นนี้โดยเริ่มต้นถึงแม้ว่ามันอาจจะจำเป็นต้องเปลี่ยนเส้นทางเช่นstdin </dev/null
แกรม

คำตอบ:


14

nohupทำให้โปรแกรมมีภูมิคุ้มกันSIGHUPและSIGQUITส่งสัญญาณเท่านั้น เปลือกโมเดิร์นอาจจะส่งสัญญาณอื่น ๆ nohupเมื่อคุณออกจากระบบจากการใช้งานของคุณจึงมีการรับประกันว่าโปรแกรมที่คุณไม่ได้ถูกฆ่าตายไม่มีแม้ทำงานภายใต้

ทางออกที่ดีกว่าคือการใช้tmuxหรือscreenหรือถ้าคุณใช้bashคุณสามารถลอง:

$ java -jar project.jar &
$ disown

หากคุณใช้disownคุณต้องเปลี่ยนเส้นทางด้วยตนเองเช่นเพิ่ม</dev/null &>/dev/null
แกรม

@ Graeme: ฉันคิดว่าถ้าเราไม่ทำงานกับเชลล์อีกต่อไป (แค่เรียกใช้คำสั่งและออก) ก็ไม่จำเป็นต้องเปลี่ยนเส้นทาง
cuonglm

ลองssh localhost 'sleep 10m & disown'ดู bashจะไม่ออก
แกรม

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

ลินุกซ์ (GNU coreutils และ busybox) และ BSD การใช้งานnohupไม่ได้ทำให้ภูมิคุ้มกันคำสั่งแต่เพียงเพื่อSIGQUIT SIGHUPซึ่งจะขัดแย้งกับมาตรฐานอย่างชัดเจนและ AFAIK อาจเกิดขึ้นได้ใน Solaris (บางรุ่น)
mosvy

13

อีกตัวเลือกหนึ่งแทนที่ (ผิดปกติเรื้อรัง) nohup:

setsid java -jar project.jar </dev/zero &>/dev/null &

สิ่งนี้ได้อย่างมีประสิทธิภาพ "daemonizes" กระบวนการ ตอนนี้มันเป็นเจ้าของโดย init ดังนั้นจะไม่ได้รับ HUP'd สตรีม I / O ของมันปลอดภัยและถูกแยกเป็นพื้นหลัง

ดูman setsidข้อมูลเพิ่มเติม ไม่เหมือนscreenหรือtmuxนี่ไม่ใช่โปรแกรมที่อ้างสิทธิ์ความเป็นเจ้าของและยังคงทำงานต่อไป มันก็จะเริ่มโปรแกรมในตัวของมันเองกลุ่มกระบวนการ


ทำไม nohup ผิดปกติ?
cpugeniusmv

@cpugeniusmv ฉันแน่ใจว่ามันดีสำหรับบางสิ่งบางอย่าง แต่ฉันไม่พบว่ามันน่าเชื่อถือสำหรับวัตถุประสงค์ที่มักจะแนะนำให้เข้าสู่ระบบในบางแห่งเริ่มต้นกระบวนการและออกจากระบบ (เหมือน OP) ฉันคิดว่ามันน่าจะผิดและบางทีอาจsetsidเป็นหลักฐานที่งี่เง่ามากกว่านี้ มันข้ามขั้นตอนโดยนัยโดย nohup (มีกระบวนการ parented อีกครั้งโดย init เป็นเด็กกำพร้า) nohupจะมีความยืดหยุ่นมากขึ้นหากคุณต้องการทำงานเบื้องหน้าในภายหลัง
goldilocks

@ TAFKA'goldilocks 'ฉันคิดว่าปัญหาคือการจัดการ stdin, stdout และ stderr ซึ่งไม่ได้จริงๆ (แต่บางส่วน (!)) จัดการโดย nohup Nohup ทำหน้าที่หลักได้ค่อนข้างดีป้องกันกระบวนการจาก SIGHUP แต่มีหลายสิ่งหลายอย่างที่ผิดไปได้กับกระแสข้อมูล - หรือแย่กว่านั้นคือบางครั้งก็ผิดพลาดขึ้นอยู่กับขนาดบัฟเฟอร์ ฉันจะบอกว่าไม่นะไม่ใช่คนผิด แต่ความคาดหวังว่าคนอื่นทำอะไร
Volker Siegel

3

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

บทช่วยสอน: http://www.rackaid.com/blog/linux-screen-tutorial-and-how-to/


-2

ลองเรียกใช้ nohup ของคุณด้วย STDOUT และ STDERR เปลี่ยนเส้นทางเป็น null:

nohup java -jar project.jar 2>&1 &

1
คุณเปลี่ยนเส้นทาง stderr ไปยัง stdout เท่านั้นซึ่งจะไม่เปลี่ยนแปลงอะไรเลยเกี่ยวกับการทำงานของ nohup (เปลี่ยนเส้นทางทั้งสองไปยังnohup.out)
Gilles 'หยุดความชั่วร้าย'

1
-1 ฉันคิดว่าคุณหมายถึงnohup java -jar project.jar 2>/dev/null &แต่คุณไม่รู้ว่าคุณกำลังทำอะไรอยู่ stdin /dev/nullยิ่งไปกว่านั้นยังมีอาหาร
PlasmaPower

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