बैश स्क्रिप्ट चलाने के बाद बाहर निकलें टर्मिनल


18

मैं कमांड bashका उपयोग करके कुछ फाइलें (ज्यादातर पीडीएफ फाइलें) खोलने के लिए एक स्क्रिप्ट लिखने की कोशिश कर रहा हूं gnome-open। मैं यह भी चाहता हूं कि पीडीएफ फाइल खुलते ही टर्मिनल बाहर निकल जाए।

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

मुझे एक उत्तर की आवश्यकता है जो केवल उस टर्मिनल को मारता है जिससे मैं कमांड चलाता हूं सभी टर्मिनल नहीं यह संभव होगा? पिछला उत्तर जो मैंने स्वीकार किया है वह खुली हुई सभी टर्मिनल खिड़कियों को मारता है। मुझे आज तक ऐसा महसूस नहीं हुआ था।


क्या आप पहली बार टर्मिनल में स्क्रिप्ट चला रहे हैं? कमांड लाइन से सख्ती से, ऐसा करने के लिए टर्मिनल खोलने का कोई कारण नहीं है।
याकूब Vlijm

हां मैं टर्मिनल से स्क्रिप्ट चलाता हूं। मुझे नहीं पता था कि टर्मिनल और कमांड लाइन के बीच अंतर था
रमेश

मैं प्रतिस्थापित gnome-openसाथ xdg-openमेरी स्क्रिप्ट में लेकिन कोई बदलाव नहीं आया है। टर्मिनल अभी भी खुला है
रमेश

@ टिम वाह, यह काम करता है =) +1
एबी

@ टिम लेकिन मेरा समाधान भी बुरा नहीं था। ;)
एबी

जवाबों:


12

यदि आप केवल एक फ़ाइल खोल रहे हैं, तो आपको वास्तव में एक स्क्रिप्ट का उपयोग करने की आवश्यकता नहीं है , क्योंकि एक स्क्रिप्ट का मतलब एक पंक्ति में कई कमांड चलाने का एक आसान तरीका है, जबकि यहां आपको केवल दो कमांड चलाने की आवश्यकता है (सहित exit) ।

यदि आप exitएक कमांड के बाद या कमांड की एक श्रृंखला के बाद चलाना चाहते हैं , तो आप इसे &&ऑपरेटर (जो पिछली कमांड की सफलता पर / कमांड की श्रृंखला पर अगले कमांड को निष्पादित करेंगे) का उपयोग करके या आपके द्वारा उपयोग करके चेन कर सकते हैं ;ऑपरेटर (जो कि कमांड के पिछले कमांड / चेन की सफलता और असफलता दोनों पर है, अगले कमांड को निष्पादित करेगा)।

इस मामले में यह कुछ इस तरह होगा:

gnome-open <path_to_pdf_file> && exit

* <path_to_pfd_file> = pdf फ़ाइल का पथ

exitएक स्क्रिप्ट के अंत में काम नहीं करता है क्योंकि यह सिर्फ उस bashउदाहरण से बाहर निकलता है जिसमें स्क्रिप्ट चलती है, जो bashटर्मिनल के आंतरिक bashउदाहरण की तुलना में एक और उदाहरण है ।

यदि आप किसी भी तरह से स्क्रिप्ट का उपयोग करना चाहते हैं, तो इसका सबसे सरल तरीका यह है कि आप स्क्रिप्ट को केवल इतना ही कहें:

<path_to_script> && exit

या यदि स्क्रिप्ट टर्मिनल की वर्तमान कार्यशील निर्देशिका में है, जैसे:

./<script> && exit

यदि आप वास्तव में ऐसा नहीं करना चाहते / नहीं कर सकते हैं, तो दूसरा तरीका यह है कि इस लाइन को अपनी स्क्रिप्ट के अंत में जोड़ें:

kill -9 $PPID

यह SIGKILLस्क्रिप्ट की मूल प्रक्रिया ( bashटर्मिनल से जुड़ा उदाहरण) के लिए एक संकेत भेजेगा । यदि केवल एक ही bashउदाहरण टर्मिनल से जुड़ा हुआ है, तो मारे जाने से टर्मिनल बंद हो जाएगा। यदि कई bashउदाहरणों को टर्मिनल से जोड़ा जाता है, तो मारे जाने से टर्मिनल बंद नहीं होगा।


2
SIGTERM सिग्नल को समाप्ति के लिए अनुरोध करने के लिए एक प्रक्रिया में भेजा जाता है। SIGKILL सिग्नल के विपरीत, इसे प्रक्रिया द्वारा पकड़ा और व्याख्या या अनदेखा किया जा सकता है। यह यदि आवश्यक हो तो संसाधनों को जारी करने और राज्य को बचाने के लिए अच्छा समाप्ति प्रदर्शन करने की अनुमति देता है। SIGINT लगभग SIGTERM के समान है।
AB

@AB तुम सही हो, SIGTERMयहाँ पर्याप्त नहीं है।
कोस

उत्तर के लिए धन्यवाद। मुझे लगता है कि आप अपने जवाब में दिए गए एकल आदेश का उपयोग कर सकते हैं
रमेश

मार डालो $ PPID बाहर निकलने के समान है - कुछ भी नहीं। और किल -9 $ PPID पेरेंट के साथ-साथ सभी चाइल्ड विंडो को बंद कर देता है।
3

5

यह स्क्रिप्ट टर्मिनल को समाप्त करती है और इस प्रकार शेल और स्वयं को।

यह निर्दयतापूर्वक सभी प्रक्रियाओं को मारता है। यदि आपके पास एक टर्मिनल में कई टैब खुले हैं, तो ये भी बंद हैं।

समस्या यह है, यदि कई टर्मिनलों को खोला जाता है और ये बच्चे की प्रक्रिया है gnome-terminal-server, तो सभी टर्मिनलों को मार दिया जाएगा।

इस मामले में, स्क्रिप्ट को एक स्वतंत्र टर्मिनल में शुरू किया जाना चाहिए, जैसे xterm

<your_command> & disown

PPPID=$(awk '{print $4}' "/proc/$PPID/stat")
kill $PPPID
  • PPID

    PPID मूल प्रक्रिया आईडी है, इस मामले में शेल ( e.g. /bin/bash)

  • PPPID

    PPPID PPID की मूल प्रक्रिया आईडी है, इस मामले में, टर्मिनल विंडो

  • <your_command> & disown

    बैश शेल में, डिस्चार्ज बिलिन कमांड का उपयोग जॉब टेबल से नौकरियों को हटाने, या नौकरियों को चिह्नित करने के लिए किया जाता है ताकि माता-पिता के शेल को प्राप्त होने पर उन्हें SITEUP सिग्नल न भेजा जाए (जैसे यदि उपयोगकर्ता लॉग आउट करता है)।

  • awk '{print $4}' "/proc/$PPID/stat"

    फ़ाइल के चौथे कॉलम का मान जाता है /proc/$PPID/stat(उदाहरण के लिए /proc/1/statयह 0 देता है)


मुझे लगता है कि कमांड $ $ को टर्मिनल की पाइड मिलेगी ... क्या यह विकल्प होगा? क्या आप यह भी बता सकते हैं कि किस तरह से डिसाइड करना है?
टिम

यह स्क्रिप्ट कैसे करती है? मैं अभी भी शेल स्क्रिप्टिंग के लिए नया हूं, इसलिए मैं वास्तव में उन आदेशों को नहीं समझ सकता। क्या आप बता सकते हैं कि यह टर्मिनल को कैसे बंद करता है
रमेश

1
@ नहीं, यह एक टर्मिनल में शेल लौटाता है: ps xa | grep $$=> 4381 pts/0 Ss 0:01 /usr/bin/zsh
AB

1
@RumeshSudhaharan यह पूरी टर्मिनल विंडो को मारता है जिसमें स्क्रिप्ट शुरू की गई है, लेकिन कोई अन्य टर्मिनल विंडो नहीं है।
एबी

3
@AB आपने पहले कहा था कि यह केवल वर्तमान टर्मिनल विंडो को मारता है, दूसरों को नहीं। मैंने आज इस लिपि का उपयोग दो टर्मिनल खिड़कियों के खुलने के साथ किया और स्क्रिप्ट चलाने के बाद दोनों को मार दिया गया।
रमेश

4

आप उपयोग कर सकते हैं ।exec ./your-script

गनोम टर्मिनल जैसा एक टर्मिनल एमुलेटर क्विट करता है जब इसके अंदर चल रही प्रारंभिक प्रक्रिया - जो आमतौर पर एक शेल - क्विट होती है।

यदि आप पहले से ही एक टर्मिनल में हैं और केवल एक चीज जिसे आप छोड़ने से पहले करना चाहते हैं, वह यह है कि टर्मिनल किसी विशेष स्क्रिप्ट (या प्रोग्राम) को चलाने के लिए है, तो इसका मतलब है कि आपको अब उस शेल की आवश्यकता नहीं है जो अब उसमें चल रहा है। इस प्रकार आप शेल के execबिलिन का उपयोग कर सकते हैं ताकि शेल आपके आदेश द्वारा बनाई गई प्रक्रिया से खुद को प्रतिस्थापित कर सके।

  • आपकी स्क्रिप्ट के मामले में, यह एक और शेल प्रक्रिया है - ठीक उसी तरह जैसे कि जब आप बिना स्क्रिप्ट चलाते हैं तो दूसरी शेल प्रक्रिया कैसे बनाई जाती है exec

वाक्य-विन्यास है , जैसे ,।exec commandexec ./your-script

exec: एक उदाहरण

उदाहरण के लिए, मान लें कि मेरे पास एक शेल स्क्रिप्ट है count, जिसे निष्पादन योग्य चिह्नित किया गया है, और वर्तमान निर्देशिका में स्थित है। इसमें शामिल है:

#!/usr/bin/env bash
for i in {5..1}; do echo $i; sleep 1; done

और, एक टर्मिनल में, मैं चलाता हूं:

exec ./count

यह प्रिंट अंकों के 5, 4, 3, 2, और 1प्रति सेकंड, एक, और फिर टर्मिनल विंडो बंद करता है।

यदि आप अपने टर्मिनल में चलने वाली पहली प्रक्रिया के अलावा किसी अन्य चीज़ से इसे चलाते हैं - उदाहरण के लिए, यदि आप bashपहली बार किसी अन्य शेल आवृत्ति को प्रारंभ करने के लिए दौड़े - तो यह आपको टर्मिनल को छोड़ने के बजाय उस प्रक्रिया को बनाने वाले शेल में वापस लाता है । (यह चेतावनी समान exitतरीकों पर लागू होती है ।)

आप उपयोग कर सकते हैं ।./your-script; exit

यदि आप अपने शेल को खुद को नई प्रक्रिया (के माध्यम से exec) से बदलने के लिए नहीं कहना चाहते हैं , तो आप इसे चारों ओर चिपकाने के लिए कह सकते हैं लेकिन नई प्रक्रिया समाप्त होने के तुरंत बाद खुद को छोड़ सकते हैं।

ऐसा करने के लिए, अपनी कमांड और कमांड को चलाएं exit, ;जिससे अलग होकर उन्हें एक लाइन पर दिया जा सके।

वाक्य-विन्यास है command; exit, जैसे ,।./your-script; exit

command; exit बनाम command && exit

आप यह देख सकते हैं कि कोस और हेमायल के उत्तरों में सुझाई गई विधि के समान है। अंतर यह है कि:./your-script && exit

  • &&दूसरी कमांड को केवल तभी चलाता है जब पहले कमांड ने रिपोर्ट किया था कि यह शून्य का निकास कोड वापस करके सफल हुआ
  • ; सफलता की सूचना दी या नहीं, भले ही दूसरी कमान चलाता हो।

आप जो चाहते हैं वह विशिष्ट स्थिति पर निर्भर करता है। यदि कमांड विफल रहता है, तो क्या आप चाहते हैं कि कॉलिंग शेल (और होस्टिंग टर्मिनल) ऊपर रहे? यदि हां, तो उपयोग करें &&; यदि नहीं, तो उपयोग करें ;

वहाँ भी है command || exit, जो विफलताcommand की सूचना देने पर ही कॉलिंग शेल को छोड़ देता है ।


2

आप इसे चलाने के बजाय अपनी स्क्रिप्ट का स्रोत बना सकते हैं

$ cat run.sh
exit;
$ ./run.sh #will not close
$ . ./run.sh # will close

1

व्यक्तिगत रूप से मैं कमांड को निष्पादित करने के लिए पीडीएफ़ या अन्य फ़ाइलों को खोलने के लिए निष्पादित करूंगा, फाइलों को खोलने देने के लिए देरी डालूं, और फिर बाहर निकलें। असल में, यहाँ है कि मैंने क्या परीक्षण किया है(nohup gnome-open *.pdf &); sleep 2; exit

इस पर भिन्नता होगी nohup gnome-open *.pdf && sleep 2 && exit


मेरे मामले में, चूंकि nohupहैंगअप सिग्नल को नजरअंदाज nohup xdg-open some_programकिया exitगया था , इसलिए मेरे लिए काम किया गया था , और गैर-जरूरी था। nohupएक nohup.outफ़ाइल के लिए संदेश को पुनर्निर्देशित करता है:nohup: ignoring input and appending output to nohup.out
निकलना अनिश्चितता

0

सबसे सरल समाधान होगा:

xdg-open file.pdf && exit

nohupकमांड को अनदेखा करने के लिए अन्य समान कमांड की आवश्यकता नहीं SIGHUPहोने के कारण, इसका कारण xdg-openएक बच्चे की प्रक्रिया को रोकना होगा जो कि पीडीएफ फाइल खोलने के लिए पसंदीदा एप्लीकेशन है। चूंकि टर्मिनल से शुरू की गई वास्तविक प्रक्रिया में अब मारे जाने की nohupजरूरत नहीं है , इसकी जरूरत नहीं है।

&&इंगित करता है कि यदि पिछला कमांड सफल होता है तो अगला कमांड चलाया जाएगा यानी एक्ज़िट कोड 0( $?=0) लौटाएगा और exitटर्मिनल को बंद कर देगा।


मुझे लगता है कि उन्होंने कहा कि बाहर निकलना काम नहीं कर रहा था ...
टिम

@ समय: शायद ओपी ने इसे सही तरीके से इस्तेमाल नहीं किया, इस सवाल से कि यह मेरे लिए बहुत अस्पष्ट है कि उसने exitआखिर में कैसे काम किया / कैसे काम नहीं किया ..
heemayl

1
@ क्योंकि क्योंकि ओपी exitस्क्रिप्ट के अंदर रखा जाता है, जो अप्रयुक्त है क्योंकि इसमें उस bashउदाहरण से बाहर निकलने का प्रभाव होता है जिसमें स्क्रिप्ट को निष्पादित किया जा रहा है, फिर मूल bashउदाहरण (टर्मिनल से जुड़ा हुआ), जिसके कारण टर्मिनल बंद हो जाएगा
कोस

1
वैसे भी xdg-openपहले से ही पृष्ठभूमि में चलता है और टर्मिनल से अनलिंक किया गया है, इसलिए आपको nohupयहां ज़रूरत नहीं है, इसके अलावा जो मुझे समझ में आता है वह ओपी xdg-openस्क्रिप्ट के अंदर कई बार कई फ़ाइलों को बैच-ओपन करने के लिए चलाता xdg-openहै, स्क्रिप्ट के अंदर इस तरह का उपयोग करने से स्क्रिप्ट का कारण होगा पहली xdg-openघटना से बाहर निकलने के लिए
kos

@kos: नहीं, मैं बैकग्राउंड में नहीं चल रहा हूं xdg-open, भले ही मैं nohupएक अलग कारण के लिए था और वहां होना चाहिए..जबकि मूल टर्मिनल से पृष्ठभूमि की प्रक्रिया को मार दिया जाएगा जब आप मूल टर्मिनल को मार देंगे .. nohupको रोकने के लिए है यह..क्योंकि मुझे टर्मिनल को अंतःक्रियात्मक रूप से फिर से उपयोग करने की आवश्यकता नहीं है, प्रक्रिया को bg में डालने की कोई आवश्यकता नहीं है..और आपके 2 अंक को भी xdg-open && exitएक
उपधारा

0

शीर्षक प्रश्न का स्पष्ट उत्तर देने के लिए,

"बैश स्क्रिप्ट चलाने के बाद टर्मिनल से बाहर निकलें" :

टर्मिनल में केवल अपनी स्क्रिप्ट चलाएँ

स्क्रिप्ट क्या करती है, इसका विवरण देखे बिना, एक स्क्रिप्ट विकल्प के साथ एक टर्मिनल के अंदर सीधे चलाया जा सकता है -e( --command), बिना शेल शुरू किए - यह शेल के बजाय प्रयोग किया जाता है:

gnome-terminal -e ./script.sh

जब आप स्क्रिप्ट को तर्क प्रदान करना चाहते हैं तो विकल्प -x( --execute) का उपयोग करें । इसके साथ, कमांडलाइन के पूरे शेष को कमांड और तर्कों के रूप में लिया जाता है।

gnome-terminal -x ./script.sh foo bar

यदि आपकी स्क्रिप्ट बाहर निकलती है, तो कोई इंटरैक्टिव शेल नहीं है जो उपयोगकर्ता इनपुट की प्रतीक्षा करके कुछ भी पकड़ सकता है।

उदाहरण

कमांड के बाहर निकलने के बाद टेम्पलिन सिर्फ बाहर निकल जाएगा - इस तरह sleep, बिना किसी शेल के 4 सेकंड चलने के बाद बंद करना :

gnome-terminal -x sleep 4

बेशक, आप शेल स्क्रिप्टिंग का उपयोग कर सकते हैं, क्योंकि आपकी स्क्रिप्ट वैसे भी एक अलग शेल उदाहरण का उपयोग कर रही है।

इसके अलावा, आप एक स्पष्ट स्क्रिप्ट के साथ एक शेल चला सकते हैं - यह इंटरैक्टिव नहीं होगा:

gnome-terminal -x bash -c "echo 'Hello!'; sleep 4"
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.