كيف أضع عملية قيد التشغيل بالفعل ضمن nohup؟

StackOverflow https://stackoverflow.com/questions/625409

  •  05-07-2019
  •  | 
  •  

سؤال

لدي عملية قيد التشغيل بالفعل لفترة طويلة ولا أريد إنهاءها.

كيف أضعه تحت nohup (أي كيف أجعله يستمر في العمل حتى لو قمت بإغلاق الجهاز؟)

هل كانت مفيدة؟

المحلول

باستخدام التحكم الوظيفي من bash لإرسال العملية إلى الخلفية:

  1. كنترول+ز لإيقاف (إيقاف مؤقت) البرنامج والعودة إلى الصدفة.
  2. bg لتشغيله في الخلفية.
  3. disown -h [job-spec] حيث [job-spec] هو رقم الوظيفة (مثل %1 لأول مهمة جارية؛تعرف على رقمك مع jobs الأمر) حتى لا يتم إنهاء المهمة عند إغلاق المحطة.

نصائح أخرى

وافترض لسبب السيطرة + Z هو أيضا لا يعمل، انتقل إلى محطة أخرى، والعثور على معرف العملية (باستخدام ps) وتشغيل:

kill -SIGSTOP PID 
kill -SIGCONT PID

وSIGSTOP ستعلق عملية وسوف SIGCONT استئناف العملية، في الخلفية. وحتى الآن، وإغلاق كل من المحطات لن تتوقف العملية الخاصة بك.

والأمر لفصل وظيفة يمتد من قذيفة (= يجعل من nohup) هو disown وقذيفة الأوامر الأساسية.

ومن باش-manpage (رجل باش):

<اقتباس فقرة>   

والتبرؤ [-ar] [ح] [jobspec ...]

     

ودون خيارات، تتم إزالة كل jobspec من جدول المهام النشطة. إذا أعطيت الخيار -h، كل jobspec ليس   إزالتها من الجدول، ولكن وضعت بحيث لا يتم إرسال تلك SIGHUP لهذه المهمة إذا تلقى قذيفة SIGHUP. إذا لم يكن هناك jobspec هو   الحاضر، فلن يتحمل -a ولا يتم توفير الخيار -r، يتم استخدام وظيفتك الحالية. إذا تم توفير أي jobspec، الخيار -a   الوسائل لإزالة أو علامة كافة الوظائف. الخيار -r دون حجة jobspec يقيد عملية لتشغيل وظيفة. العودة   القيمة 0 ما لم jobspec لا يحدد وظيفة سارية المفعول.

وهذا يعني، أن بسيطة

disown -a

وسيتم إزالة جميع الوظائف من جدول العمل وتجعلها nohup

وهذه هي أجوبة جيدة أعلاه، أنا فقط أريد أن أضيف توضيحا:

وأنت لا يمكن disown على معرف المنتج أو العملية، يمكنك disown على وظيفة، وهذا تمييز مهم.

وألف وظيفة هو الشيء الذي هو فكرة العملية التي يتم تركيبها على قذيفة، لذلك عليك ان تقذف هذه المهمة في الخلفية (لا تعليق عليه) ثم يتبرأ منه.

العدد:

%  jobs
[1]  running java 
[2]  suspended vi
%  disown %1

http://www.quantprinciple.com/ استثمار / index.php / مستندات / tipsandtricks / يونيكس / jobcontrol / لمناقشة أكثر تفصيلا ليونكس تحكم العمل.

ومما يؤسف له disown غير محددة لسحق وغير متوفرة في جميع القذائف.

وبعض النكهات يونيكس (مثل AIX، وسولاريس) لديك خيار في الأمر nohup نفسها التي يمكن تطبيقها على عملية تشغيل:

nohup -p pid

http://en.wikipedia.org/wiki/Nohup

إن إجابة Node رائعة حقًا، لكنها تركت السؤال مفتوحًا حول كيفية إعادة توجيه stdout وstderr.لقد وجدت حلا على يونيكس ولينكس, ، ولكنها ليست كاملة أيضًا.أود دمج هذين الحلين.ها هو:

بالنسبة للاختبار، قمت بإنشاء نص باش صغير يسمى حلقة.sh، والذي يطبع معرف الهوية (pid) نفسه مع دقيقة نوم في حلقة لا نهائية.

$./loop.sh

الآن احصل على PID لهذه العملية بطريقة أو بأخرى.عادة ps -C loop.sh هو جيد بما فيه الكفاية، ولكن يتم طباعته في حالتي.

يمكننا الآن التبديل إلى محطة أخرى (أو اضغط على ^Z وفي نفس المحطة).الآن gdb ينبغي أن تعلق على هذه العملية.

$ gdb -p <PID>

يؤدي هذا إلى إيقاف البرنامج النصي (إذا كان قيد التشغيل).يمكن التحقق من حالتها عن طريق ps -f <PID>, ، أين ال STAT الحقل هو 'T+' (أو في حالة ^Z 'T')، وهو ما يعني (man ps(1))

    T Stopped, either by a job control signal or because it is being traced
    + is in the foreground process group

(gdb) call close(1)
$1 = 0

Close(1) يُرجع صفرًا عند النجاح.

(gdb) call open("loop.out", 01102, 0600)
$6 = 1

يقوم Open(1) بإرجاع واصف الملف الجديد في حالة نجاحه.

هذا مفتوح يساوي open(path, O_TRUNC|O_CREAT|O_RDWR, S_IRUSR|S_IWUSR).بدلاً من O_RDWR O_WRONLY يمكن تطبيقها، ولكن /usr/sbin/lsof يقول "u" لجميع معالجات الملفات std* (FD العمود)، وهو O_RDWR.

لقد قمت بفحص القيم الموجودة في ملف الرأس /usr/include/bits/fcntl.h.

يمكن فتح ملف الإخراج مع O_APPEND, ، مثل nohup ستفعل، ولكن لم يتم اقتراح هذا من قبل man open(2), ، بسبب مشاكل NFS المحتملة.

إذا حصلنا على -1 كقيمة إرجاع، إذن call perror("") يطبع رسالة الخطأ.إذا كنا في حاجة إلى errno، استخدم p errno أمر gdb.

الآن يمكننا التحقق من الملف المعاد توجيهه حديثًا. /usr/sbin/lsof -p <PID> مطبوعات:

loop.sh <PID> truey    1u   REG   0,26        0 15008411 /home/truey/loop.out

إذا أردنا، يمكننا إعادة توجيه stderr إلى ملف آخر، إذا أردنا استخدامه call close(2) و call open(...) مرة أخرى باستخدام اسم ملف مختلف.

الآن المرفقة bash يجب أن يتم إطلاق سراحنا ويمكننا الاستقالة gdb:

(gdb) detach
Detaching from program: /bin/bash, process <PID>
(gdb) q

إذا تم إيقاف البرنامج النصي gdb من محطة أخرى يستمر تشغيله.يمكننا العودة مرة أخرى إلى محطة Loop.sh.الآن لا يكتب أي شيء على الشاشة، ولكن يعمل ويكتب في الملف.علينا أن نضعه في الخلفية.لذا اضغط ^Z.

^Z
[1]+  Stopped                 ./loop.sh

(الآن نحن في نفس الحالة كما لو ^Z تم الضغط عليه في البداية.)

الآن يمكننا التحقق من حالة المهمة:

$ ps -f 24522
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
<UID>    <PID><PPID>  0 11:16 pts/36   S      0:00 /bin/bash ./loop.sh
$ jobs
[1]+  Stopped                 ./loop.sh

لذلك يجب أن يتم تشغيل العملية في الخلفية وفصلها عن الجهاز.الرقم في jobs يحدد إخراج الأمر بين قوسين مربعين المهمة الموجودة بداخله bash.يمكننا استخدامها في ما يلي المدمج في bash الأوامر التي تضع علامة '%' قبل رقم الوظيفة:

$ bg %1
[1]+ ./loop.sh &
$ disown -h %1
$ ps -f <PID>
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
<UID>    <PID><PPID>  0 11:16 pts/36   S      0:00 /bin/bash ./loop.sh

والآن يمكننا التوقف عن الاتصال باش.تستمر العملية في الخلفية.إذا قمنا بإنهاء PPID الخاص به يصبح 1 (عملية init(1)) وتصبح محطة التحكم غير معروفة.

$ ps -f <PID>
UID        PID  PPID  C STIME TTY      STAT   TIME CMD
<UID>    <PID>     1  0 11:16 ?        S      0:00 /bin/bash ./loop.sh
$ /usr/bin/lsof -p <PID>
...
loop.sh <PID> truey    0u   CHR 136,36                38 /dev/pts/36 (deleted)
loop.sh <PID> truey    1u   REG   0,26     1127 15008411 /home/truey/loop.out
loop.sh <PID> truey    2u   CHR 136,36                38 /dev/pts/36 (deleted)

تعليق

يمكن أتمتة عناصر gdb من خلال إنشاء ملف (على سبيل المثال.Loop.gdb) الذي يحتوي على الأوامر والتشغيل gdb -q -x loop.gdb -p <PID>.يبدو ملف Loop.gdb الخاص بي كما يلي:

call close(1)
call open("loop.out", 01102, 0600)
# call close(2)
# call open("loop.err", 01102, 0600)
detach
quit

أو يمكن للمرء استخدام الخطوط الملاحية المنتظمة التالية بدلاً من ذلك:

gdb -q -ex 'call close(1)' -ex 'call open("loop.out", 01102, 0600)' -ex detach -ex quit -p <PID>

آمل أن يكون هذا وصفًا كاملاً إلى حد ما للحل.

لإرسال عملية التشغيل إلى nohup (http://en.wikipedia.org/wiki/Nohup)

nohup -p pid ، لم ينجح الأمر بالنسبة لي

ثم جربت الأوامر التالية وكانت جيدة جدًا

  1. قم بتشغيل بعض أوامر SOMECOMMAND ، قال /usr/bin/python /vol/scripts/python_scripts/retention_all_properties.py 1.

  2. كنترول+ز لإيقاف (إيقاف مؤقت) البرنامج والعودة إلى الصدفة.

  3. bg لتشغيله في الخلفية.

  4. disown -h حتى لا يتم قتل العملية عند إغلاق المحطة.

  5. يكتب exit للخروج من الصدفة لأنه من الجيد الآن المضي قدمًا حيث سيتم تشغيل العملية في الخلفية في عمليتها الخاصة، لذا فهي غير مرتبطة بالصدفة.

هذه العملية تعادل التشغيل nohup SOMECOMMAND.

في نظام AIX بلدي، وأنا حاولت

nohup -p  processid>

وهذا يعمل بشكل جيد. واصلت لتشغيل عملية بلدي حتى بعد إغلاق نوافذ المحطة. لقد KSH كما قذيفة الافتراضي حتى bg وdisown الأوامر لم تنجح.

  1. كنترول + ض - سيؤدي هذا إلى إيقاف المهمة مؤقتًا (لن يتم إلغاؤها!)
  2. bg - سيؤدي هذا إلى وضع المهمة في الخلفية والعودة إلى عملية التشغيل
  3. disown -a - سيؤدي هذا إلى قطع جميع المرفقات مع المهمة (حتى تتمكن من إغلاق الجهاز وسيظل قيد التشغيل)

ستسمح لك هذه الخطوات البسيطة بإغلاق الجهاز مع استمرار العملية.

لن يتم ارتداؤه nohup (بناءً على فهمي لسؤالك، فأنت لست بحاجة إليه هنا).

لقد نجح هذا بالنسبة لي على Ubuntu linux أثناء وجودي في tcshell.

  1. كنترولز لإيقافه مؤقتًا

  2. bg للتشغيل في الخلفية

  3. jobs للحصول على رقم وظيفتها

  4. nohup %n حيث n هو رقم الوظيفة

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top