একাধিক প্রোগ্রাম দ্বারা নিরাপদে মুদ্রিত "লাইন" কীভাবে?


11

ধরুন আমি সমান্তরালভাবে একাধিক প্রোগ্রাম সম্পাদন করতে চাই এবং তাদের ফলাফলগুলি একটি পাইপের সাথে একত্রিত করতে চাই:

sh -c '
    (echo qqq; echo qqq2; echo qqq3)&
    (echo www; echo www2; echo www3)& 
    (echo eee; echo eee2; echo eee3)& 
  wait; wait; wait'

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

qqq
qqwww
q2
qqq3www2

wwweee3

eee2
eee3

যে সমাধানগুলির সমাধান সম্পর্কে আমাকে ইঙ্গিত দেওয়া হয়েছিল তার মধ্যে একটি ছিল tail -f:

tail -n +0 -q -f <(echo qqq; echo qqq2; echo qqq3) <(echo www; echo www2; echo www3) <(echo eee; echo eee2; echo eee3)

, তবে এটি উপ-অনুকূল বিকল্প: এটি আস্তে আস্তে আউটপুট দেয়, এটি শেষ হয় না; আমি আউটপুটগুলি "ঘুম" ক্রমে দেখছি না, তবে এই ক্ষেত্রে আর্গুমেন্টের ক্রমে:

tail -n +0 -q -f <(sleep 1; echo qqq; sleep 1; echo qqq2; echo qqq3) <(echo www; echo www2; sleep 10; echo www3) <(echo eee; sleep 4; echo eee2; echo eee3) | cat

আমি এটির জন্য একটি বিশেষ ছোট প্রোগ্রাম বাস্তবায়ন করেছি , তবে বিশ্বাস করি এটি করার কিছু মানক উপায় থাকতে হবে।

মানক সরঞ্জামগুলি (এবং কোনও tail -fঅসুবিধে ছাড়াই ) কীভাবে এটি ব্যবহার করবেন ?


আপনি কিভাবে আউটপুট মিশ্রিত করতে চান? স্পষ্টতই আপনি আউটপুটটি মিশ্রিত করতে চান যেহেতু আপনি "আর্গুমেন্ট অর্ডার" না দিয়ে "স্লিপ অর্ডার" চান। আপনার আউটপুটটি মিশ্রিত করতে হবে তবে লাইনগুলি নয়, অর্থাত্ প্রতিটি লাইনটি প্রিন্ট করা উচিত?
গিলস 'তাই খারাপ হওয়া বন্ধ করুন'

Linewise। সমস্ত শুরু হওয়া প্রোগ্রামগুলির সমস্ত লাইনগুলি তাড়াতাড়ি সরবরাহ করা উচিত, তবে প্রতিটি লাইনের ভিতরে না মিশিয়ে।
vi।

আমি মনে করি এটি করার মানক syslog
উপায়টিকে

ব্যবহার করছে syslogলগ নয়, কিন্তু কিছু জন্য কাস্টম ঠিক আছে বলে মনে করা?
vi।

এটি এখন পর্যন্ত পোস্ট করা অন্যান্য পরামর্শের চেয়ে আদর্শ নয়, তবে আমি ভেবেছিলাম এটি -sলেজের বিকল্পের জন্য উল্লেখ করা উপযুক্ত হবে। উদাহরণস্বরূপ tail -f -s .1 fileলুপের বিলম্বকে ডিফল্ট 1 সেকেন্ড থেকে .1 সেকেন্ডে হ্রাস করবে।
cpugeniusmv

উত্তর:


3

জিএনইউ সমান্তরাল।

আগস্ট ২০১৩ তারিখে প্রকাশিত নোটগুলি থেকে :

--line-bufferলাইন ভিত্তিতে আউটপুট বাফার করবে। --groupপুরো কাজের জন্য আউটপুট একসাথে রাখে। --ungroupআউটপুট এক কাজ থেকে আসা অর্ধেক লাইনের সাথে এবং অন্য কাজ থেকে আসা অর্ধেক লাইনের সাথে মিশ্রণের অনুমতি দেয়। --line-bufferএই দুটি মধ্যে ফিট করে; এটি একটি সম্পূর্ণ লাইন মুদ্রণ করে, তবে বিভিন্ন কাজের লাইন মেশানোর জন্য অনুমতি দেয়।

উদাহরণ স্বরূপ:

parallel --line-buffer <jobs

যেখানে jobsরয়েছে:

./long.sh
./short.sh one
./short.sh two

short.sh:

#!/bin/bash

while true; do
        echo "short line $1"
        sleep .1
done

long.sh:

#!/bin/bash

count=0
while true; do
        echo -n "long line with multiple write()s "
        sleep .1
        count=$((count+1))
        if [ $count -gt 30 ]; then
                count=0
                echo
        fi
done

আউটপুট:

short line one
short line two
short line one
short line two
short line one
**-snip-**
short line one
short line one
short line two
short line two
short line one
short line one
short line one
long line with multiple write()s long line with multiple write()s long line with multiple write()s long line with multiple write()s long line with multiple write()s long line with multiple write()s long line with multiple write()s long line with multiple write()s long line with multiple write()s long line with multiple write()s long line with multiple write()s long line with multiple write()s long line with multiple write()s long line with multiple write()s long line with multiple write()s long line with multiple write()s long line with multiple write()s long line with multiple write()s long line with multiple write()s long line with multiple write()s long line with multiple write()s long line with multiple write()s long line with multiple write()s long line with multiple write()s long line with multiple write()s long line with multiple write()s long line with multiple write()s long line with multiple write()s long line with multiple write()s long line with multiple write()s long line with multiple write()s 
short line two
short line two
short line two
short line one

1

একটি সমাধান বাস্তবায়ন লক:

function putlines () {
   read line || return $?
   while ! ln -s $$ lock >/dev/null 2>&1
   do
      sleep 0.05
   done
   echo "$line" 
}

function getlines () {
     while read lline
     do 
          echo "$lline"
          rm lock
     done
}

# your paralelized jobs  
(  
   job1 | putlines & 
   job2 | putlines & 
   job3 | putlines & 
   wait
) | getlines| final_processing

ফাইল সিস্টেম ব্যবহারের চেয়ে একটি লক তৈরির আরও দ্রুত উপায় হওয়া উচিত।


0

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

তবে, যদি আপনার লাইনগুলি প্রসেস স্যুইচিংয়ের আগে পুরোপুরি লেখা যেতে পারে এবং আপনার সমস্যাটি হ'ল যে একটি লাইন তৈরি করা খুব দীর্ঘ সময় নেয়, আপনি পঠন ব্যবহার করে আউটপুটটি বাফার করতে পারেন।

উদাহরণ:

((./script1 | while read line1; do echo $line1; done) & \
(./script2 | while read line2; do echo $line2; done)) | doSomethingWithOutput

সুন্দর না. অসম্ভব যে নির্ভরযোগ্য। অসম্ভব যে অভিনয় ভাল হবে।
vi।

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

বর্তমানে আমি আমার প্রোগ্রামের সাথে সন্তুষ্ট (প্রশ্নে লিঙ্কিত) ব্যতীত এটি সংগ্রহস্থলগুলিতে পাওয়া যায় না সুতরাং এটিকে সামান্য "স্ট্যান্ডার্ড" হিসাবে বিবেচনা করা যায় না। সমাধানটি সেখানে চাপ দেওয়ার চেষ্টা করা যেতে পারে ...
vi।

0

আপনি নামযুক্ত পাইপটি দিয়ে নাম তৈরি করতে পারেন mkfifo, আউটপুটটিকে নামক পাইপে ফেলে দিতে পারেন এবং আপনার সংগৃহীত ডেটার জন্য নামী পাইপ থেকে আলাদাভাবে পড়তে পারেন:

mkfifo /tmp/mypipe
job1 > /tmp/mypipe &
job2 > /tmp/mypipe &
job3 > /tmp/mypipe &

cat /tmp/mypipe > /path/to/final_output &

wait; wait; wait; wait

1
কখন job1এবং job2আউটপুট দীর্ঘ (> 4096 বাইট) রেখাগুলি কীভাবে এই ম্যাংলিং থেকে রক্ষা করবে ? এটিকে কোয়েডের প্রথম কোডের কোডের সমান পাইপ বলে মনে হয়।
vi।

খুব ফর্সা পয়েন্ট। আপনার প্রশ্নের মধ্যে সুস্পষ্টভাবে ডেকে আনা সত্ত্বেও আমি বড়-অঙ্কুরিত আউটপুটটিকে বিবেচনা করি না। আমি এখন ভাবছি যে সম্ভবত এমন কোনও সরঞ্জাম নেই যা বিপরীত করে tee, যা আপনি যা চান ঠিক তেমন মনে হয়। সম্ভবত অভ্যন্তরীণ syslogবা অন্যান্য লগিং সরঞ্জামগুলির দিকে নজর দিন কারণ তারা স্পষ্টতই একাধিক স্থান থেকে এক লগ ফাইলে একত্রিত করে। লক করা ঠিক উত্তর হতে পারে, যেমনটি অমানবিক প্রস্তাবিত, যেমনটিও।
ডোপঘোতি
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.