বাশ: প্রক্রিয়া প্রতিস্থাপন এবং স্টাডিন


13

নিম্নলিখিত লাইনটি সুস্পষ্ট:

echo "bla" | foo | bar

কিন্তু নীচের লোকেরা কি একই কাজ করে?

echo "bla" | bar <(foo)
echo "bla" | bar < <(foo)

কোনটি fooএবং barstdin এবং কেন থেকে "bla" পড়া?

আমি বলতে চাইছি, অবশ্যই, আমি কেবল এটি কোড করতে এবং এটি পরীক্ষা করতে পারি, তবে আমি নিশ্চিত নই যে এটি নির্ধারিত আচরণ কিনা বা আমি যে বৈশিষ্ট্যগুলি ব্যবহার করছি তার উপর নির্ভর করা উচিত নয়।

উত্তর:


9

এটি শেল নির্ভর এবং নথিভুক্ত নয় এএএএফসিএস। ইন kshএবং bash, প্রথম ক্ষেত্রে, fooহিসাবে একই stdin ভাগ করবে bar। তারা আউটপুট জন্য লড়াই করবে echo

সুতরাং উদাহরণস্বরূপ,

$ seq 10000 | paste - <(tr 1 X)'
1       X
2       X042
3       X043
4       X044
5       X045
[...]

আপনি প্রমাণগুলি দেখতে পান যা pasteপাঠ্যের প্রতিটি ব্লককে seqআউটপুট থেকে অন্য পাঠ করে trreads

এর সাহায্যে zshএটি বাহ্যিক স্টিডিন পায় (যদি এটি টার্মিনাল না হয় এবং শেলটি ইন্টারেক্টিভ না হয় তবে এটির থেকে পুনঃনির্দেশিত হয় /dev/null)। ksh(যেখানে এটি উদ্ভূত হয়েছিল), zshএবং bashপ্রক্রিয়া প্রতিস্থাপন AFAIK এর সমর্থন সহ একমাত্র বোর্নের মতো শেল।

ইন echo "bla" | bar < <(foo), নোট করুন যে barএর স্টিডিন হ'ল পাইপ হবে আউটপুট দ্বারা খাওয়ানো foo। এটি ভালভাবে সংজ্ঞায়িত আচরণ। সেক্ষেত্রে, এটা মনে হয় যে fooএর stdin নল দ্বারা খাওয়ানো হয় echoসব ksh, zshএবং bash

যদি আপনি তিনটি শাঁস জুড়ে সামঞ্জস্যপূর্ণ আচরণ করতে চান এবং ভবিষ্যত-প্রমাণ হতে চান যেহেতু নথিবদ্ধ না হওয়ায় আচরণটি পরিবর্তিত হতে পারে, তবে আমি এটি লিখব:

echo bla | { bar <(foo); }

নিশ্চিত হওয়ার জন্য যে fooস্টিডিন হ'ল পাইপও echo(আমি দেখতে পাচ্ছি না কেন আপনি এটি করতে চাইছেন)। বা:

echo bla | bar <(foo < /dev/null)

পাইপ থেকে পড়া নাfoo হয় তা নিশ্চিত করার জন্য echo। বা:

{ echo bla | bar 3<&- <(foo <&3); } 3<&0

আছে foo'বর্তমান সংস্করণে মত বাইরের stdin stdin গুলি zsh


"সেক্ষেত্রে, ফু এর স্টিডিন হ'ল পিএসপি, কেএসএস, জেডএস এবং বাশ সবই প্রতিধ্বনিত। আপনি এখনই হাত দ্বারা এটি পরীক্ষা করেছেন, বা এটি কোথাও নথিভুক্ত করা হয়েছে?
etam1024

"প্রথম ক্ষেত্রে" কি প্রথম লাইনে `| বোঝায়? foo | বারে বা `| বার <(foo)?
ভোলকার সিগেল

4

echo "bla" | foo | bar: যার আউটপুট echo "bla"পুনঃনির্দেশিত হয় foo, যার আউটপুট পুনঃনির্দেশিত bar

echo "bla" | bar <(foo): তা এক পাইপ আউটপুট echo "bla"করতে bar। কিন্তু barএকটি যুক্তি দিয়ে মৃত্যুদন্ড কার্যকর করা হয়। যুক্তি হ'ল ফাইল ডিজিকারের পথ, যেখানে আউটপুট fooপ্রেরণ করা হবে। এই যুক্তি একটি ফাইলের মতো আচরণ করে যা এর আউটপুট ধারণ করে foo। সুতরাং, এটি একই নয়।

echo "bla" | bar < <(foo): কেউ অনুমান করতে পারে যে এর আউটপুট echo "bla"প্রেরণ করা উচিত barএবং পুরো বিবৃতিটি প্রথমটির সমতুল্য। তবে, এটি সঠিক নয়। নিম্নলিখিতটি ঘটে: পাইপ ( ) এর পরে ইনপুট পুনঃনির্দেশ <সঞ্চালিত হওয়ার কারণে |এটি ওভাররাইট করে । তাই echo "bla"বারে পাইপ করা হয় না। পরিবর্তে এর আউটপুটটি fooস্ট্যান্ডার্ড ইনপুট হিসাবে পুনঃনির্দেশিত হয় bar। এটি পরিষ্কার করতে নিম্নলিখিত কমান্ড এবং আউটপুট দেখুন:

$ echo "bla" | cat < <(echo "foo")
foo

যেমন আপনি দেখতে echo "bla"পরাস্ত করা হয় echo "foo"

এখন এই আদেশ দেখুন:

$ echo "bar" | cat < <(awk '{printf "%s and foo", $0}')
bar and foo

সুতরাং echo "bar"পাইপ করা হয় awk, যা স্টিডিন পড়ে এবং and fooআউটপুটটিতে স্ট্রিং যুক্ত করে । এই আউটপুট পাইপ করা হয় cat


এবং আমার প্রশ্ন: " awk" বার "পড়ার বিষয়টি কি একটি সংজ্ঞায়িত আচরণ?"
etam1024

হ্যাঁ, তাই cmd1 < <(cmd2)হিসাবে একই আচরণ করে cmd2 | cmd1
বিশৃঙ্খলা

বা cmd1 | cmd2 | cmd3এর মতোইcmd1 | cmd3 < <(cmd2)
বিশৃঙ্খলা

3
এটি যদি উইকিপিডিয়া হত তবে আমি আপনার বিবৃতিতে "উদ্ধৃতি আবশ্যক" ট্যাগটি রেখেছিলাম :) আমার প্রশ্নের পুরো বিষয়টি হ'ল এটি আপনার কাজ হিসাবে কাজ করে, তবে আমি এটি সম্পর্কে কোনও দলিল খুঁজে পাইনি।
etam1024
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.