मैं एक नई प्रक्रिया कैसे लॉन्च कर सकता हूं जो मूल प्रक्रिया का बच्चा नहीं है?

(ओएसएक्स 10.7) हमारे द्वारा उपयोग किए जाने वाले एक एप्लिकेशन को एप्लिकेशन के भीतर कुछ गतिविधियां होने पर स्क्रिप्ट को कॉल करने दें। मैंने एक बैश स्क्रिप्ट असाइन की है और इसे कहा जा रहा है, समस्या यह है कि मुझे कुछ कमांड निष्पादित करने की आवश्यकता है, 30 सेकंड प्रतीक्षा करें, और उसके बाद कुछ और आदेश निष्पादित करें। अगर मेरे पास मेरी बैश स्क्रिप्ट खत्म हो गई है तो मेरी स्क्रिप्ट समाप्त होने के दौरान पूरे 30 सेकंड के लिए "एप्लिकेशन 30" पूरा हो जाता है।

I tried putting the 30 second wait (and the second set of commands) into a separate script and calling "./secondScript &" but the application still sits there for 30 seconds doing nothing. I assume the application is waiting for the script and all child processes to terminate.

मैंने दूसरी स्क्रिप्ट को मुख्य लिपि में से कॉल करने के लिए इन बदलावों का प्रयास किया है, उन सभी को एक ही समस्या है:

  • nohup ./secondScript &
  • ( ( ./secondScript & ) & )
  • ( ./secondScript & )
  • nohup script -q /dev/null secondScript &

मेरे पास एप्लिकेशन को बदलने की क्षमता नहीं है और इसे मेरी स्क्रिप्ट लॉन्च करने के लिए कहें और इसे पूरा करने की प्रतीक्षा न करें।

मैं एक प्रक्रिया कैसे लॉन्च कर सकता हूं (मैं एक स्क्रिप्टिंग भाषा में प्रक्रिया को प्राथमिकता दूंगा) जैसे कि नई प्रक्रिया वर्तमान प्रक्रिया का बच्चा नहीं है?

धन्यवाद, क्रिस

अनुलेख मैंने "अस्वीकार" आदेश की कोशिश की और इससे कोई मदद नहीं मिली। मेरी मुख्य लिपि इस तरह दिखती है:

[initial commands]
echo Launching second script
./secondScript &
echo Looking for jobs
jobs
echo Sleeping for 1 second
sleep 1
echo Calling disown
disown
echo Looking again for jobs
jobs
echo Main script complete

और मुझे आउटपुट के लिए क्या मिलता है यह है:

Launching second script
Looking for jobs
[1]+ Running ./secondScript &
Sleeping for 1 second
Calling disown
Looking again for jobs
Main script complete

और इस बिंदु पर कॉलिंग एप्लिकेशन 45 सेकंड के लिए बैठता है, दूसरी स्क्रिप्ट खत्म होने की प्रतीक्षा करता है।

p.p.s

यदि, मुख्य स्क्रिप्ट के शीर्ष पर, मैं "ps" निष्पादित करता हूं, यह केवल एक चीज है जो इंटरैक्टिव बैश सत्र की प्रक्रिया आईडी है, मैंने एक अलग टर्मिनल विंडो में खुल दिया है।

$ SHELL का मान/बिन/बैश है

अगर मैं "ps -p $$" निष्पादित करता हूं तो यह सही ढंग से मुझे बताता है

PID   TTY TIME    CMD
26884 ??  0:00.00 mainScript

अगर मैं "lsof -p $$" निष्पादित करता हूं तो यह मुझे सभी प्रकार के परिणाम देता है (मैंने यह मानते हुए सभी कॉलम पेस्ट नहीं किया है कि वे प्रासंगिक नहीं हैं):

FD   TYPE   NAME
cwd  DIR    /private/tmp/blahblahblah
txt  REG    /bin/bash
txt  REG    /usr/lib/dyld
txt  REG    /private/var/db/dyld/dyld_shared_cache_x86_64
0    PIPE   
1    PIPE   -> 0xffff8041ea2d10
2    PIPE   -> 0xffff 8017d21cb
3r   DIR    /private/tmp/blahblah
4r   REG    /Volumes/DATA/blahblah
255r REG    /Volumes/DATA/blahblah
0
मुख्य स्क्रिप्ट को अनामित एप्लिकेशन (सीवीएस) से लॉन्च किया जा रहा है। आप सीवीएस को बता सकते हैं "जब कोई उपयोगकर्ता फाइल करता है तो मेरी स्क्रिप्ट लॉन्च करें"।
जोड़ा लेखक Betty Crokker, स्रोत
मुझे लगता है कि सीवीएस सिर्फ एक सिस्टम कर रहा है ("/ bin/bash mainScript.sh"), सीवीएस क्या "खोल कर्तव्यों" को संभालने में सक्षम होगा?
जोड़ा लेखक Betty Crokker, स्रोत
मुख्य स्क्रिप्ट का अभिभावक क्या है?
जोड़ा लेखक thom, स्रोत
उस स्थिति में, आपकी स्क्रिप्ट सीधे बैश खोल पर नहीं चल रही है और एप्लिकेशन शैल कर्तव्यों का पालन कर रहा है, जो बहुत कुछ बताता है। आपको आवेदन की प्रक्रिया के बाहर धीमी प्रक्रिया शुरू करने का सहारा लेना होगा।
जोड़ा लेखक thom, स्रोत
यदि सीवीएस बस कर रहा है (/ bin/bash mainScript) तो आप pstree -p में लॉन्च बैश खोल को मुख्य स्क्रिप्ट और सीवीएस के अभिभावक के रूप में उस बैश खोल के माता-पिता के रूप में देखेंगे। यदि सीवीएस सीधे मुख्य स्क्रिप्ट का अभिभावक है, तो इसमें कोई भी बैश खोल शामिल नहीं है। सीवीएस क्या करेगा हर सिस्टम कॉल को रोकने के लिए एक बहुत ही स्पष्ट तरीके से 'नकल'।
जोड़ा लेखक thom, स्रोत

5 उत्तर

यहाँ मेरे पास एक खोल है

└─bash(13882)

जहां मैं इस तरह की प्रक्रिया शुरू करता हूं:

$ (urxvt -e ssh somehost&)

मुझे एक प्रक्रिया पेड़ मिलता है (यह आउटपुट pstree -p से छीन लिया गया है):

├─urxvt(14181)───ssh(14182)

जहां प्रक्रिया को पिड 1 के नीचे parented (मेरे कोड में systemd ) है।

However, had I instead done this (note where the & is) :

$ (urxvt -e ssh somehost)&

तो प्रक्रिया खोल का एक बच्चा होगा:

└─bash(13882)───urxvt(14181)───ssh(14182)

दोनों मामलों में शेल प्रॉम्प्ट तुरंत लौटा दिया जाता है और मैं exit कर सकता हूं मैंने जिस प्रक्रिया पेड़ को ऊपर शुरू किया था उसे समाप्त किए बिना।

बाद के मामले के लिए प्रक्रिया पेड़ को 1 के दौरान रीडेंस किया जाता है खोल निकलता है, इसलिए यह पहले उदाहरण के समान होता है।

├─urxvt(14181)───ssh(14182)

किसी भी तरह से, परिणाम एक प्रक्रिया पेड़ है जो खोल को आगे बढ़ाता है। केवल उस प्रक्रिया पेड़ की प्रारंभिक parenting ही अंतर है।

संदर्भ के लिए, आप भी उपयोग कर सकते हैं

  • nohup urxvt -e ssh somehost &
  • urxvt -e ssh somehost & disown $!

दोनों एक ही प्रक्रिया पेड़ उपरोक्त दूसरे उदाहरण के रूप में देते हैं।

└─bash(13882)───urxvt(14181)───ssh(14182)

जब खोल समाप्त हो जाता है तो प्रक्रिया पेड़, पहले की तरह, reparented है 1 को पिड करने के लिए।

nohup additionally redirects the process' standard output to a file nohup.out so, if that is a useful trait, it may be a more useful choice.

अन्यथा, ऊपर के पहले फॉर्म के साथ, आप तुरंत पूरी तरह से है अलग प्रक्रिया पेड़।

0
जोड़ा

यूनिक्स में ऐसा करने का सामान्य तरीका डबल फोर्क है। बाश में, आप इसे कर सकते हैं

( sleep 30 & )

(..) creates a child process, and & creates a grandchild process. When the child process dies, the grandchild process is inherited by init.


यदि यह काम नहीं करता है, तो आपका आवेदन बाल प्रक्रियाओं की प्रतीक्षा नहीं कर रहा है।

सत्र और ओपन लॉक फाइलों को शामिल करने के लिए अन्य चीजें जो प्रतीक्षा कर रही हैं:

नया सत्र बनाने के लिए, लिनक्स में setid है। ओएस एक्स पर, आप इसे script के माध्यम से करने में सक्षम हो सकते हैं, जो संयोग से एक नया सत्र भी बनाता है:

# Linux:
setsid sleep 30

# OS X:
nohup script -q -c 'sleep 30' /dev/null &

विरासत फ़ाइल वर्णनकर्ताओं की एक सूची खोजने के लिए, आप lsof -p yourpid का उपयोग कर सकते हैं, जो कुछ इस तरह आउटपुट करेगा:

sleep   22479 user    0u   CHR 136,32      0t0       35 /dev/pts/32
sleep   22479 user    1u   CHR 136,32      0t0       35 /dev/pts/32
sleep   22479 user    2u   CHR 136,32      0t0       35 /dev/pts/32
sleep   22479 user    5w   REG  252,0        0  1048806 /tmp/lockfile

इस मामले में, मानक एफडी 0, 1 और 2 के अतिरिक्त, आपके पास एक लॉक फ़ाइल के साथ एक एफडी 5 भी खुला है जिसके लिए माता-पिता प्रतीक्षा कर सकते हैं।

To close fd 5, you can use exec 5>&-. If you think the lock file might be stdin/stdout/stderr themselves, you can use nohup to redirect them to something else.

0
जोड़ा
क्षमा करें, मेरा अपडेट और आपकी प्रतिक्रिया पथ पार हो गई ... मैंने लाइन ((स्क्रिप्ट और) और) जोड़ने का प्रयास किया और इसका एक ही परिणाम था।
जोड़ा लेखक Betty Crokker, स्रोत

मुझे लगता है कि यह इस बात पर निर्भर करता है कि आपकी मूल प्रक्रिया कैसे समाप्त हो जाती है, यह पता लगाने की कोशिश करता है कि आपकी बाल प्रक्रिया पूरी हो गई है या नहीं। मेरे मामले में (मेरी मूल प्रक्रिया gnu मेक थी), मैं stdout और stderr को बंद करके सफल होता हूं (थोड़ा उस अन्य व्यक्ति का उत्तर ) इस तरह:

sleep 30 >&- 2>&- &

आप stdin भी बंद कर सकते हैं

sleep 30 <&- >&- 2>&- &

या अतिरिक्त रूप से अपने बच्चे की प्रक्रिया को अस्वीकार कर दिया (मैक के लिए नहीं)

sleep 30 <&- >&- 2>&- & disown

वर्तमान में केवल कुबंटू 14.04 और मैक ओएसएक्स पर बैश में परीक्षण किया गया।

यह एकमात्र ऐसा है जो मेरे लिए काम करता है। धन्यवाद!
जोड़ा लेखक caleb, स्रोत

एक और तरीका बच्चे को त्यागना है

#!/bin/bash

yourprocess &

disown

जहां तक ​​मैं समझता हूं, एप्लिकेशन सामान्य बैश खोल को प्रतिस्थापित करता है क्योंकि यह अभी भी प्रक्रिया समाप्त होने का इंतजार कर रहा है भले ही init को इस बच्चे की प्रक्रिया का ख्याल रखना चाहिए। यह हो सकता है कि " एप्लिकेशन " अनाथ हैंडलिंग को रोकता है जो आमतौर पर init द्वारा किया जाता है।

उस स्थिति में, कुछ आईपीसी के साथ केवल समानांतर प्रक्रिया समाधान प्रदान कर सकती है (मेरा दूसरा जवाब देखें)

0
जोड़ा
हां, ओएसएक्स में "अस्वीकार" आदेश नहीं है। [क्षमा करें, मेरा बुरा, अस्वीकार एक बैश कमांड है और इसके लिए कोई मैन पेज नहीं है। लेकिन मैं अभी तक इसे काम करने में सक्षम नहीं हूं क्योंकि मुझे इसके लिए दस्तावेज़ीकरण नहीं मिल रहा है]
जोड़ा लेखक Betty Crokker, स्रोत
अच्छा है धन्यवाद! तो अगली समस्या ... मुझे लगता है कि कांटा का जवाब ज्यादातर छद्म कोड है, मैं वास्तव में किसी भी विकल्प के बिना अस्वीकार नहीं कर सकता। ऐसा लगता है कि मुझे इसे नौकरी आईडी पास करने की ज़रूरत है, और मैं यह पता लगाने के लिए वेब खोज रहा हूं कि मुझे नौकरी आईडी कैसे मिलती है ...
जोड़ा लेखक Betty Crokker, स्रोत
जब मैं कहता हूं, "मैं वास्तव में किसी भी विकल्प के बिना अस्वीकार नहीं कर सकता" मेरा मतलब क्या है "जब मैं बिना किसी विकल्प के अस्वीकार करता हूं तो यह मुझे एक त्रुटि संदेश देता है" अस्वीकार: वर्तमान: ऐसी कोई नौकरी नहीं "
जोड़ा लेखक Betty Crokker, स्रोत
कुछ और अजीब: "नौकरियां" कमांड मुझे कभी भी कोई परिणाम नहीं देता है
जोड़ा लेखक Betty Crokker, स्रोत
मेरा बुरा, मैं अभी भी फोन कर रहा था "((द्वितीयस्क्रिप्ट और))", जब मैंने बस "दूसरी स्क्रिप्ट" कॉल करना शुरू किया और अस्वीकार आदेश काम करना शुरू कर दिया। मैंने अपने शुरुआती प्रश्न में जोड़ा (क्योंकि स्वरूपण में टिप्पणियों की तुलना में बेहतर है)
जोड़ा लेखक Betty Crokker, स्रोत
@BettyCrokker: info bash और "अस्वीकार" की खोज करें, या यहां
जोड़ा लेखक Keith Thompson, स्रोत
नहीं, यह छद्म कोड नहीं है। आपको नौकरी आईडी की आवश्यकता नहीं है। अस्वीकार बस अपने सभी बच्चों को स्थानीय प्रोसेस्टेबल से मिटा देता है। आपको अपनी प्रक्रिया के नाम से yourprocess को प्रतिस्थापित करना होगा।
जोड़ा लेखक thom, स्रोत
तो आप शायद एक बैश खोल में नहीं हैं, लेकिन आपकी स्क्रिप्ट शायद एक अल्मक्विस्ट खोल या कुछ कस्टम में एप्लिकेशन द्वारा सोर्स की जा रही है। यदि आप अपनी स्क्रिप्ट से /bin/bash -c "yourscript.sh" के साथ एक नया खोल शुरू करते हैं और बाकी में "yourscript.sh"
जोड़ा लेखक thom, स्रोत
यदि आप स्क्रिप्ट चला रहे हैं, तो भी pstree -p पर बारीकी से देखें। जांचें कि bash शब्द एप्लिकेशन के बच्चे के रूप में दिखाई देता है या नहीं।
जोड़ा लेखक thom, स्रोत

यदि सभी अन्य विफल होते हैं:

  1. नामित पाइप बनाएं

  2. " एप्लिकेशन " से "धीमी" स्क्रिप्ट स्वतंत्र प्रारंभ करें, सुनिश्चित करें कि पाइप से पढ़ने के साथ, यह एक अंतहीन पाश में अपना कार्य निष्पादित करता है। जब यह पढ़ने की कोशिश करता है तो यह रीड-अवरुद्ध हो जाएगा ..

  3. एप्लिकेशन से, अपनी दूसरी स्क्रिप्ट शुरू करें। जब इसे "धीमी" स्क्रिप्ट का आह्वान करने की आवश्यकता होती है, तो बस कुछ डेटा पाइप पर लिखें। धीमी स्क्रिप्ट स्वतंत्र रूप से शुरू हो जाएगी, इसलिए आपकी स्क्रिप्ट "धीमी" स्क्रिप्ट को समाप्त करने की प्रतीक्षा नहीं करेगी।

So, to answer the question:
bash - how can I launch a new process that is NOT a child of the original process?

Simple: don't launch it but let an independent entity launch it during boot...like init or on the fly with the command at or batch

0
जोड़ा