سؤال كيف أقوم بفصل العملية عن المحطة ، تمامًا؟


أستخدم Tilda (محطة طرفية) على Ubuntu كـ "أمر مركزي" - إلى حد كبير الطريقة التي قد يستخدمها الآخرون جنوم دو أو كويك سيلفر أو كونسيبي.

ومع ذلك ، أنا أعاني من كيفية فصل عملية (مثل Firefox) تمامًا عن المحطة ، تم إطلاقها من - أي تمنع مثل هذه العملية (غير) للأطفال

  • يتم إنهاؤها عند إغلاق المحطة الأصلية
  • "تلوث" محطة المنشأ عبر STDOUT / STDERR

على سبيل المثال ، لبدء برنامج Vim في نافذة طرفية "مناسبة" ، جربت برنامجًا نصيًا بسيطًا كما يلي:

exec gnome-terminal -e "vim $@" &> /dev/null &

ومع ذلك ، ما زال يسبب التلوث (أيضا ، لا يبدو أن تمرير اسم الملف يعمل).


278
2018-03-23 11:59


الأصل


هذا أيضا سؤال جيد. أعتقد أنه من الإنصاف اعتبار لغة Bash لغة برمجة - على الرغم من أن نطاق هذا السؤال هو على الأرجح على جانب مسؤول النظام ...
هذه نسخة مكررة من هذا السؤال stackoverflow.com/questions/285015/... - Dana the Sane
dup من:superuser.com/questions/177218/... - behrooz
حالة استخدامك لا تصف فصل كامل ، في حد ذاته. - jiggunjer


الأجوبة:


في البداية؛ بمجرد بدء عملية ، يمكنك وضعها في الخلفية من خلال إيقافها أولاً (اضغط على السيطرة-Z) ومن ثم الكتابة bg لندعها تستأنف في الخلفية. انها الآن "وظيفة" ، و stdout/stderr/stdin لا تزال متصلة بالطرف الخاص بك.

يمكنك بدء عملية كخلفية على الفور من خلال إلحاق "&" بنهايتها:

firefox &

لتشغيلها في الخلفية تم إسكاتها ، استخدم هذا:

firefox </dev/null &>/dev/null &

بعض المعلومات الإضافية:

nohup هو برنامج يمكنك استخدامه لتشغيل التطبيق الخاص بك مع بحيث يمكن إرسال stdout / stderr إلى ملف بدلاً من ذلك ، مثل إغلاق البرنامج النصي الأصل لن SIGHUP التابع. ومع ذلك ، يجب أن يكون لديك بصيرة لاستخدامه قبل بدء التطبيق. بسبب الطريق nohup يعمل ، لا يمكنك فقط تطبيقه على عملية قيد التشغيل.

disown هو bash builtin يزيل مهمة shell من قائمة مهام shell. ما يعنيه هذا أساسا هو أنه لا يمكنك استخدامه fg، bg على بعد الآن ، ولكن الأهم من ذلك ، عند إغلاق صدفة الخاص بك لن يتعطل أو إرسال SIGHUP لهذا الطفل بعد الآن. مختلف nohup، disown يستخدم بعد تم إطلاق العملية وخلفيتها.

ماذا أنت لا يمكن القيام به ، هو تغيير stdout / stderr / stdin من عملية بعد إطلاقه. على الأقل ليس من القشرة. إذا قمت بتشغيل العملية الخاصة بك وأخبرتها أن stdout هو الطرفية الخاصة بك (وهو ما تفعله افتراضيًا) ، فستتم تهيئة هذه العملية لإخراجها إلى جهازك. ليس لدى shell الخاص بك أي أعمال مع إعداد FD للعمليات ، وهذا شيء محض تديره العملية نفسها. يمكن أن تقرر العملية نفسها ما إذا كان سيتم إغلاق stdout / stderr / stdin أو لا ، ولكن لا يمكنك استخدام shell لإجبارها على القيام بذلك.

لإدارة إخراج عملية الخلفية ، لديك الكثير من الخيارات من البرامج النصية ، "nohup" ربما تكون أول من يتبادر إلى الذهن. لكن بالنسبة للعمليات التفاعلية التي تبدأها ولكنك نسيت أن تسكت (firefox < /dev/null &>/dev/null &) لا يمكنك فعل الكثير ، حقا.

أوصيك بأن تحصل على جنو screen. من خلال الشاشة ، يمكنك إغلاق الصدفة التي تعمل عندها عندما يصبح المخرج عملية يزعج ويفتح واحدة جديدة (^Ac).


أوه ، وبالمناسبة ، لا تستخدم "$@"أين تستخدمه.

$@يعني، $1، $2، $3 ... ، والتي من شأنها تحويل الأمر إلى:

gnome-terminal -e "vim $1" "$2" "$3" ...

هذا على الأرجح ليس ما تريد لأنني لا أفعل واحد جدال. استعمال $1 لإظهار أن البرنامج النصي يمكنه التعامل مع وسيطة واحدة فقط.

من الصعب حقا الحصول على حجج متعددة تعمل بشكل صحيح في السيناريو الذي أعطيته (مع gnome-terminal -e) لان -e يأخذ وسيطة واحدة فقط ، وهي سلسلة أمر shell. سيكون عليك ترميز حججك في واحدة. إن الطريقة الأفضل والأكثر قوة ، ولكن بالأحرى ، هي مثل:

gnome-terminal -e "vim $(printf "%q " "$@")"

313
2018-03-23 13:18



شكرا جزيلا لهذا! للأسف لا أستطيع إلا قبول إجابة واحدة. انتهى بي الأمر مع "nohup $ @ &> / dev / null &" و "alias wvim = 'launch.sh gnome-terminal -x vim'"
ما إجابة مفصّلة وغنية بالمعلومات. +1 - Teekin
@ Hi-Angel عند إغلاق قذيفة bash تفاعلية ، Bash HUPs جميع الوظائف النشطة. عندما تكون ^ Z و bg عملية ما زالت مهمة ، سواء كانت خلفية. لإزالته كوظيفة ، استخدمه disown، ستستمر العملية في العيش بعد إغلاق القوقعة لأن bash لن يكون HUP بعد الآن. - lhunath
لن تستخدم $* بدلا من $@ إصلاح مشكلة السلاسل المنفصلة بالفعل؟ - sjas
ما لا يمكنك فعله هو تغيير stdout / stderr / stdin من العملية بعد إطلاقها. - ليس صحيحًا تمامًا. استعمال reptyr لهذا. - Stefan Seidel


nohup cmd &

nohup يفصل العملية تمامًا (يخترقها)


193
2018-03-23 12:17



على الرغم من أن الإيجاز ذو قيمة ، إلا أن الاكتمال أكثر قيمة. على الرغم من أن nohup هو غنو غنو ، فإن جواب باش فقط (أو ملاحظة حول عدم وجود واحد) سيكون مناسبًا هنا. مع ذلك اجابة جيدة - Limited Atonement
nohup يتجاهل فقط SIGHUP إشارة. ينفذ العملية بشكل طبيعي. لا شيماء. - nemo
nemo مما يعني أن العملية ليست منفصلة ، ولكنها ستصبح منفصلة (وطفل من init) إذا خرجت قذيفة ... أليس كذلك؟ - Noldorin
Noldorin نعم. تجاهل SIGHUP ، التي يتم إرسالها عند انتهاء الصدفة ، سيترك عملية الطفل قيد التشغيل ويتم نقله إلى init. - nemo
nemo nohup أيضا يسكت معيار في / خارج. متابعة مع نزول لفصل تماما. - jiggunjer


إذا كنت تستخدم bash، محاولة disown [jobspec]. نرى باش (1).

طريقة أخرى يمكنك تجربتها هي at now. إذا لم تكن مستخدمًا متميزًا ، فأذن منك باستخدامه at قد تكون مقيدة.


53
2018-03-23 12:05



لا يبدو أن "التبرؤ" هو أمر bash داخلي (غير متوفر على جهازي ، وأستخدم bash). "نوهوب" ، كما اقترح بين ، قد يكون طريقة أفضل (ومعيارية) للقيام بذلك.
لم يفكر في استخدام "في" ، شكرا لهذه الفكرة! - cadrian
at لتفويض الإعدام لشخص آخر ، أحب ذلك! +1 - Ninsuo
كنقطة مرجعية ، وهذا يعمل في zsh كذلك. - Coderer
أيضا، disown لا يبدو أن لها التأثير المطلوب gnome-terminal-disownلا تزال عمليات إد قتل عندما يخرج المحطة. أحب أن أعرف لماذا / كيف. - Kyle Strand


قراءة هذه الإجابات ، كنت تحت الانطباع الأولي أن إصدار nohup <command> & ستكون كافية. تشغيل zsh في gnome-terminal ، لقد وجدت ذلك nohup <command> & لم يمنع صدري من قتل عمليات الطفل عند الخروج. برغم من nohup مفيدًا ، خاصةً مع الأصداف غير التفاعلية ، فإنه يضمن هذا السلوك فقط إذا لم تعيد عملية الطفل معالجه من أجل SIGHUP إشارة.

في حالتي، nohup يجب منع إشارات تعليق المكالمة من الوصول إلى التطبيق ، ولكن تطبيق الطفل (VMWare Player في هذه الحالة) كان يعيد ضبط SIGHUP معالج. ونتيجة لذلك ، عند إنهاء محاكي المحطة الطرفية ، قد يظل بإمكانك قتل العمليات الفرعية الخاصة بك. يمكن حل هذه المشكلة فقط ، على حد علمي ، من خلال التأكد من إزالة العملية من جدول مهام shell. إذا nohup هو تجاوز مع shell مدمج ، كما هو الحال في بعض الأحيان ، وهذا قد يكون كافيا ، ومع ذلك ، في حال لم يكن ...


disown هي قذيفة مدمجة في bash، zshو ksh93،

<command> &
disown

أو

<command> &; disown

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

بعد التبرؤ ، لا تزال هذه العملية تابعة لمحاكي طرفي الخاص بك (اللعب مع pstree إذا كنت ترغب في مشاهدة هذا في العمل) ، ولكن بعد إنهاء محاكي المحطة الطرفية ، يجب أن تراه مرفقًا بعملية init. بعبارة أخرى ، كل شيء كما ينبغي ، وكما يفترض أن تكون.

ما يجب فعله إذا كانت صدقتك لا تدعم disown؟ سأنادي بقوة بالانتقال إلى شخص يفعل ذلك ، ولكن في غياب هذا الخيار ، لديك بعض الخيارات.

  1. screen و tmux يمكن أن تحل هذه المشكلة ، لكنها حلول وزن أثقل بكثير ، وأنا لا أحب تشغيلها لمثل هذه المهمة البسيطة. فهي أكثر ملاءمة للحالات التي تريد فيها الحفاظ على tty ، عادةً على جهاز بعيد.
  2. بالنسبة للعديد من المستخدمين ، قد يكون من المرغوب فيه معرفة ما إذا كانت قوقعتك تدعم إمكانية مثل zsh setopt nohup. يمكن استخدام هذا لتحديد ذلك SIGHUPيجب عدم إرسالها إلى المهام في جدول المهام عند خروج shell. يمكنك إما تطبيق هذا فقط قبل الخروج من shell أو إضافته إلى تهيئة shell مثل ~/.zshrc إذا كنت تريد ذلك دائمًا.
  3. ابحث عن طريقة لتحرير جدول المهام. لم أتمكن من إيجاد طريقة للقيام بذلك tcsh أو csh، وهو أمر مزعج بعض الشيء.
  4. اكتب برنامج C صغير للتفرع و exec(). هذا حل ضعيف للغاية ، لكن المصدر يجب أن يتكون فقط من بضع عشرات من الخطوط. يمكنك تمرير الأوامر كوسيطات سطر الأوامر إلى برنامج C ، وبالتالي تجنب إدخال خاص بعملية في جدول المهام.

36
2018-01-22 17:08





  1. nohup $ COMMAND &

  2. $ COMMAND و تتبرأ

  3. الأمر setid

لقد كنت أستخدم الرقم 2 لفترة طويلة جدًا ، لكن الرقم 3 يعمل أيضًا. أيضًا ، يمكن إلغاء علامة "nohup" من "-h" ، يمكن أن تتبرأ من جميع العمليات باستخدام "-a" ، ويمكنها تبرئة جميع العمليات الجارية باستخدام "-ar".

يتم تحقيق إسكات بواسطة '$ COMMAND &> / dev / null'.

أتمنى أن يساعدك هذا!


24
2017-08-25 14:39





أعتقد أن الشاشة قد تحل مشكلتك


9
2018-03-25 01:51





في tcsh (وربما في قذائف أخرى كذلك) ، يمكنك استخدام الأقواس لفصل العملية.

قارن هذا:

> jobs # shows nothing
> firefox &
> jobs
[1]  + Running                       firefox

الى هذا:

> jobs # shows nothing
> (firefox &)
> jobs # still shows nothing
>

هذا يزيل فايرفوكس من قائمة الوظائف ، لكنه لا يزال مرتبطا إلى المحطة ؛ إذا قمت بتسجيل الدخول إلى هذه العقدة عبر "ssh" ، فستظل محاولة تسجيل الخروج معطلاً لعملية ssh.


8
2018-03-23 14:55