আপনি বিভিন্ন শেলগুলিতে কমান্ড কপ্রোকটি কীভাবে ব্যবহার করবেন?


77

কেউ কীভাবে ব্যবহার করতে পারেন তার কয়েকটি উদাহরণ প্রদান করতে পারেন coproc?

উত্তর:


118

সহ-প্রক্রিয়াগুলি একটি kshবৈশিষ্ট্য (ইতিমধ্যে রয়েছে ksh88)। zshযখন এটি শুধু মাত্র যোগ করা হয়েছে শুরু (তাড়াতাড়ি 90s) থেকে বৈশিষ্ট্য ছিল, bashমধ্যে 4.0(2009)।

তবে, 3 টি শেলের মধ্যে আচরণ এবং ইন্টারফেস উল্লেখযোগ্যভাবে পৃথক।

ধারণাটি একই, যদিও: এটি পটভূমিতে একটি কাজ শুরু করার অনুমতি দেয় এবং নামকরণ পাইপগুলির অবলম্বন না করে এটির ইনপুট পাঠাতে এবং তার আউটপুট পড়তে সক্ষম করে।

এটি বেশিরভাগ শেল এবং সকেটপেইরের সাথে নামবিহীন পাইপ দিয়ে কিছু সিস্টেমে ksh93 এর সাম্প্রতিক সংস্করণ সহ সম্পন্ন করা হয়।

ইন a | cmd | b, aডেটা ফিড করে cmdএবং bএর আউটপুট পড়ে। cmdএকটি সহ-প্রক্রিয়া হিসাবে চালনা শেল উভয় aএবং উভয় হতে দেয় b

ksh সহ প্রক্রিয়াগুলি

ইন ksh, আপনি এই হিসাবে একটি স্বীকৃতি শুরু করুন:

cmd |&

আপনি এই জাতীয় cmdকাজ করে ডেটা ফিড করেন :

echo test >&p

অথবা

print -p test

এবং cmdএর মতো জিনিসগুলির সাথে আউটপুট পড়ুন :

read var <&p

অথবা

read -p var

cmdকোনো পটভূমি কাজ হিসাবে শুরু হয়, তুমি দেখতে ব্যবহার করতে পারেন fg, bg, killএটা এবং তা পড়ুন %job-numberবা মাধ্যমে $!

পাইপের লেখার শেষটি cmdপড়তে পাঠাচ্ছে , আপনি এটি করতে পারেন:

exec 3>&p 3>&-

এবং অন্য পাইপের পড়ার শেষটি বন্ধ করতে (এক cmdএটি লিখেছেন):

exec 3<&p 3<&-

আপনি প্রথমে পাইপ ফাইল বর্ণনাকারীদের কিছু অন্যান্য এফডিএস সংরক্ষণ না করে আপনি দ্বিতীয় সহ-প্রক্রিয়া শুরু করতে পারবেন না। এই ক্ষেত্রে:

tr a b |&
exec 3>&p 4<&p
tr b c |&
echo aaa >&3
echo bbb >&p

zsh সহ প্রক্রিয়া

ইন zsh, কো-প্রসেসগুলি তাদের মধ্যে প্রায় একই রকম ksh। আসল পার্থক্যটি হ'ল zshসহ-প্রক্রিয়াগুলি coprocকীওয়ার্ড দিয়ে শুরু হয় ।

coproc cmd
echo test >&p
read var <&p
print -p test
read -p var

এরকম:

exec 3>&p

দ্রষ্টব্য: এটি coprocফাইলের বর্ণনাকারীকে এফডি তে স্থানান্তরিত করে না 3( kshঅনুরূপ), তবে এটি সদৃশ করে। সুতরাং, আছে কোন স্পষ্ট পথ খাওয়ানো বা পড়া পাইপ বন্ধ করতে, অন্যান্য শুরু অন্য coproc

উদাহরণস্বরূপ, খাওয়ানোর শেষটি বন্ধ করতে:

coproc tr a b
echo aaaa >&p # send some data

exec 4<&p     # preserve the reading end on fd 4
coproc :      # start a new short-lived coproc (runs the null command)

cat <&4       # read the output of the first coproc

পাইপ ভিত্তিক সহ-প্রক্রিয়াগুলি ছাড়াও, zsh(২০০০ সালে প্রকাশিত ৩.১..6-ডিভ ১৯৯০ এর সাথে) সিউডো-টিটি ভিত্তিক নির্মাণ রয়েছে expect। বেশিরভাগ প্রোগ্রামের সাথে ইন্টারঅ্যাক্ট করার জন্য, ksh- স্টাইলের কো-প্রসেসগুলি কাজ করবে না, যেহেতু প্রোগ্রামগুলি যখন আউটপুটটি পাইপ হয় তখন বাফার শুরু করে।

এখানে কিছু উদাহরণঃ.

সহ-প্রক্রিয়া শুরু করুন x:

zmodload zsh/zpty
zpty x cmd

(এখানে, cmdএকটি সহজ কমান্ড But তবে আপনি evalবা ফাংশনগুলির সাথে কল্পিত কাজ করতে পারেন ))

একটি সহ-প্রক্রিয়া ডেটা ফিড:

zpty -w x some data

সহ-প্রক্রিয়া ডেটা পড়ুন (সবচেয়ে সহজ ক্ষেত্রে):

zpty -r x var

পছন্দ করুন expect, এটি প্রদত্ত প্যাটার্নের সাথে মিলিত কো-প্রক্রিয়া থেকে কিছু আউটপুট অপেক্ষা করতে পারে।

বাশ সহ-প্রক্রিয়া

ব্যাশ সিনট্যাক্সটি অনেক নতুন, এবং সম্প্রতি ksh93, ব্যাশ এবং zsh এ যুক্ত হওয়া একটি নতুন বৈশিষ্ট্যের শীর্ষে নির্মিত। এটি 10 ​​এর উপরে গতিশীলভাবে বরাদ্দকৃত ফাইল বর্ণনাকারীদের পরিচালনা করার জন্য একটি সিনট্যাক্স সরবরাহ করে।

bashএকটি বেসিক coproc সিনট্যাক্স এবং একটি বর্ধিত এক প্রস্তাব দেয়।

বেসিক সিনট্যাক্স

একটি সহ-প্রক্রিয়া শুরু করার জন্য প্রাথমিক সিনট্যাক্সটি দেখতে এর মতো দেখাচ্ছে zsh:

coproc cmd

ইন kshবা zsh, এর এবং সহ-প্রক্রিয়া থেকে পাইপ ব্যবহার করা হয় >&pএবং <&p

তবে এতে bash, সহ-প্রক্রিয়া থেকে পাইপ এবং অন্য পাইপ থেকে সহ-প্রসেসের ফাইলের বিবরণকারীগুলি $COPROCঅ্যারেতে ফিরে আসে (যথাক্রমে ${COPROC[0]}এবং ${COPROC[1]}... সুতরাং ...

সহ প্রক্রিয়ায় ডেটা ফিড করুন:

echo xxx >&"${COPROC[1]}"

সহ-প্রক্রিয়া থেকে ডেটা পড়ুন:

read var <&"${COPROC[0]}"

বেসিক সিনট্যাক্সের সাহায্যে আপনি কেবলমাত্র একটি সহ-প্রক্রিয়া শুরু করতে পারেন।

বর্ধিত বাক্য গঠন

প্রসারিত বাক্য গঠনতে , আপনি আপনার সহ-প্রক্রিয়াগুলির নাম দিতে পারেন ( zshzpty কো-প্রোসেসিসের মতো ):

coproc mycoproc { cmd; }

কমান্ড রয়েছে একটি যৌগ কমান্ড যাবে। (লক্ষ্য করুন যে উপরের উদাহরণটি কীভাবে মনে করিয়ে দেয় function f { ...; }))

এবার, ফাইল বর্ণনাকারী রয়েছে ${mycoproc[0]}এবং আছে ${mycoproc[1]}

আপনি একটি সময়ে একাধিক সহ-প্রক্রিয়া শুরু হতে পারে সময় কিন্তু আপনি কি একটি সর্তকবার্তা পান যখন আপনি একটি কো-প্রক্রিয়া শুরু করার সময় এক এখনও চলছে (এমনকি নন-ইন্টারেক্টিভ মোডে)।

বর্ধিত বাক্য গঠন ব্যবহার করার সময় আপনি ফাইল বর্ণনাকারী বন্ধ করতে পারেন।

coproc tr { tr a b; }
echo aaa >&"${tr[1]}"

exec {tr[1]}>&-

cat <&"${tr[0]}"

নোট করুন যে উপায়টি বন্ধ করা বাশ সংস্করণগুলিতে 4.3 এর আগে কাজ করে না যেখানে আপনাকে এটি পরিবর্তে লিখতে হবে:

fd=${tr[1]}
exec {fd}>&-

মতই kshএবং zshসেই নল ফাইল বর্ণনাকারী ক্লোজ-অন Exec হিসাবে চিহ্নিত করা হয়েছে।

কিন্তু এ bashনির্বাহিত কমান্ড সেই পাস করার একমাত্র উপায় তাদের fds সদৃশ তৈরি হয় 0, 1অথবা 2। এটি আপনার একক কমান্ডের সাথে ইন্টারঅ্যাক্ট করতে পারে এমন সহ-প্রক্রিয়াগুলির সংখ্যা সীমিত করে। (একটি উদাহরণ জন্য নিচে দেখুন.)

যশ প্রক্রিয়া এবং পাইপলাইন পুনর্নির্দেশ

yashপ্রতি সেউসে কোনও সহ-প্রক্রিয়া বৈশিষ্ট্য নেই, তবে একই পাইপলাইন এবং প্রক্রিয়া পুনঃনির্দেশ বৈশিষ্ট্যগুলির সাথে একই ধারণাটি প্রয়োগ করা যেতে পারে । সিস্টেম কলটিতে yashএকটি ইন্টারফেস রয়েছে pipe(), সুতরাং এই ধরণের জিনিসটি তুলনামূলকভাবে সহজেই হাতে হাতে করা যায়।

আপনি এর সাথে একটি সহ-প্রক্রিয়া শুরু করবেন:

exec 5>>|4 3>(cmd >&5 4<&- 5>&-) 5>&-

যা প্রথমে একটি pipe(4,5)(5 লেখার শেষ, 4 পড়া শেষ) তৈরি করে, তারপরে অন্য প্রান্তে তার স্টিডিনের সাথে প্রবাহিত কোনও প্রসেসে fd 3 কে একটি পাইপতে পুনঃনির্দেশ করে এবং আগে তৈরি পাইপে গিয়ে স্টাডআউট। তারপরে আমরা সেই পাইপের লেখার শেষটি পিতামাতার মধ্যে বন্ধ করি যা আমাদের প্রয়োজন হবে না। সুতরাং এখন শেলটিতে আমরা সেন্টিমিডির স্টিডিনের সাথে এফডি 3 সংযুক্ত করেছি এবং পাইপগুলির সাথে সিএমডি এর স্টাডাউটের সাথে fd 4 সংযুক্ত করেছি।

নোট করুন যে-অন-এক্সিকিউটিভ পতাকাটি সেই ফাইল বিবরণকারীগুলিতে সেট করা নেই।

ডেটা খাওয়ানোর জন্য:

echo data >&3 4<&-

ডেটা পড়তে:

read var <&4 3>&-

এবং আপনি যথারীতি এফডিএস বন্ধ করতে পারেন:

exec 3>&- 4<&-

এখন, কেন তারা এত জনপ্রিয় নয়

নামযুক্ত পাইপ ব্যবহারের ক্ষেত্রে খুব সহজেই কোনও উপকার পাবেন

কো-প্রসেসগুলি স্ট্যান্ডার্ড নামযুক্ত পাইপগুলি সহ সহজেই প্রয়োগ করা যায়। আমি জানি না কখন নামকরণ করা পাইপগুলি চালু হয়েছিল তবে এটি সম্ভব ছিল kshসহ-প্রক্রিয়াগুলি নিয়ে আসার পরে (সম্ভবত 80 এর দশকের মাঝামাঝি সময়ে, ksh88 88 তে "মুক্তি পেয়েছিল", তবে আমি বিশ্বাস করি যে kshকয়েক বছর আগে এটিএন্ডটিটিতে অভ্যন্তরীণভাবে ব্যবহৃত হয়েছিল) যে) যা ব্যাখ্যা করবে।

cmd |&
echo data >&p
read var <&p

এর সাথে লেখা যেতে পারে:

mkfifo in out

cmd <in >out &
exec 3> in 4< out
echo data >&3
read var <&4

এগুলির সাথে যোগাযোগ করা আরও সহজ straight বিশেষত যদি আপনার একাধিক সহ-প্রক্রিয়া চালানো দরকার। (নীচে উদাহরণ দেখুন।)

ব্যবহারের একমাত্র সুবিধা coprocহ'ল ব্যবহারের পরে আপনাকে সেই নামযুক্ত পাইপগুলি পরিষ্কার করতে হবে না।

অচলাবস্থা-প্রবণ

শেলগুলি কয়েকটি নির্মাণে পাইপ ব্যবহার করে:

  • শেল পাইপ: cmd1 | cmd2 ,
  • কমান্ড প্রতিকল্পন: $(cmd) ,
  • এবং প্রক্রিয়া প্রতিস্থাপন: <(cmd) , >(cmd)

সেগুলিতে, ডেটা বিভিন্ন প্রক্রিয়াগুলির মধ্যে কেবল একটি দিকে প্রবাহিত হয় ।

সহ-প্রক্রিয়াগুলি এবং নামযুক্ত পাইপ সহ, যদিও, অচলাবস্থায় চালানো সহজ। কোনটি কমান্ডের মধ্যে কোন ফাইল বর্ণনাকারী খোলা রয়েছে তার ট্র্যাক রাখতে হবে, যাতে কোনও ব্যক্তি খোলা থাকে না এবং কোনও প্রক্রিয়া জীবিত থাকে। ডেডলকগুলি তদন্ত করার জন্য কৌশলযুক্ত হতে পারে, কারণ এগুলি অ-সংজ্ঞাবহভাবে হতে পারে; উদাহরণস্বরূপ, কেবলমাত্র যখন একটি পাইপ আপ পূরণ করার জন্য যতটা ডেটা প্রেরণ করা হয়।

expectএটির জন্য যা ডিজাইন করা হয়েছে তার থেকেও খারাপ কাজ করে

সহ-প্রক্রিয়াগুলির মূল উদ্দেশ্য হ'ল কমান্ডগুলির সাথে যোগাযোগের উপায় সহ শেল সরবরাহ করা। তবে এটি এতটা ভাল কাজ করে না।

উপরে বর্ণিত ডেডলকের সহজতম রূপটি হ'ল:

tr a b |&
echo a >&p
read var<&p

কারণ এর আউটপুট কোনও টার্মিনালে যায় না, trতার আউটপুটটি বাফার করে। সুতরাং এটি এতে কোনওরকম ফাইল আউটপুট দেয় না যতক্ষণ না এটি এতে ফাইল-এর শেষ প্রান্তটি না দেখায় stdinবা এটি আউটপুটে ডেফায় পূর্ণ বাফার জমে থাকে। সুতরাং উপরে, শেলের আউটপুট a\n(কেবলমাত্র 2 বাইট) থাকার পরে, readঅনির্দিষ্টকালের trজন্য ব্লক হবে কারণ শেলটি আরও ডেটা প্রেরণের জন্য অপেক্ষা করছে।

সংক্ষেপে, পাইপগুলি কমান্ডের সাথে যোগাযোগের জন্য ভাল নয় n't সহ-প্রক্রিয়াগুলি কেবলমাত্র সেই আদেশগুলির সাথে ইন্টারঅ্যাক্ট করতে ব্যবহার করা যেতে পারে যা তাদের আউটপুট বাফার করে না বা কমান্ডগুলি যা তাদের আউটপুট বাফার না করতে বলা যেতে পারে; উদাহরণস্বরূপ, stdbufসাম্প্রতিক জিএনইউ বা ফ্রিবিএসডি সিস্টেমগুলিতে কিছু কমান্ড ব্যবহার করে ।

এজন্য expectবা zptyপরিবর্তে সিউডো-টার্মিনাল ব্যবহার করুন। expectকমান্ডগুলির সাথে ইন্টারঅ্যাক্ট করার জন্য ডিজাইন করা একটি সরঞ্জাম এবং এটি এটি ভাল করে।

ফাইল বর্ণনাকারী হ্যান্ডলিং বেআইনীভাবে এবং সঠিকভাবে পাওয়া শক্ত

কো-প্রসেসগুলি সাধারণ শেল পাইপগুলির তুলনায় আরও জটিল প্লাম্বিং করতে ব্যবহৃত হতে পারে।

যে অন্যান্য ইউনিক্স.এসই উত্তরে একটি কপ্রোক ব্যবহারের উদাহরণ রয়েছে।

এখানে একটি সরলীকৃত উদাহরণ রয়েছে: আপনি একটি ফাংশন চান তা কল্পনা করুন যা একটি কমান্ডের আউটপুটের অনুলিপি 3 অন্যান্য কমান্ডকে সরবরাহ করে এবং তারপরে 3 টি কমান্ডের আউটপুট সংক্ষিপ্ত হয়ে যায়।

সমস্ত পাইপ ব্যবহার করে।

উদাহরণস্বরূপ, আউটপুট ভোজন printf '%s\n' foo barকরতে tr a b, sed 's/./&&/g'এবং cut -b2-ভালো কিছু প্রাপ্ত:

foo
bbr
ffoooo
bbaarr
oo
ar

প্রথমত, এটি অগত্যা সুস্পষ্ট নয়, তবে সেখানে অচলাবস্থা হওয়ার সম্ভাবনা রয়েছে এবং এটি কয়েক কিলোবাইটের ডেটা পরেই ঘটতে শুরু করবে।

তারপরে, আপনার শেলের উপর নির্ভর করে, আপনি বিভিন্ন সমস্যার সমাধান করবেন যেগুলি আলাদাভাবে মোকাবেলা করতে হবে।

উদাহরণস্বরূপ, এর সাথে zsh, আপনি এটি দিয়ে যাবেন:

f() (
  coproc tr a b
  exec {o1}<&p {i1}>&p
  coproc sed 's/./&&/g' {i1}>&- {o1}<&-
  exec {o2}<&p {i2}>&p
  coproc cut -c2- {i1}>&- {o1}<&- {i2}>&- {o2}<&-
  tee /dev/fd/$i1 /dev/fd/$i2 >&p {o1}<&- {o2}<&- &
  exec cat /dev/fd/$o1 /dev/fd/$o2 - <&p {i1}>&- {i2}>&-
)
printf '%s\n' foo bar | f

সর্বোপরি, সহ-প্রক্রিয়া fds ক্লোজ-অন Exec পতাকা সেট আছে, কিন্তু না বেশী যে (হিসাবে তাদের কাছ থেকে সদৃশ হয় {o1}<&p)। সুতরাং, অচলাবস্থা এড়াতে, আপনাকে নিশ্চিত করতে হবে যে কোনও প্রক্রিয়ায় যেগুলি তাদের প্রয়োজন হয় না সেগুলি বন্ধ রয়েছে।

একইভাবে, exec catপাইপ খোলা রাখার বিষয়ে শেল প্রক্রিয়া নেই বলে তা নিশ্চিত করতে আমাদের একটি সাবশেল ব্যবহার করতে হবে এবং শেষ পর্যন্ত ব্যবহার করতে হবে।

সঙ্গে ksh(এখানে ksh93), যে হতে হবে তা হবে:

f() (
  tr a b |&
  exec {o1}<&p {i1}>&p
  sed 's/./&&/g' |&
  exec {o2}<&p {i2}>&p
  cut -c2- |&
  exec {o3}<&p {i3}>&p
  eval 'tee "/dev/fd/$i1" "/dev/fd/$i2"' >&"$i3" {i1}>&"$i1" {i2}>&"$i2" &
  eval 'exec cat "/dev/fd/$o1" "/dev/fd/$o2" -' <&"$o3" {o1}<&"$o1" {o2}<&"$o2"
)
printf '%s\n' foo bar | f

( দ্রষ্টব্য: এটি সেই সিস্টেমে কাজ করবে না যেখানে পরিবর্তে kshব্যবহার socketpairsকরে pipesএবং যেখানে /dev/fd/nলিনাক্সের মতো কাজ করে))

ইন ksh, উপরের এফডিএসগুলি কমান্ড 2-অন- এক্সিকিউট ফ্ল্যাগের সাথে চিহ্নিত করা হয়, যদি না তারা কমান্ড লাইনে স্পষ্টভাবে পাস না করে। এই কারণেই আমাদের অব্যবহৃত ফাইল বর্ণনাকারীদের বন্ধ করতে হবে না zshut তবে এটি কেন আমাদের করতে হবে {i1}>&$i1এবং evalসেই নতুন মানটির জন্য ব্যবহার $i1করতে হবে, যা পাস করতে হবে teeএবং cat

এটি করা bashযায় না, কারণ আপনি ঘনিষ্ঠ অন-এক্সিকিউট পতাকাটি এড়াতে পারবেন না।

উপরে, এটি তুলনামূলকভাবে সহজ, কারণ আমরা কেবল সাধারণ বাহ্যিক কমান্ড ব্যবহার করি। এটির পরিবর্তে আপনি যখন শেল কনস্ট্রাক্টস ব্যবহার করতে চান এটি আরও জটিল হয়ে যায় এবং আপনি শেল বাগগুলিতে চালানো শুরু করেন।

নামের পাইপ ব্যবহার করে উপরের সাথে তুলনা করুন:

f() {
  mkfifo p{i,o}{1,2,3}
  tr a b < pi1 > po1 &
  sed 's/./&&/g' < pi2 > po2 &
  cut -c2- < pi3 > po3 &

  tee pi{1,2} > pi3 &
  cat po{1,2,3}
  rm -f p{i,o}{1,2,3}
}
printf '%s\n' foo bar | f

উপসংহার

আপনি যদি কোনও কমান্ড, ব্যবহার expect, বা zshএর zpty, বা নামযুক্ত পাইপগুলির সাথে ইন্টারেক্ট করতে চান ।

আপনি যদি পাইপগুলির সাথে কিছু অভিনব নদীর গভীরতানির্ণয় করতে চান তবে নামযুক্ত পাইপগুলি ব্যবহার করুন।

সহ-প্রক্রিয়াগুলি উপরোক্ত কিছু করতে পারে, তবে অপ্রয়োজনীয় কোনও কিছুর জন্য গুরুতর মাথা স্ক্র্যাচিং করতে প্রস্তুত থাকুন।


সত্যিই দুর্দান্ত উত্তর। নির্দিষ্টভাবে কখন এটি ঠিক করা হয়েছিল তা আমি জানি না, তবে কমপক্ষে bash 4.3.11আপনি এখন কক্স্রোক ফাইল বর্ণনাকারীদের সরাসরি অক্সের প্রয়োজন ছাড়াই বন্ধ করতে পারেন । পরিবর্তনশীল; আপনার উত্তর উদাহরণ পরিপ্রেক্ষিতে exec {tr[1]}<&- এখন কাজ হবে (coproc এর stdin বন্ধ করতে; মনে রাখবেন যে আপনার কোড (পরোক্ষভাবে) বন্ধ করুন করার চেষ্টা করে {tr[1]}ব্যবহার >&-, কিন্তু {tr[1]}coproc কারো নির্দেশ চলে না stdin , এবং অবশ্যই বন্ধ করতে হবে <&-)। সমাধানটি অবশ্যই কোথাও কোথাও এসেছিল 4.2.25যা এখনও সমস্যাটি প্রদর্শন করে এবং 4.3.11যা হয় না।
mklement0

1
@ এমকেলেটমেন্ট ০, ধন্যবাদ exec {tr[1]}>&-সত্যই নতুন সংস্করণগুলির সাথে কাজ করে বলে মনে হচ্ছে এবং এটি সিডাব্লুআরইউ / চেঞ্জলগ এন্ট্রিতে রেফারেন্স করা হয়েছে ( {অ্যারে [ind] like এর মতো শব্দগুলিকে বৈধ পুনঃনির্দেশের জন্য অনুমতি দিন ... 2012-09-01)। exec {tr[1]}<&-(বা আরও সঠিক >&-সমতুল্য যদিও এটি কোনও পার্থক্য close()করে না যে কেবল উভয়ের জন্য আহ্বান জানায় ) কোপ্রোকের স্টিডিন বন্ধ করে না, তবে পাইপটির লেখার শেষটি সেই কোপ্রোকের কাছে রয়েছে।
স্টাফেন চেজেলাস

1
@ এমকিলেটমেন্ট ০, ভাল পয়েন্ট, আমি এটি আপডেট করে যুক্ত করেছি yash
স্টাফেন চেজেলাস

1
এর সর্বোপরি একটি সুবিধা mkfifoহ'ল আপনাকে রেস অ্যাক্সেসের জন্য রেসের অবস্থা এবং সুরক্ষা সম্পর্কে চিন্তা করতে হবে না। ফিফোর সাথে অচলাবস্থার বিষয়ে আপনাকে এখনও চিন্তা করতে হবে।
ওথিউস

1
অচলাবস্থা সম্পর্কে: stdbufকমান্ডটি তাদের কমপক্ষে কয়েকটি রোধ করতে সহায়তা করতে পারে। আমি এটি লিনাক্স এবং ব্যাশের অধীনে ব্যবহার করেছি। যাইহোক আমি বিশ্বাস করি @ স্টাফেনচাজেলাস উপসংহারে ঠিক: "মাথা চুলকানো" পর্বটি কেবল তখনই শেষ হয়েছিল যখন আমি নামী পাইপগুলিতে ফিরে এসেছি।
shub

7

কো-প্রসেসগুলি প্রথমে ksh88শেল (1988) দিয়ে শেল স্ক্রিপ্টিং ভাষায় এবং পরে zsh1993 এর আগে কোনও সময়ে প্রবর্তিত হয়েছিল ।

Ksh এর অধীনে একটি সহ-প্রক্রিয়া চালু করার বাক্য গঠন command |&। সেখান থেকে শুরু করে আপনি commandস্ট্যান্ডার্ড ইনপুটটিতে লিখতে পারেন print -pএবং এর স্ট্যান্ডার্ড আউটপুট এর সাথে পড়তে পারেন read -p

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

বাশ ৪.০ এবং আরও নতুনর অধীনে, আপনি coprocআদেশটি সহ একটি সহ-প্রক্রিয়া চালু করতে পারেন , যেমন:

$ coproc awk '{print $2;fflush();}'

তারপরে আপনি স্ট্যান্ডিন কমান্ডের কাছে কিছু পাঠাতে পারেন:

$ echo one two three >&${COPROC[1]}

এবং এর সাথে বিশ্রী আউটপুট পড়ুন:

$ read -ru ${COPROC[0]} foo
$ echo $foo
two

Ksh এর অধীনে, এটি হত:

$ awk '{print $2;fflush();}' |&
$ print -p "one two three"
$ read -p foo
$ echo $foo
two

-1

"কপোক্রোক" কী?

এটি "সহ-প্রক্রিয়া" এর জন্য সংক্ষিপ্ত, যার অর্থ শেলকে সহযোগিতা করার একটি দ্বিতীয় প্রক্রিয়া। এটি কমান্ডের শেষে "&" দিয়ে শুরু হওয়া পটভূমির কাজটির সাথে খুব মিল, এর প্যারেন্ট শেল হিসাবে একই স্ট্যান্ডার্ড ইনপুট এবং আউটপুটকে ভাগ না করে, তার স্ট্যান্ডার্ড I / O একটি বিশেষ দ্বারা প্যারেন্ট শেলের সাথে সংযুক্ত থাকে এফআইএফও নামে পরিচিত পাইপের একটি ধরণের রেফারেন্সের জন্য এখানে ক্লিক করুন

কেউ zsh এর সাথে একটি কপোক্রোক শুরু করে

coproc command

কমান্ডটি স্টিডিনের কাছ থেকে পড়তে এবং / অথবা স্টডআউটে লেখার জন্য প্রস্তুত থাকতে হয়, বা এটি কোনও কপোক্রোক হিসাবে খুব বেশি ব্যবহৃত হয় না।

এই নিবন্ধটি এখানে পড়ুন এটি এক্সিকিউট এবং কপোক্রোকের মধ্যে কেস স্টাডি সরবরাহ করে


আপনি নিজের উত্তরের নিবন্ধটি কিছু যোগ করতে পারেন? আমি এই বিষয়টিকে ইউ ও এল-তে অন্তর্ভুক্ত করার চেষ্টা করছিলাম কারণ এটি উপস্থাপিত বলে মনে হচ্ছে। আপনার উত্তরের জন্য ধন্যবাদ! এছাড়াও লক্ষ করুন যে আমি ট্যাগটি zsh নয়, বাশ হিসাবে সেট করেছি।
slm

@ এসএলএম আপনি ইতিমধ্যে বাশ হ্যাকারগুলিকে নির্দেশ করেছেন। আমি সেখানে যথেষ্ট উদাহরণ দেখেছি। যদি আপনার উদ্দীপনাটি এই প্রশ্নটিকে মনোযোগের আওতায় আনতে হয় তবে হ্যাঁ আপনি সফল
ভ্যালেন্টাইন বাজরামি

এগুলি বিশেষ ধরণের পাইপ নয়, তারা ব্যবহৃত পাইপগুলির মতো |। (এটি বেশিরভাগ শেলের পাইপ এবং ksh93-তে সকেটপেইস ব্যবহার করা হয়)। পাইপ এবং সকেটপেইরগুলি প্রথম-ইন, প্রথম আউট, তারা সমস্ত ফিফো। mkfifoনামযুক্ত পাইপ তৈরি করে, কপোরাসেস নামক পাইপ ব্যবহার করে না।
স্টাফেন চেজেলাস

@ এসএলএম zsh এর জন্য দুঃখিত ... আসলে আমি zsh এ কাজ করি। আমি কখনও কখনও প্রবাহের সাথে এটি করার ঝোঁক করি। এটি বাশের ক্ষেত্রেও দুর্দান্ত কাজ করে ...
মুনাই দাস উদাসিন

@ স্টিফেন চেজেলাস আমি নিশ্চিত যে আমি কোথাও এটি পড়েছি যে এটি আমি / ও ফিফো নামক বিশেষ ধরণের পাইপের সাথে যুক্ত ...
মুনাই দাস উদাসিন

-1

এখানে আরও একটি ভাল (এবং কার্যকরী) উদাহরণ রয়েছে - BASH এ লিখিত একটি সাধারণ সার্ভার। দয়া করে নোট করুন যে আপনার ওপেনবিএসডি দরকার হবে netcat, ক্লাসিকটি কাজ করবে না। অবশ্যই আপনি ইউনিক সকেটের পরিবর্তে ইনট সকেট ব্যবহার করতে পারেন।

server.sh:

#!/usr/bin/env bash

SOCKET=server.sock
PIDFILE=server.pid

(
    exec </dev/null
    exec >/dev/null
    exec 2>/dev/null
    coproc SERVER {
        exec nc -l -k -U $SOCKET
    }
    echo $SERVER_PID > $PIDFILE
    {
        while read ; do
            echo "pong $REPLY"
        done
    } <&${SERVER[0]} >&${SERVER[1]}
    rm -f $PIDFILE
    rm -f $SOCKET
) &
disown $!

client.sh:

#!/usr/bin/env bash

SOCKET=server.sock

coproc CLIENT {
    exec nc -U $SOCKET
}

{
    echo "$@"
    read
} <&${CLIENT[0]} >&${CLIENT[1]}

echo $REPLY

ব্যবহার:

$ ./server.sh
$ ./client.sh ping
pong ping
$ ./client.sh 12345
pong 12345
$ kill $(cat server.pid)
$
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.