আধা অ্যাসিনক্রোনাস পাইপ


11

ধরুন আমার কাছে নিম্নলিখিত পাইপ রয়েছে:

a | b | c | d

আমি কিভাবে শেষ হওয়ার জন্য অপেক্ষা করতে পারেন c(অথবা b) এ shবা bash? এর অর্থ এই যে স্ক্রিপ্ট dযে কোনো সময় শুরু করতে পারেন (এবং না না অপেক্ষা করা প্রয়োজন) কিন্তু থেকে সম্পূর্ণ আউটপুট প্রয়োজন cকাজ সঠিকভাবে।

ব্যবহারের ক্ষেত্রে একটি হল difftoolজন্য gitইমেজ তুলনা করা হয়। এটিকে বলা হয় gitএবং এর ইনপুট ( a | b | cঅংশ) প্রক্রিয়া করা এবং তুলনার ফলাফল ( dঅংশ) প্রদর্শন করা দরকার। আহ্বানকারী ইনপুট যে জন্য প্রয়োজন বোধ করা হয় মুছে ফেলবে aএবং b। এর অর্থ হ'ল স্ক্রিপ্ট থেকে ফিরে আসার আগে প্রক্রিয়া c(বা b) অবশ্যই শেষ করতে হবে। অন্যদিকে, আমি অপেক্ষা করতে পারি না dকারণ এর অর্থ আমি ব্যবহারকারীর ইনপুটটির জন্য অপেক্ষা করছি।

আমি জানি আমি cএকটি অস্থায়ী ফাইলে ফলাফল লিখতে পারি বা সম্ভবত কোনও ফিফো ব্যবহার করতে পারি bash। (যদিও এফআইএফও সাহায্য করবে কিনা তা নিশ্চিত নয়।) অস্থায়ী ফাইলগুলি না করে কি এটি অর্জন করা সম্ভব sh?

সম্পাদনা

সম্ভবত এটি যথেষ্ট হবে যদি আমি নির্ভরযোগ্য ফ্যাশনে c(বা b) প্রক্রিয়াটির প্রসেস আইডিটি জানতে পারি । তারপরে পুরো পাইপটি তাত্পর্যপূর্ণভাবে শুরু করা যেতে পারে এবং আমি কোনও প্রক্রিয়া আইডির জন্য অপেক্ষা করতে পারি। এর লাইন বরাবর কিছু

wait $(a | b | { c & [print PID of c] ; } | d)

সম্পাদনা ^ 2

আমি একটি সমাধান পেয়েছি, মন্তব্যগুলি (বা আরও ভাল সমাধান) স্বাগত।


আপনি বলতে চাইছেন যে আপনি সম্পূর্ণ করার পরে কেবলমাত্র আউটপুট dপ্রসেসিং শুরু করতে চান ? আপনি প্রতিটি আউটপুট লাইনের সাথে সাথে প্রক্রিয়া শুরু করতে চান না ? ccd
terdon

@ এটারডন: না, dএটি যখনই পছন্দ করে তখন cশুরু করতে পারে তবে আমার এগিয়ে যাওয়ার আগে শেষ করা দরকার।
krlMLr

এটি স্ববিরোধী বলে মনে হচ্ছে, dএটি যখন পছন্দ করতে শুরু করতে পারে তবে আপনি ঠিক কীটির জন্য অপেক্ষা করছেন?
terdon

@ ইটারডন: ব্যবহারের ক্ষেত্রে দেখানোর জন্য প্রসারিত।
krlMLr

যদি dএর আউটপুট ব্যবহার cনা করে dতবে পাইপলাইনের অংশটি তৈরি করার কোনও ধারণা নেই বলে মনে হচ্ছে । তবে যদি dইনপুটটি ব্যবহার করে তবে dঅবশ্যই কোনও পার্থক্য করতে আপনার পদ্ধতির জন্য এটি সমস্ত পড়ার পরে তার ইনপুটটিতে কিছুক্ষণ কাজ করতে হবে।
হউক লেগেছে

উত্তর:


6
a | b | { c; [notify];} | d

বিজ্ঞপ্তিটি করা যেতে পারে যেমন একটি পিআইডি-র সংকেত দ্বারা যা এনভায়রনমেন্ট ভেরিয়েবল ( kill -USR1 $EXTPID) এ পাস করা হয়েছে বা একটি ফাইল ( touch /path/to/file) তৈরি করে ।

আরেকটি ধারণা:

আপনি পাইপলাইন থেকে পরবর্তী প্রক্রিয়াটি (যার জন্য আপনি অপেক্ষা করতে শুরু করতে সক্ষম হবেন) সম্পাদন করুন:

a | b | { c; exec >&-; nextprocess;} | d

অথবা

a | b | { c; exec >&-; nextprocess &} | d

ধন্যবাদ। তবে তারপরে, মধ্যবর্তী আউটপুটটির জন্য একটি অস্থায়ী ফাইল তৈরি করা আরও ভার্জোজ এবং পার্স করা সহজ (কোনও মানুষের জন্য)। এছাড়াও, আমি কীভাবে সংকেত সহকারে দৌড়ের অবস্থা এড়াতে পারি? ... আমি একটি ক্লিনার সমাধানের জন্য আশা করছিলাম, তবে যদি এই উপায় হয়, তবে তাই হবে।
krlMLr

@krlmlr রেসের অবস্থা কি?
হউক লেগেছে

notifyআমি সিগন্যাল ফাঁদ সেট আপ করার আগে কার্যকর করা যেতে পারে। আমি কীভাবে নিশ্চিত করতে পারি যে সেই সিগন্যালটি মিস করবেন না?
krlMLr

@krlmlr আপনি স্ক্রিপ্টটি থামিয়ে দিন যা পাইপলাইনটিকে কল করে যতক্ষণ না এটি সংকেত প্রাপ্ত হওয়ার পরে নিজেই trapসংজ্ঞায়িত হওয়ার পরে প্রেরণ করা হয় ।
হউক লেগেছে

আপনার সম্পাদনা: পাইপটি একটি লুপে ডাকা হয়, যার উপর আমার কোনও নিয়ন্ত্রণ নেই। দুর্ভাগ্যক্রমে, { c; bg; }বা { c; exit 0; }কাজ করছে বলে মনে হচ্ছে না।
krlmlr

5

আমি যদি আপনার প্রশ্নটি সঠিকভাবে বুঝতে পারি তবে এটির কাজ করা উচিত:

a | b | c | { (exec <&3 3<&-; d) &} 3<&0

(এফডি 3 কৌশলটি কারণ কয়েকটি (বেশিরভাগ) শেল স্টিডিনকে / dev / নাল দিয়ে পুনঃনির্দেশ করে &)।


4

ব্যাশে, আপনি একটি প্রক্রিয়া বিকল্প ব্যবহার করতে পারেন । প্রক্রিয়া প্রতিস্থাপনের কমান্ড অ্যাসিনক্রোনাক্যালি চলমান, এটির জন্য অপেক্ষা করা হয় না।

a | b | c > >(d)

ধন্যবাদ। এটি bashকেবল, ঠিক - কোনও shসমর্থন নেই?
krlMLr

@krlmlr বাশ / zsh কেবল (এবং কয়েকটি পরিবর্তন সহ ksh93)
গিলস

3

হউকের ইনপুটটির সাহায্যে এটি আমি পরীক্ষার এবং ত্রুটির দ্বারা খুঁজে পেয়েছি:

a | b | { c; kill -PIPE $$; } | d

সমতুল্যভাবে:

a | b | ( c; kill -PIPE $$; ) | d

(পরেরটি আরও স্পষ্ট, কারণ {}কোনও পাইপের অভ্যন্তরে যদি যাইহোক সাবহেল চলবে))

কিছু অন্যান্য সিগন্যাল (সহ QUIT, TERMএবং USR1) কাজ করে, তবে এই ক্ষেত্রে সংকেতের বিবরণটি টার্মিনালে প্রদর্শিত হয়।

আমি ভাবছি যদি এটি PIPEসিগন্যালের আসল উদ্দেশ্য হয় । ম্যানুয়াল অনুসারে :

SIGPIPE: PIPEসিগন্যালটি কোনও প্রক্রিয়ায় প্রেরণ করা হয় যখন এটি অন্য প্রান্তের সাথে সংযুক্ত কোনও প্রক্রিয়া ছাড়াই পাইপে লেখার চেষ্টা করে।

এর অর্থ হ'ল আমি যখন কৃত্রিমভাবে সাবসেলের কাছে পাইপ সিগন্যাল প্রেরণ করি তখন এটি চূড়ান্তভাবে চূড়ান্তভাবে শেষ হয়, চূড়ান্ত গ্রাহককে ( d) রেখে যায়।

এই উভয় কাজ করে shএবং bash


0

আপনি sponge"moreutils" প্যাকেজ থেকে প্রোগ্রামটি ব্যবহার করতে পারেন :

a | b | c | sponge | d

স্পঞ্জ cএর পাইপ করার আগে এর আউটপুট শেষ হবে d। আশা করি আপনি যা চেয়েছিলেন


0

আপনি ঠিক করতে পারেন:

a | b | c | (d ; cat > /dev/null)

সুতরাং, যখন dশেষ হয়, শেষ না হওয়া অবধি অবশিষ্টের আউটপুট catশুষে নেবে c

ঠিক আছে. মন্তব্যের পরে, আমি মনে করি উত্তরটি সরাসরি dপটভূমিতে শুরু করা।

না:

a | b | c | (d &)

বা ব্যবহার স্টিফেন Chazelas এর সমাধান যদি সমস্যা হয় dথেকে পড়া stdin


আমার ভয় হচ্ছে যে আমার ব্যবহারের ঘটনাটি বরং অন্যভাবে হয়: এর cআগে শেষ হয় d, এবং cশেষ হওয়া পর্যন্ত আমাকে অপেক্ষা করতে হয় তবে যত্ন করে না d
krlmlr

দুঃখিত, আমি এটি পেলাম না। cশেষ হয়ে গেলে এবং dচলমান অবস্থায় আপনি কী করতে চান ? খুন d?
অ্যাঙ্গাস

dএকটি জিইউআই রয়েছে এবং ব্যবহারকারী এটি বন্ধ না করা পর্যন্ত চলতে পারে।
krlmlr

ঠিক আছে ... তবে এটি ইতিমধ্যে ঘটেছে। যখন a, bএবং cতাদের কাজ শেষ হয়, তারা স্টাডআউট বন্ধ করে প্রস্থান করে; এবং শুধুমাত্র dচলমান থাকে। শেষ হয়ে dগেলে আপনি কি পটভূমিতে প্রেরণ করতে চান c? এইটাই কি সেইটা?
অ্যাঙ্গাস

হ্যাঁ, dএকবার cশেষ হয়ে গেলে পটভূমিতে প্রেরণ করা উচিত ।
krlmlr
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.