নামযুক্ত পাইপে স্বয়ংক্রিয় ইওএফগুলি প্রতিরোধ করুন এবং আমি যখন চাই তখন একটি ইওএফ প্রেরণ করুন


12

আমার একটি প্রোগ্রাম রয়েছে যা একটি প্রদত্ত স্ট্রিমের EOF পড়ার পরে স্বয়ংক্রিয়ভাবে প্রস্থান করে (নিম্নলিখিত ক্ষেত্রে, স্টিডিন) din
এখন আমি একটি শেল স্ক্রিপ্ট তৈরি করতে চাই, যা একটি নামযুক্ত পাইপ তৈরি করে এবং প্রোগ্রামটির স্টিডিনকে এটির সাথে সংযুক্ত করতে পারে। তারপরে স্ক্রিপ্টটি পাইপটিতে বেশ কয়েকবার ব্যবহার করে echoএবং cat(এবং অন্যান্য সরঞ্জামগুলি যা স্বয়ংক্রিয়ভাবে একটি ইওফ উত্পন্ন করে যখন তারা বের হয়)। আমি যে সমস্যার মুখোমুখি হচ্ছি echoতা হ'ল প্রথম কাজটি শেষ হয়ে গেলে এটি পাইপকে একটি ইওএফ প্রেরণ করে প্রোগ্রামটি প্রস্থান করে। যদি আমি এর মতো কিছু ব্যবহার করি tail -fতবে আমি প্রোগ্রামটি ছাড়ার ইচ্ছায় আমি কোনও ইওএফ পাঠাতে পারি না। আমি ভারসাম্যযুক্ত সমাধান নিয়ে গবেষণা করছি কিন্তু কোন ফলসই হয়নি।
ইওএফগুলি কীভাবে প্রতিরোধ করা যায় এবং কীভাবে ম্যানুয়ালি একটি ইওএফ পাঠাতে হয় উভয়ই আমি ইতিমধ্যে খুঁজে পেয়েছি তবে আমি সেগুলি সংহত করতে পারি না। কোন ইঙ্গিত আছে?

#!/bin/sh
mkfifo P
program < P & : # Run in background
# < P tail -n +1 -f | program
echo some stuff > P # Prevent EOF?
cat more_stuff.txt > P # Prevent EOF?
send_eof > P # How can I do this?
# fg

উত্তর:


13

অন্যরা যেমন সূচিত করেছে, কোনও লেখকের বাকী থাকার পরে পাইপের পাঠক ইওএফ পান। সুতরাং সমাধানটি হ'ল এটি নিশ্চিত করা যে সর্বদা একজন লেখক এটিকে খোলায়। সেই লেখককে কিছু পাঠাতে হবে না, খালি এটি ধরে রাখুন।

যেহেতু আপনি একটি শেল স্ক্রিপ্ট ব্যবহার করছেন তাই সহজ সমাধান হ'ল শেলকে লেখার জন্য পাইপ খুলতে বলা। এবং আপনার কাজ শেষ হয়ে গেলে এটি বন্ধ করুন।

#!/bin/sh
mkfifo P
exec 3>P # open file descriptor 3 writing to the pipe
program < P
# < P tail -n +1 -f | program
echo some stuff > P
cat more_stuff.txt > P
exec 3>&- # close file descriptor 3

মনে রাখবেন যে আপনি যদি শেষ লাইনটি বাদ দেন তবে স্ক্রিপ্টটি প্রস্থান করলে ফাইল বর্ণনাকারী 3 স্বয়ংক্রিয়ভাবে বন্ধ হয়ে যায় (এবং এভাবে পাঠক ইওএফ পান)। সুবিধাগুলি বাদে, স্ক্রিপ্টটি যদি কোনওভাবে প্রথম দিকে শেষ করতে হয় তবে এটি প্রকারের সুরক্ষাও সরবরাহ করে।


2
এই exec 3>Pকারণেই বাশ ঝুলবে কেন?
ওয়াং

@ ওয়াং এটা করা উচিত নয়। যদি এটি হয় তবে আপনি সম্ভবত প্রশ্নটির পোকা কোডের মতো একই জিনিস করছেন না। কেবলমাত্র আমি ভাবতে পারি যে এটির ফলে এটি ব্লক হয়ে যাবে যদি আপনি পরিবর্তে এর মতো কিছু করছেন exec 2>Pএবং আপনি ট্রেস মোড চালু করেছেন ( set -x), যাতে বাশটি পাইপটিতে লিখতে চলেছে, তবে কোনও পাঠক নেই সুতরাং এটির জন্য অপেক্ষা করা বন্ধ করে দেয় কিছু পড়ার জন্য।
প্যাট্রিক

1
@ ওয়াং @ পেট্রিক আসলে exec 3>Pআমার মেশিনেও ঝুলছে ash এটি কারণ কোনও প্রক্রিয়া পড়ার প্রক্রিয়া নেই P। সুতরাং, সমাধানটি ছিল লাইনগুলি অদলবদল করা exec 3>Pএবং program < P &(অ্যাম্পারস্যান্ড যুক্ত করা যাতে প্রোগ্রামটি পটভূমিতে চলে runs
macieksk

2

শেষ লেখক চলে গেলে একটি পাইপ ইওএফ পায়। এটি এড়াতে, নিশ্চিত হয়ে নিন যে সেখানে সর্বদা একজন লেখক রয়েছেন (এমন প্রক্রিয়া যা লেখার জন্য পাইপ খোলে, তবে আসলে কিছুই লিখেন না)। ইওএফ পাঠাতে, সেই রিজার্ভ লেখককে দূরে সরিয়ে দিন।

mkfifo P
while sleep 1; do :; done >P &
P_writer_pid=$!
send_eof_to_P () {
  kill $P_writer_pid
}

0

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

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

অন্য বিকল্প:

( echo some stuff; cat more_stuff.txt ) >P

অথবা

{ echo some stuff; cat more_stuff.txt; } >P
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.