كيف أضع عملية قيد التشغيل بالفعل ضمن nohup؟
سؤال
لدي عملية قيد التشغيل بالفعل لفترة طويلة ولا أريد إنهاءها.
كيف أضعه تحت nohup (أي كيف أجعله يستمر في العمل حتى لو قمت بإغلاق الجهاز؟)
المحلول
باستخدام التحكم الوظيفي من bash لإرسال العملية إلى الخلفية:
- كنترول+ز لإيقاف (إيقاف مؤقت) البرنامج والعودة إلى الصدفة.
bg
لتشغيله في الخلفية.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
إن إجابة 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
، لم ينجح الأمر بالنسبة لي
ثم جربت الأوامر التالية وكانت جيدة جدًا
قم بتشغيل بعض أوامر SOMECOMMAND ، قال
/usr/bin/python /vol/scripts/python_scripts/retention_all_properties.py 1
.كنترول+ز لإيقاف (إيقاف مؤقت) البرنامج والعودة إلى الصدفة.
bg
لتشغيله في الخلفية.disown -h
حتى لا يتم قتل العملية عند إغلاق المحطة.يكتب
exit
للخروج من الصدفة لأنه من الجيد الآن المضي قدمًا حيث سيتم تشغيل العملية في الخلفية في عمليتها الخاصة، لذا فهي غير مرتبطة بالصدفة.
هذه العملية تعادل التشغيل nohup SOMECOMMAND
.
في نظام AIX بلدي، وأنا حاولت
nohup -p processid>
وهذا يعمل بشكل جيد. واصلت لتشغيل عملية بلدي حتى بعد إغلاق نوافذ المحطة. لقد KSH كما قذيفة الافتراضي حتى bg
وdisown
الأوامر لم تنجح.
- كنترول + ض - سيؤدي هذا إلى إيقاف المهمة مؤقتًا (لن يتم إلغاؤها!)
bg
- سيؤدي هذا إلى وضع المهمة في الخلفية والعودة إلى عملية التشغيلdisown -a
- سيؤدي هذا إلى قطع جميع المرفقات مع المهمة (حتى تتمكن من إغلاق الجهاز وسيظل قيد التشغيل)
ستسمح لك هذه الخطوات البسيطة بإغلاق الجهاز مع استمرار العملية.
لن يتم ارتداؤه nohup
(بناءً على فهمي لسؤالك، فأنت لست بحاجة إليه هنا).
لقد نجح هذا بالنسبة لي على Ubuntu linux أثناء وجودي في tcshell.
كنترولز لإيقافه مؤقتًا
bg
للتشغيل في الخلفيةjobs
للحصول على رقم وظيفتهاnohup %n
حيث n هو رقم الوظيفة