বাশ স্ক্রিপ্ট চালানোর পরে টার্মিনাল থেকে প্রস্থান করুন


18

কমান্ডটি bashব্যবহার করে কিছু ফাইল (বেশিরভাগ পিডিএফ ফাইল) খোলার জন্য আমি একটি স্ক্রিপ্ট লেখার চেষ্টা করছি gnome-open। আমি পিডিএফ ফাইলটি খোলার পরে টার্মিনালটি প্রস্থান করতে চাই।

আমি যোগ করার চেষ্টা করেছি exit আমার স্ক্রিপ্টের শেষে করার করেছি তবে এটি টার্মিনালটি বন্ধ করে দেয় না। আমি আমার প্রশ্নের উত্তরের জন্য অনলাইনে অনুসন্ধান করার চেষ্টা করেছি তবে আমি কোনও সঠিক উত্তর পেলাম না, আপনি যদি সাহায্য করতে পারেন তবে আমি সত্যিই এটির প্রশংসা করব।

আমার এমন একটি উত্তর দরকার যা কেবলমাত্র টার্মিনালটি মেরে ফেলুন যেখান থেকে আমি কমান্ডটি চালাচ্ছি সমস্ত টার্মিনাল কি এটি সম্ভব হবে? পূর্ববর্তী উত্তর যা আমি স্বীকার করেছি তা খোলা থাকা সমস্ত টার্মিনাল উইন্ডোজকে হত্যা করে। আমি আজ অবধি বুঝতে পারিনি।


আপনি কি প্রথম জায়গায় টার্মিনালে স্ক্রিপ্টটি চালাচ্ছেন? কমান্ড লাইন থেকে কঠোরভাবে, এটি করার জন্য টার্মিনালটি খোলার কোনও কারণ নেই।
জ্যাকব ভ্লিজম

হ্যাঁ আমি টার্মিনাল থেকে স্ক্রিপ্টটি চালাচ্ছি। আমি বুঝতে পারিনি যে টার্মিনাল এবং কমান্ড লাইনের মধ্যে পার্থক্য রয়েছে
রুমেশ

আমি আমার স্ক্রিপ্টটির gnome-openসাথে প্রতিস্থাপন xdg-openকরেছি তবে কোনও পরিবর্তন নেই। টার্মিনালটি এখনও খোলা রয়েছে
রুমেশ

@ টিম ওয়াও, এটি কাজ করে =) +1
এবি

@ টিম তবে আমার সমাধানটিও খারাপ ছিল না। ;)
এবি

উত্তর:


12

আপনি যদি কেবল একটি ফাইল খোলেন, আপনার সত্যিই কোনও স্ক্রিপ্ট ব্যবহার করার দরকার নেই, কারণ স্ক্রিপ্ট বলতে বোঝানো হয় একাধিক কমান্ড একাধিক কমান্ড চালানোর সহজ উপায়, যখন এখানে আপনাকে কেবল দুটি কমান্ড চালানো দরকার (সহ exit) ।

যদি আপনি exitকোনও কমান্ডের পরে বা কমান্ডগুলির একটি শৃঙ্খলার পরে চালাতে চান তবে আপনি &&অপারেটরটি ব্যবহার করে এটি ইতিমধ্যে যা চালিয়ে যেতে পারেন (যা পূর্ববর্তী কমান্ডের সাফল্যে / কমান্ডের শৃঙ্খলা পরবর্তী কমান্ডটি কার্যকর করবে) বা এটি ব্যবহার করে; অপারেটর (যা উভয় সাফল্যের উপর এবং পূর্ববর্তী কমান্ড / শৃঙ্খলের শৃঙ্খলা ব্যর্থতার সাথে পরবর্তী কমান্ড কার্যকর করবে)।

এক্ষেত্রে এটি এমন কিছু হবে:

gnome-open <path_to_pdf_file> && exit

* <path_to_pfd_file> = পিডিএফ ফাইলের পথ

exitকোনও স্ক্রিপ্টের শেষে রাখা কাজ করে না কারণ এটি bashস্ক্রিপ্টটি চালিত দৃষ্টান্তটি থেকে বেরিয়ে আসে যা bashটার্মিনালের অভ্যন্তরীণ bashউদাহরণের চেয়ে অন্য উদাহরণ।

আপনি যদি যাইহোক কোনও স্ক্রিপ্ট ব্যবহার করতে চান তবে সর্বাধিক সরলতম উপায় এটির মতো স্ক্রিপ্টটি কল করার জন্য:

<path_to_script> && exit

বা স্ক্রিপ্টটি যদি টার্মিনালের বর্তমান ওয়ার্কিং ডিরেক্টরিতে থাকে:

./<script> && exit

আপনি যদি সত্যিই এটি না করতে / না করতে চান তবে দ্বিতীয় সর্বাধিক সোজা উপায় হ'ল আপনার স্ক্রিপ্টের শেষে এই লাইনটি যুক্ত করা:

kill -9 $PPID

এটি SIGKILLস্ক্রিপ্টের অভিভাবক প্রক্রিয়াতে (সংকেত bashউদাহরণটি টার্মিনালের সাথে সংযুক্ত) প্রেরণ করবে । যদি কেবলমাত্র একটি bashউদাহরণ টার্মিনালের সাথে যুক্ত হয়, তবে এটি মারা যাওয়ার ফলে টার্মিনালটি নিজেকে বন্ধ করে দেবে। যদি একাধিক bashউদাহরণ টার্মিনালের সাথে সংযুক্ত থাকে, তবে এটি নিহত হওয়ার ফলে টার্মিনালটি নিজেকে বন্ধ করে দেবে না।


2
SIGTERM সিগন্যালটি একটি সমাপ্তির অনুরোধের জন্য কোনও প্রক্রিয়াতে প্রেরণ করা হয়। সিগ্কিল সিগন্যালের বিপরীতে, এটি ধরা পড়ে এবং প্রক্রিয়া দ্বারা ব্যাখ্যা করা বা উপেক্ষা করা যায়। এটি প্রক্রিয়াটি দুর্দান্ত সমাপ্তি রিসোর্সগুলি রিলিজ করে এবং যথাযথ হলে রাষ্ট্রের সাশ্রয় করতে পারে allows সাইন ইন সিগনটারের মতো প্রায় একই রকম।
এবি

@ AB আপনি ঠিক বলেছেন, SIGTERMএখানে যথেষ্ট নয়।
কোস

জবাবের জন্য ধন্যবাদ. আমার অনুমান যে আপনার উত্তরে আপনি যে একক আদেশ দিয়েছেন তা কেবলমাত্র
অসুবিধে করুন

হত্যা $ পিপিআইডি প্রস্থান হিসাবে একই কাজ করে - কিছুই না। এবং কিল -9 $ পিপিআইডি পিতা-মাতার সাথে সমস্ত সন্তানের উইন্ডো বন্ধ করে দেয়।
এসডসোলার

5

এই স্ক্রিপ্টটি টার্মিনাল এবং এভাবে শেল এবং নিজেই সমাপ্ত করে।

এটি নির্বিচারে সমস্ত প্রক্রিয়া হত্যা করে। আপনার যদি টার্মিনালে একাধিক ট্যাব খোলা থাকে তবে এগুলিও বন্ধ রয়েছে।

সমস্যাটি হ'ল, যদি বেশ কয়েকটি টার্মিনাল খোলা হয় এবং এগুলি শিশু প্রক্রিয়াগুলি হয় তবে gnome-terminal-serverসমস্ত টার্মিনাল হত্যা করা হবে।

এই ক্ষেত্রে, স্ক্রিপ্টটি একটি স্বাধীন টার্মিনালে শুরু করা উচিত, যেমন xterm

<your_command> & disown

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

    পিপিআইডি হ'ল মূল প্রক্রিয়া আইডি, এক্ষেত্রে শেল ( e.g. /bin/bash)

  • PPPID

    পিপিপিআইডি হ'ল পিপিআইডি-র মূল প্রক্রিয়া আইডি, এক্ষেত্রে টার্মিনাল উইন্ডো

  • <your_command> & disown

    বাশ শেলের মধ্যে, অস্বীকৃত বিল্টিন কমান্ডটি কাজের টেবিল থেকে কাজগুলি সরাতে, বা কাজের চিহ্ন চিহ্নিত করতে ব্যবহৃত হয় যাতে অভিভাবক শেলটি প্রাপ্ত হলে তাদের কাছে একটি সিএইচএইচপি সংকেত না পাঠানো হয় (উদাহরণস্বরূপ যদি ব্যবহারকারী লগ আউট করে)।

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

    ফাইলের চতুর্থ কলামের মান পান /proc/$PPID/stat(উদাহরণস্বরূপ /proc/1/statএটি 0 ফেরায়)


আমি মনে করি command কমান্ডটি টার্মিনালের পিড পেয়েছে ... তা কি বিকল্প হতে পারে? আপনি কীভাবে অস্বীকার করবেন তাও ব্যাখ্যা করতে পারেন?
টিম

এই স্ক্রিপ্টটি কীভাবে তা করে? আমি এখনও শেল স্ক্রিপ্টিংয়ের জন্য নতুন তাই আমি এই আদেশগুলি সত্যিই বুঝতে পারি না। আপনি কীভাবে এটি টার্মিনালটি বন্ধ করে তা ব্যাখ্যা করতে পারেন
রুমেশ

1
@ টিম না, এটি একটি টার্মিনালে শেলটি ফেরত দেয়: ps xa | grep $$=> 4381 pts/0 Ss 0:01 /usr/bin/zsh
এবি

1
@ রুমেশসুধাহরণ এটি স্ক্রিনটি শুরু হওয়া পুরো টার্মিনাল উইন্ডোটিকে মেরে ফেলল, তবে অন্য কোনও টার্মিনাল উইন্ডো নেই।
এবি

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
নিক indiessance

0

এর সহজ সমাধানটি হ'ল:

xdg-open file.pdf && exit

nohupকমান্ডটিকে উপেক্ষা করার মতো অন্যান্য অনুরূপ কমান্ডের মতো নয় SIGHUP, কারণটি xdg-openএকটি শিশু প্রক্রিয়া তৈরির প্রস্থান করবে যা পিডিএফ ফাইল খোলার জন্য পছন্দসই প্রয়োগ। টার্মিনাল থেকে শুরু হওয়া আসল প্রক্রিয়াটি আর হত্যার nohupদরকার নেই, প্রয়োজন নেই।

&&পূর্ববর্তী কমান্ডটি সফল হলে অর্থাৎ প্রস্থান কোড 0( $?=0) প্রদান করে এবং exitকেবলমাত্র টার্মিনালটি বন্ধ করে দিলে পরবর্তী কমান্ডটি চালানো হবে indicates


আমার মনে হয় তিনি বলেছিলেন প্রস্থানটি কাজ করছে না ...
টিম

@ টিম: সম্ভবত ওপি সঠিকভাবে এটি ব্যবহার করে নি, প্রশ্নটি থেকে আমার কাছে এটি খুব স্পষ্ট নয় যে তিনি / তিনি কীভাবে exitশেষ করেছেন এবং
কীভাবে

1
@ টিম কারণ ওপি exitস্ক্রিপ্টের ভিতরে রেখেছিল , যা অকার্যকর কারণ এটির bashফলে স্ক্রিপ্টটি কার্যকর হওয়ার পরিবর্তে পিতামাত্ত bashউদাহরণটি (টার্মিনালের সাথে সংযুক্ত একটি) প্রদর্শিত হবে যা এর পরিবর্তে টার্মিনালটি বন্ধ করে দেবে
কোস

1
যাইহোক, xdg-openইতিমধ্যে ব্যাকগ্রাউন্ডে চলে এবং টার্মিনাল থেকে লিঙ্কযুক্ত, সুতরাং আপনার nohupএখানে দরকার নেই, প্লাস যা আমি বুঝতে পারি তার থেকে xdg-openস্ক্রিপ্টের মধ্যে একাধিক ফাইল ব্যাচ-ওপেন চালানোর xdg-openজন্য স্ক্রিপ্টের অভ্যন্তরে এটি ব্যবহার করে স্ক্রিপ্টের কারণ হতে পারে প্রথমে প্রস্থান xdg-openoccurence
কস

@ কোস: না, আমি xdg-openব্যাকগ্রিতে চালাচ্ছি না, এমনকি আমার যদি nohupঅন্য কারণে হয় এবং অবশ্যই nohupসেখানে থাকতে হয় ... যখন আপনি প্যারেন্ট টার্মিনালটি মেরে ফেলবেন তখন আরম্ভের টার্মিনাল থেকে যে কোনও পটভূমি প্রক্রিয়াটি মারা যাবে .. প্রতিরোধের জন্য কি আছে? এটি..আপনার সাথে আবারও টার্মিনালটি ইন্টারেক্টিভভাবে ব্যবহার করার দরকার নেই, প্রক্রিয়াটি বিজি তে রাখার দরকার নেই..আপনার ২ য় পয়েন্টে যা প্রতিটি 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"
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.