সমাপ্ত সাবকম্যান্ডে পাইপিংয়ের সময় লুপ প্রস্থানকালে কোনও বাশ কেন হয় না?


12

নীচের কমান্ডটি প্রস্থান করে না কেন? প্রস্থান করার পরিবর্তে লুপটি অনির্দিষ্টকালের জন্য চলে।

আমি আরও জটিল সেটআপ ব্যবহার করে এই আচরণটি আবিষ্কার করার সময়, কমান্ডের সর্বাধিকতম রূপটি নিম্নলিখিতটিতে হ্রাস করে।

প্রস্থান করে না:

while /usr/bin/true ; do echo "ok" | cat ; done | exit 1

উপরে কোনও টাইপস নেই। প্রতিটি '|' একটি পাইপ 'প্রস্থান 1' এর মধ্যে দৌড়ে আসা এবং প্রস্থান হওয়া অন্য একটি প্রক্রিয়া দাঁড়ায়।

আমি প্রত্যাশা করি "প্রস্থান 1" এর সময় লুপটিতে (কোনও পাঠকবিহীন পাইপে লিখুন) এবং লুপটি ভেঙে যাওয়ার জন্য একটি সাইনপাইপ সৃষ্টি করবে। তবে, লুপটি চলতে থাকে।

কমান্ড থামছে না কেন?


zsh সাধারণত প্রস্থান করে।
ব্রিয়াম

উত্তর:


13

এটি বাস্তবায়নের পছন্দের কারণে।

সোলারিসে একই স্ক্রিপ্ট চালানো ksh93অন্যরকম আচরণের জন্ম দেয়:

$ while /usr/bin/true ; do echo "ok" | cat ; done | exit 1
cat: write error [Broken pipe]

যে বিষয়টি ইস্যুটি দেয় তা হ'ল অভ্যন্তরীণ পাইপলাইন, এটি ছাড়া লুপটি শেল / ওএস যাই হোক না কেন থেকে প্রস্থান করে:

$ while /usr/bin/true ; do echo "ok" ; done | exit 1
$

cat বাশের অধীনে একটি সিগপাইপ সিগন্যাল পাচ্ছে তবে শেলটি যেভাবেই লুপটিকে পুনরাবৃত্তি করছে।

Process 5659 suspended
[pid 28801] execve("/bin/cat", ["cat"], [/* 63 vars */]) = 0
[pid 28801] --- SIGPIPE (Broken pipe) @ 0 (0) ---
Process 5659 resumed
Process 28801 detached
Process 28800 detached
--- SIGCHLD (Child exited) @ 0 (0) ---
Process 28802 attached
Process 28803 attached
[pid 28803] execve("/bin/cat", ["cat"], [/* 63 vars */]) = 0
Process 5659 suspended
[pid 28803] --- SIGPIPE (Broken pipe) @ 0 (0) ---
Process 5659 resumed
Process 28803 detached
Process 28802 detached
--- SIGCHLD (Child exited) @ 0 (0) ---
Process 28804 attached
Process 28805 attached (waiting for parent)
Process 28805 resumed (parent 5659 ready)
Process 5659 suspended
[pid 28805] execve("/bin/cat", ["cat"], [/* 63 vars */]) = 0
[pid 28805] --- SIGPIPE (Broken pipe) @ 0 (0) ---
Process 5659 resumed
Process 28805 detached
Process 28804 detached
--- SIGCHLD (Child exited) @ 0 (0) ---

বাশ ডকুমেন্টেশনে বলা হয়েছে:

শেলটি কোনও মান ফেরত দেওয়ার আগে পাইপলাইনে সমস্ত কমান্ডের সমাপ্তির জন্য অপেক্ষা করে

Ksh ডকুমেন্টেশন বলে:

সম্ভবত সর্বশেষটি ব্যতীত প্রতিটি কমান্ড পৃথক প্রক্রিয়া হিসাবে চালিত হয়; শেলটি শেষ কমান্ডটির সমাপ্তির জন্য অপেক্ষা করে

পসিক্স জানিয়েছে:

পাইপলাইনটি ব্যাকগ্রাউন্ডে না থাকলে (অ্যাসিনক্রোনাস তালিকাগুলি দেখুন), শেলটি পাইপলাইনে বর্ণিত শেষ কমান্ডটি সম্পূর্ণ হওয়ার জন্য অপেক্ষা করবে এবং সমস্ত কমান্ড সম্পূর্ণ হওয়ার জন্যও অপেক্ষা করতে পারে


আমার মনে হয় এটা ঠিক ভেতরের পাইপলাইন না যে ট্রিগার ইস্যু, এটা যে builtin echoউপেক্ষা SIGPIPE। env echoপরিবর্তে echo(প্রকৃত echoবাইনারিটি ব্যবহার করতে বাধ্য করার জন্য) ব্যবহার করে আপনি সমস্যাটি পুনরুত্পাদন করতে পারেন । (এছাড়াও আউটপুট তুলনা করুন { echo hi; echo $? >&2; } | exit 1এবং { env echo hi; echo $? >&2; } | exit 1।)
লুকাস Werkmeister

1

এই সমস্যাটি আমাকে বছরের পর বছর ধরে আটকে রেখেছে। জিলিয়াগ্র্রেকে সঠিক দিকের ধাক্কা দেওয়ার জন্য ধন্যবাদ।

আমার লিনাক্স বাক্সে, প্রশ্নটি কিছুটা পুনরুদ্ধার করা হচ্ছে, এটি প্রত্যাশার সাথে প্রস্থান করে:

while true ; do echo "ok"; done | head

কিন্তু আমি যদি একটি নল যোগ করুন, এটা নেই না প্রস্থান আশানুরূপ:

while true ; do echo "ok" | cat; done | head

যা আমাকে বছরের পর বছর হতাশ করেছিল। জিলিয়াগ্র্রে লেখা উত্তর বিবেচনা করে, আমি এই দুর্দান্ত সমাধানটি নিয়ে এসেছি:

while true ; do echo "ok" | cat || exit; done | head

কিয়েড ...

ভাল, বেশ না। এখানে কিছুটা জটিল জটিল:

i=0
while true; do
    i=`expr $i + 1`
    echo "$i" | grep '0$' || exit
done | head

এটি ঠিক কাজ করে না। আমি এটি যোগ করেছি || exitতাই এটি কীভাবে তাড়াতাড়ি শেষ করতে হয় তা জানে তবে খুব প্রথমটির echoসাথে এটি মেলে না grepতাই লুপটি অবিলম্বে সরে যায়। এই ক্ষেত্রে, আপনি সত্যিই এর প্রস্থান স্থিতিতে আগ্রহী নন grep। আমার কাজের চারপাশে অন্য একটি যোগ করা হয় cat। সুতরাং, এখানে "দশক" নামে একটি স্বীকৃত স্ক্রিপ্ট রয়েছে:

#!/bin/bash
i=0
while true; do
    i=`expr $i + 1`
    echo "$i" | grep '0$' | cat || exit
done

চলার সময় এটি যথাযথভাবে শেষ হয় tens | head। সৃষ্টিকর্তাকে ধন্যবাদ.

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.