আন্তঃসংযুক্ত কমান্ডগুলির মধ্যে আমি কীভাবে ডেটার একটি বিজ্ঞপ্তি প্রবাহকে প্রয়োগ করতে পারি?


19

আমি দুটি প্রকার সম্পর্কে জানি যে কীভাবে কমান্ডগুলি একে অপরের সাথে সংযুক্ত হতে পারে:

  1. পাইপ ব্যবহার করে (পরবর্তী কমান্ডের স্টাডি-ইনপুটটিতে স্টাডি-আউটপুট স্থাপন)।
  2. টি ব্যবহার করে (আউটপুটটিকে অনেকগুলি আউটপুটগুলিতে বিভক্ত করুন)।

আমি জানি না যে এটি সম্ভব কি না, তাই আমি একটি অনুমান সংযোগের ধরনটি আঁকি:

এখানে চিত্র বর্ণনা লিখুন

এই সিউডো কোডে উদাহরণস্বরূপ কমান্ডগুলির মধ্যে ডেটার একটি বিজ্ঞপ্তি প্রবাহ প্রয়োগ করা কীভাবে সম্ভব হবে, যেখানে আমি কমান্ডের পরিবর্তে ভেরিয়েবল ব্যবহার করি:

pseudo-code:

a = 1    # start condition 

repeat 
{
b = tripple(a)
c = sin(b) 
a = c + 1 
}

উত্তর:


16

বিজ্ঞপ্তি I / O লুপ প্রয়োগ করা হয়েছে tail -f

এটি একটি বিজ্ঞপ্তি I / O লুপ প্রয়োগ করে:

$ echo 1 >file
$ tail -f file | while read n; do echo $((n+1)); sleep 1; done | tee -a file
2
3
4
5
6
7
[..snip...]

এটি আপনার উল্লিখিত সাইন অ্যালগরিদম ব্যবহার করে বিজ্ঞপ্তি ইনপুট / আউটপুট লুপ প্রয়োগ করে:

$ echo 1 >file
$ tail -f file | while read n; do echo "1+s(3*$n)" | bc -l; sleep 1; done | tee -a file
1.14112000805986722210
.72194624281527439351
1.82812473159858353270
.28347272185896349481
1.75155632167982146959
[..snip...]

এখানে, bcভাসমান পয়েন্ট গণিত করে এবং s(...)সাইন ফাংশনের জন্য সিসি চিহ্নিতকরণ।

পরিবর্তে পরিবর্তনশীল ব্যবহার করে একই অ্যালগরিদমের প্রয়োগ

এই নির্দিষ্ট গণিত উদাহরণের জন্য, বিজ্ঞপ্তি I / O পদ্ধতির প্রয়োজন হয় না। একটি সহজেই একটি পরিবর্তনশীল আপডেট করতে পারে:

$ n=1; while true; do n=$(echo "1+s(3*$n)" | bc -l); echo $n; sleep 1; done
1.14112000805986722210
.72194624281527439351
1.82812473159858353270
.28347272185896349481
[..snip...]

12

আপনি এটির জন্য তৈরি, এর জন্য একটি ফিফো ব্যবহার করতে পারেন mkfifo। তবে মনে রাখবেন যে দুর্ঘটনাক্রমে একটি অচলাবস্থা তৈরি করা এটি খুব সহজ। আমাকে ব্যাখ্যা করতে দাও — আপনার অনুমানের "বিজ্ঞপ্তি" উদাহরণটি নিন। আপনি কোনও কমান্ডের আউটপুটটিকে তার ইনপুটটিতে ফিড দিন। কমপক্ষে দুটি উপায় রয়েছে এটি অচল হতে পারে:

  1. কমান্ডটির একটি আউটপুট বাফার রয়েছে। এটি আংশিকভাবে পূরণ করা হয়েছে, তবে এখনও ফ্লাশ করা হয়নি (আসলে লিখিত)। এটি পূরণ করার পরে এটি করা হবে। সুতরাং এটি এর ইনপুট পড়তে ফিরে যায়। এটি চিরতরে বসে থাকবে, কারণ এটির যে ইনপুটটির জন্য এটি অপেক্ষা করছে তা আসলে আউটপুট বাফারে। এবং এটি ইনপুট না পাওয়া পর্যন্ত এটি ফ্লাশ করা হবে না ...

  2. কমান্ডটিতে লেখার জন্য একগুচ্ছ আউটপুট রয়েছে। এটি এটি লেখা শুরু করে তবে কার্নেল পাইপ বাফারটি পূর্ণ হয়। সুতরাং এটি সেখানে বসে, বাফারে তাদের স্থান হওয়ার জন্য অপেক্ষা করছে। এটি এর ইনপুটটি পড়ার সাথে সাথে ঘটবে, অর্থাত্ এটি কখনই এটি করবে না যতক্ষণ না এটি তার আউটপুটে যা কিছু লেখা শেষ করে।

বলেছিল, আপনি এখানে এটি কীভাবে করছেন। এই উদাহরণটি সহ od, হেক্স ডাম্পগুলির একটি শেষ না হওয়া চেইন তৈরি করতে:

mkfifo fifo
( echo "we need enough to make it actually write a line out"; cat fifo ) \ 
    | stdbuf -i0 -o0 -- od -t x1 | tee fifo

নোট করুন যে অবশেষে বন্ধ হয়ে যায়। কেন? এটি অচল হয়ে গেছে, উপরে # 2। আপনি এখানে stdbufকলটি লক্ষ্য করতে পারেন , বাফারিং অক্ষম করতে। তা ছাড়া? কোনও আউটপুট ছাড়াই ডেডলকস।


ধন্যবাদ, আমি এই প্রসঙ্গে বাফার সম্পর্কে কিছুই জানতাম না, আপনি কি আরও কীওয়ার্ড সম্পর্কে আরও পড়তে জানেন?
আবদুল আল হাজরেড

1
ইনপুট / আউটপুট বাফার উপলব্ধ, আপ চেহারার জন্য @AbdulAlHazred stdio বাফার উপলব্ধ । একটি পাইপে কার্নেলের বাফারের জন্য, পাইপ বাফারটি কাজ করছে বলে মনে হচ্ছে।
ডারোবার্ট

4

সাধারণভাবে আমি একটি মেকফিল (কমান্ড মেক) ব্যবহার করব এবং আপনার চিত্রটি মেকফাইল বিধিগুলিতে ম্যাপ করার চেষ্টা করব।

f1 f2 : f0
      command < f0 > f1 2>f2

পুনরাবৃত্তি / সাইক্লিক কমান্ডগুলির জন্য, আমাদের একটি পুনরাবৃত্তি নীতি নির্ধারণ করতে হবে। সঙ্গে:

SHELL=/bin/bash

a.out : accumulator
    cat accumulator <(date) > a.out
    cp a.out accumulator

accumulator:
    touch accumulator     #initial value

প্রত্যেকে makeসেই সময়ে একটি পুনরাবৃত্তি উত্পাদন করবে।


এর অপব্যবহারের makeঅপ্রয়োজনীয়, তবে অপ্রয়োজনীয়: আপনি যদি একটি মধ্যবর্তী ফাইল ব্যবহার করেন তবে কেন এটি পরিচালনা করার জন্য একটি লুপ ব্যবহার করবেন না?
অ্যালেক্সিস

@ অ্যালেক্সিস, মেকফিলগুলি সম্ভবত ওভারকিল। লুপগুলি সম্পর্কে আমি খুব আরামদায়ক নই: ঘড়ির ধারণা, থামার অবস্থা বা একটি সুস্পষ্ট উদাহরণ আমি মিস করছি। প্রাথমিক চিত্রগুলি আমাকে ওয়ার্কফ্লো এবং ফাংশন স্বাক্ষরের স্মরণ করিয়েছিল। জটিল চিত্রগুলির জন্য আমরা ডেটা সংযোগ বা মেকফাইল টাইপ করা নিয়মগুলির প্রয়োজন শেষ করব। (এটি কেবল একটি আপত্তিজনক অন্তর্নিহিত)
জাজাও

@ অ্যালেক্সিস এবং অবশ্যই আমি আপনার সাথে একমত হই।
জাজাও

আমি মনে করি না এটি অপব্যবহার - makeএটি ম্যাক্রোগুলি সম্পর্কে যা এখানে একটি নিখুঁত প্রয়োগ।
মাইকজার্ভ

1
@ মাইকজার্, হ্যাঁ এবং আমরা সকলেই জানি যে অপব্যবহারের সরঞ্জামগুলি ইউনিক্সের আন্ডারগ্রাউন্ড ম্যাগনা কার্টা :)
জাজাও

4

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

প্রথম স্থানে, এটি প্রদর্শিত হবে যে bcএটি আপনার জন্য একজন কপোক্রেসির প্রধান প্রার্থী। ইন bcআপনি যা করতে পারেন defineফাংশন যে আপনার pseudocode মধ্যে জন্য প্রায় কাছাকাছি কি আপনি জিজ্ঞাসা করতে পারেন। উদাহরণস্বরূপ, এটি করার জন্য কিছু খুব সাধারণ ক্রিয়াকলাপ এর মতো দেখতে পারে:

printf '%s()\n' b c a |
3<&0 <&- bc -l <<\IN <&3
a=1; b=0; c=0;
define a(){ "a="; return (a = c+1); }
define b(){ "b="; return (b = 3*a); }
define c(){ "c="; return (c = s(b)); }
IN

... যা মুদ্রণ করবে ...

b=3
c=.14112000805986722210
a=1.14112000805986722210

তবে অবশ্যই এটি স্থায়ী হয় না । printfএর পাইপ প্রস্থান ছাড়ারprintfa()\n দায়িত্বে থাকা শিগগিরই ( পাইপকে লেখার ঠিক পরে ) পাইপটি ছিঁড়ে ফেলা হয় এবং bcএর ইনপুট বন্ধ হয়ে যায় এবং এটিও প্রস্থান করে। এটি যতটা কার্যকর হতে পারে তেমন কার্যকর নয়।

ইউডারলিটি ইতিমধ্যে ইউটিলিটি সহ একটি নামযুক্ত পাইপ ফাইল তৈরি করে ফিফোর কথা উল্লেখ করেছে । এগুলি মূলত কেবল পাইপগুলিই রয়েছে, সিস্টেম কার্নেল উভয় প্রান্তের সাথে একটি ফাইল সিস্টেম প্রবেশের লিঙ্ক দেয়। এগুলি খুব কার্যকর, তবে ফাইল সিস্টেমে ঝুঁকিপূর্ণভাবে ঝুঁকি না নিয়ে যদি আপনি কেবল পাইপটি পেতে পারেন তবে এটি খুব ভাল।mkfifo

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

ইন bash, উদাহরণস্বরূপ, কেমন প্রক্রিয়া প্রতিকল্পন কাজ দেখতে পারেন:

bash -cx ': <(:)'
+ : /dev/fd/63

আপনি দেখতে পাচ্ছেন যে এটি আসলে একটি প্রতিস্থাপন । শেল সম্প্রসারণ করার সময় একটি মান কর্মের পরিবর্তে একটি পাথ সাথে সঙ্গতিপূর্ণ লিংক একটি থেকে নল । আপনি এর সদ্ব্যবহার করতে পারেন - ()প্রতিস্থাপনের মধ্যে যা কিছু প্রক্রিয়া চলে তার সাথে যোগাযোগ করার জন্য আপনাকে কেবল সেই পাইপটি ব্যবহার করতে বাধা দেওয়া হবে না ...

bash -c '
    eval "exec 3<>"<(:) "4<>"<(:)
    cat  <&4 >&3  &
    echo hey cat >&4
    read hiback  <&3
    echo "$hiback" here'

... যা ছাপায় ...

hey cat here

এখন আমি জানি যে বিভিন্ন শাঁস বিভিন্ন উপায়ে কোপ্রোসেস জিনিসটি করে - এবং এটি bashস্থাপনের জন্য একটি নির্দিষ্ট বাক্য গঠন রয়েছে (এবং সম্ভবত এটির জন্য একটিও zshরয়েছে) - তবে কীভাবে এই জিনিসগুলি কাজ করে তা আমি জানি না। আমি শুধু জানি তুমি উভয় অনর্থক সব ছাড়া কার্যত একই জিনিস করে উপরে সিনট্যাক্স ব্যবহার করতে পারেন bashএবং zsh- এবং আপনি একটি অনুরূপ জিনিস করতে পারেন dashএবং busybox ashএখানে-নথি সঙ্গে একই উদ্দেশ্য অর্জনের জন্য (কারণ dashএবং busyboxএখানে- না অন্যান্য দু'জনের মতো টেম্প-ফাইলের চেয়ে পাইপযুক্ত নথি)

সুতরাং, যখন প্রয়োগ করা হয় bc...

eval "exec 3<>"<(:) "4<>"<(:)
bc -l <<\INIT <&4 >&3 &
a=1; b=0; c=0;
define a(){ "a="; return (a = c+1); }
define b(){ "b="; return (b = 3*a); }
define c(){ "c="; return (c = s(b)); }
INIT
export BCOUT=3 BCIN=4 BCPID="$!"

... এটা শক্ত অংশ। এবং এটি মজার অংশ ...

set --
until [ "$#" -eq 10 ]
do    printf '%s()\n' b c a >&"$BCIN"
      set "$@" "$(head -n 3 <&"$BCOUT")"
done; printf %s\\n "$@"

... যা ছাপায় ...

b=3
c=.14112000805986722210
a=1.14112000805986722210
#...24 more lines...
b=3.92307618030433853649
c=-.70433330413228041035
a=.29566669586771958965

... এবং এটি এখনও চলছে ...

echo a >&"$BCIN"
read a <&"$BCOUT"
echo "$a"

... যা শুধু আমার জন্য সর্বশেষ মান পায় bc'র aবরং কলিং চেয়ে a()এটি এবং কপি করে প্রিন্ট বাড়াতে ফাংশন ...

.29566669586771958965

এটি চালিয়ে যেতে থাকবে, আসলে, যতক্ষণ না আমি এটিকে হত্যা করব এবং এর আইপিসি পাইপগুলি ছিন্ন করব না ...

kill "$BCPID"; exec 3>&- 4>&-
unset BCPID BCIN BCOUT

1
অনেক আগ্রহব্যাঞ্জক. সাম্প্রতিক ব্যাশ এবং zsh এর সাথে দ্রষ্টব্য, আপনাকে ফাইল বর্ণনাকারী নির্দিষ্ট করতে হবে না, যেমন eval "exec {BCOUT}<>"<(:) "{BCIN}<>"<(:)কাজ করে
Thor
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.