মধ্যে পার্থক্য কি <<
, <<<
এবং < <
ব্যাশ কি?
মধ্যে পার্থক্য কি <<
, <<<
এবং < <
ব্যাশ কি?
উত্তর:
এখানে দলিল
<<
here-document
কাঠামো হিসাবে পরিচিত । আপনি প্রোগ্রামটিকে শেষ পাঠ্যটি কী তা জানাতে পারবেন এবং যখনই এই ডিলিমিটারটি দেখা যাবে তখন প্রোগ্রামটি আপনার দেওয়া সমস্ত সামগ্রী প্রোগ্রামটিকে ইনপুট হিসাবে পড়বে এবং তার উপর একটি কার্য সম্পাদন করবে।
আমি যা বলতে চাইছি তা এখানে:
$ wc << EOF
> one two three
> four five
> EOF
2 5 24
এই উদাহরণে আমরা wc
প্রোগ্রামকে EOF
স্ট্রিংয়ের জন্য অপেক্ষা করতে বলি , তারপরে পাঁচটি শব্দ টাইপ করুন এবং তারপরে EOF
সিগন্যালটি টাইপ করুন যে আমরা ইনপুটটি দিয়েছি। বাস্তবে, এটি wc
নিজেই চালানো , কথায় টাইপ করা, আবার টিপানোর মতোCtrlD
ব্যাশে এগুলি টেম্প ফাইলগুলির মাধ্যমে সাধারণত ফর্মটিতে /tmp/sh-thd.<random string>
প্রয়োগ করা হয় , যখন ড্যাশগুলিতে এগুলি বেনামে পাইপ হিসাবে প্রয়োগ করা হয়। strace
কমান্ড সহ ট্রেসিং সিস্টেম কলগুলির মাধ্যমে এটি লক্ষ্য করা যায় । প্রতিস্থাপন bash
সঙ্গে sh
কিভাবে দেখতে /bin/sh
এই ফেরৎ সম্পাদন করে।
$ strace -e open,dup2,pipe,write -f bash -c 'cat <<EOF
> test
> EOF'
এখানে স্ট্রিং
<<<
হিসাবে পরিচিত হয় here-string
। পাঠ্যটিতে টাইপ করার পরিবর্তে আপনি কোনও প্রোগ্রামকে পাঠ্যের একটি প্রাক-তৈরি স্ট্রিং দেন। উদাহরণস্বরূপ, এই জাতীয় প্রোগ্রামের সাথে bc
আমরা bc <<< 5*4
কেবলমাত্র সেই নির্দিষ্ট ক্ষেত্রে আউটপুট পেতে পারি , বিসি ইন্টারেক্টিভভাবে চালানোর দরকার নেই।
এখানে ব্যাশের স্ট্রিংগুলি অস্থায়ী ফাইলগুলির মাধ্যমে সাধারণত ফর্ম্যাটটিতে প্রয়োগ করা হয় /tmp/sh-thd.<random string>
, যা পরে লিঙ্কযুক্ত হয়, ফলে তারা অস্থায়ীভাবে কিছু মেমরি স্থান দখল করে তবে /tmp
ডিরেক্টরি এন্ট্রিগুলির তালিকায় প্রদর্শিত হয় না এবং বেনামে ফাইল হিসাবে কার্যকরভাবে উপস্থিত থাকে, যা এখনও অবধি থাকতে পারে শেল নিজেই ফাইল ডেস্ক্রিপ্টারের মাধ্যমে উল্লেখ করা যেতে পারে এবং সেই ফাইল বিবরণকারীটি আদেশ দ্বারা উত্তরাধিকার সূত্রে প্রাপ্ত হয় এবং পরে dup2()
ফাংশনের মাধ্যমে ফাইল বর্ণনাকারী 0 (স্টিডিন) এ নকল হয় । এটি মাধ্যমে পর্যবেক্ষণ করা যেতে পারে
$ ls -l /proc/self/fd/ <<< "TEST"
total 0
lr-x------ 1 user1 user1 64 Aug 20 13:43 0 -> /tmp/sh-thd.761Lj9 (deleted)
lrwx------ 1 user1 user1 64 Aug 20 13:43 1 -> /dev/pts/4
lrwx------ 1 user1 user1 64 Aug 20 13:43 2 -> /dev/pts/4
lr-x------ 1 user1 user1 64 Aug 20 13:43 3 -> /proc/10068/fd
এবং ট্রেসিং সিস্কলগুলির মাধ্যমে (পাঠযোগ্যতার জন্য আউটপুট সংক্ষিপ্ত করে; লক্ষ্য করুন যে টেম্প ফাইলটি এফডি 3 হিসাবে কীভাবে খোলা হয়, এতে লেখা ডেটা, তারপরে এটি O_RDONLY
এফডি 4 হিসাবে এবং পুনরায় লিঙ্কযুক্ত পরে পুনরায় খোলা হয় dup2()
, যা cat
পরে উত্তরাধিকারসূত্রে প্রাপ্ত হয়) ):
$ strace -f -e open,read,write,dup2,unlink,execve bash -c 'cat <<< "TEST"'
execve("/bin/bash", ["bash", "-c", "cat <<< \"TEST\""], [/* 47 vars */]) = 0
...
strace: Process 10229 attached
[pid 10229] open("/tmp/sh-thd.uhpSrD", O_RDWR|O_CREAT|O_EXCL, 0600) = 3
[pid 10229] write(3, "TEST", 4) = 4
[pid 10229] write(3, "\n", 1) = 1
[pid 10229] open("/tmp/sh-thd.uhpSrD", O_RDONLY) = 4
[pid 10229] unlink("/tmp/sh-thd.uhpSrD") = 0
[pid 10229] dup2(4, 0) = 0
[pid 10229] execve("/bin/cat", ["cat"], [/* 47 vars */]) = 0
...
[pid 10229] read(0, "TEST\n", 131072) = 5
[pid 10229] write(1, "TEST\n", 5TEST
) = 5
[pid 10229] read(0, "", 131072) = 0
[pid 10229] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=10229, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
+++ exited with 0 +++
মতামত: সম্ভাব্য কারণ এখানে স্ট্রিংগুলি অস্থায়ী পাঠ্য ফাইলগুলি ব্যবহার করে, এটি সম্ভবত কারণ যা এখানে-স্ট্রিংগুলি সর্বদা একটি অনুবর্তনযোগ্য নিউলাইন সন্নিবেশ করায়, যেহেতু পসিক্স সংজ্ঞা দ্বারা টেক্সট ফাইলটিতে লাইন থাকতে হবে যা নিউলাইন অক্ষরে শেষ হয়।
প্রক্রিয়া প্রতিস্থাপন
Tldp.org যেমন ব্যাখ্যা করেছে,
প্রক্রিয়া প্রতিস্থাপন একটি প্রক্রিয়া (বা প্রসেস) এর আউটপুট অন্য প্রক্রিয়ার স্টিডিনে ফিড করে।
সুতরাং বাস্তবে এটি অন্য কমান্ডের স্টাইডআউটের পাইপিংয়ের অনুরূপ , যেমন echo foobar barfoo | wc
। তবে লক্ষ্য করুন: ব্যাশ ম্যানপেজে আপনি দেখতে পাবেন যে এটি হিসাবে চিহ্নিত হয়েছে <(list)
। সুতরাং মূলত আপনি একাধিক (!) কমান্ডের আউটপুট পুনর্নির্দেশ করতে পারেন।
দ্রষ্টব্য: প্রযুক্তিগতভাবে যখন আপনি বলেন যে < <
আপনি একটি জিনিস উল্লেখ করছেন না, তবে একক <
এবং দুটি আউটপুট পুনর্নির্দেশ প্রক্রিয়া পুনঃনির্দেশ সঙ্গে <( . . .)
।
এখন যদি আমরা কেবল বিকল্প প্রতিস্থাপন করি তবে কী হবে?
$ echo <(echo bar)
/dev/fd/63
যেমন আপনি দেখতে পাচ্ছেন, শেলটি অস্থায়ী ফাইল বিবরণী তৈরি করে /dev/fd/63
যেখানে আউটপুট যায় (যা গিলসের উত্তর অনুসারে , একটি অনামী পাইপ)। এর অর্থ <
সেই ফাইল বিবরণকারীকে একটি কমান্ডের ইনপুট হিসাবে পুনঃনির্দেশ করে।
খুব সহজ উদাহরণটি হ'ল দুটি ইকো কমান্ড থেকে ডাব্লিউসি তে আউটপুটটির প্রক্রিয়া প্রতিস্থাপন করা:
$ wc < <(echo bar;echo foo)
2 2 8
সুতরাং আমরা এখানে প্রথম বন্ধনীতে ঘটে যাওয়া সমস্ত আউটপুটের জন্য শেল একটি ফাইল বর্ণনাকারী তৈরি করব এবং এটিকে ইনপুট হিসাবে পুনঃনির্দেশিত করব wc
expected এবং যথাযথভাবে আমাদের কাছে 2 টি শব্দ, 2 লাইন এবং 6 টি অক্ষর এবং দুটি নতুনলাইন গণনা করা হয়েছে।
পার্শ্ব দ্রষ্টব্য: প্রক্রিয়া প্রতিস্থাপনকে বাশিজম হিসাবে উল্লেখ করা যেতে পারে (অগ্রণী শেলগুলির মতো কমান্ড বা কাঠামো যেমন পসিক্সbash
দ্বারা নির্দিষ্ট করা যায় না) তবে কেএস ম্যান পৃষ্ঠাksh
হিসাবে বাশের অস্তিত্বের আগে এটি প্রয়োগ করা হয়েছিল এবং এই উত্তরটি প্রস্তাব দেয়। শেলগুলি পছন্দ করে tcsh
এবং mksh
তবে প্রক্রিয়াটির বিকল্প নেই। সুতরাং আমরা কীভাবে প্রক্রিয়া প্রতিস্থাপন ছাড়াই একাধিক কমান্ডের একাধিক কমান্ডের আউটপুট পুনর্নির্দেশের কাছাকাছি যেতে পারি? গ্রুপিং প্লাস পাইপিং!
$ (echo foo;echo bar) | wc
2 2 8
কার্যকরভাবে এটি উপরের উদাহরণের মতো একই, তবে, প্রক্রিয়া প্রতিস্থাপন থেকে এটি হুডের নীচে পৃথক, যেহেতু আমরা wc
পাইপের সাথে সংযুক্ত পুরো সাবশেল এবং স্টিডিনকে স্টডআউট করি । অন্যদিকে, প্রক্রিয়া প্রতিস্থাপন একটি অস্থায়ী ফাইল বিবরণকারী পড়ার জন্য একটি কমান্ড তৈরি করে।
সুতরাং আমরা যদি পাইপিংয়ের সাথে গ্রুপিং করতে পারি তবে আমাদের কেন প্রক্রিয়া বিকল্পের দরকার হবে? কারণ অনেক সময় আমরা পাইপ ব্যবহার করতে পারি না। নীচের উদাহরণটি বিবেচনা করুন - দুটি কমান্ডের আউটপুটগুলির সাথে তুলনা করুন diff
(যার জন্য দুটি ফাইলের প্রয়োজন, এবং এই ক্ষেত্রে আমরা এটি দুটি ফাইল বর্ণনাকারী দিচ্ছি)
diff <(ls /bin) <(ls /usr/bin)
< <
যখন কোনও প্রক্রিয়া প্রতিস্থাপন থেকে স্টিডিন পাচ্ছেন তখন ব্যবহৃত হয় । যেমন একটি কমান্ড অনুযায়ী প্রদর্শিত হবে: cmd1 < <(cmd2)
। উদাহরণস্বরূপ,wc < <(date)
< <
প্রক্রিয়া প্রতিস্থাপনের ক্ষেত্রে এটি নিজেই কোনও জিনিস নয়, <
এরপরেই শুরু হয় অন্য কিছু যা শুরু হয়<
<<<
প্রথম প্ল্যান 9 আরসি শেলের ইউনিক্স বন্দর দ্বারা পরে zsh, বাশ এবং ksh93 দ্বারা গৃহীত হয়েছিল। আমি তখন একে বাশিজম বলব না।
echo 'foo' | read; echo ${REPLY}
আসবে নাfoo
, কারণ read
একটি সাব-শেল থেকে শুরু হয়েছে - পাইপিং একটি উপ-শেল শুরু করে। তবে, read < <(echo 'foo'); echo ${REPLY}
সঠিকভাবে ফিরে আসে foo
, কারণ কোনও সাব-শেল নেই।
< <
একটি সিনট্যাক্স ত্রুটি:
$ cat < <
bash: syntax error near unexpected token `<'
< <()
হয় প্রক্রিয়া প্রতিকল্পন ( <()
) (ফেরৎ সঙ্গে মিলিত <
):
একটি স্বীকৃত উদাহরণ:
$ wc -l < <(grep ntfs /etc/fstab)
4
$ wc -l <(grep ntfs /etc/fstab)
4 /dev/fd/63
প্রক্রিয়া প্রতিস্থাপনের সাথে, ফাইল বর্ণনাকারীর পথটি ফাইলের নামের মতো ব্যবহার করা হয়। আপনি যদি সরাসরি কোনও ফাইল নাম ব্যবহার করতে (বা না করতে) চান না তবে আপনি পুনঃনির্দেশের সাথে প্রক্রিয়া বিকল্পটিকে একত্রিত করবেন।
পরিষ্কার করে বলতে গেলে, কোনও < <
অপারেটর নেই।
<()
একটি ফাইল- নামের মতো জিনিস দেয়, তাই এটি আরও সাধারণভাবে কার্যকর - স্টিডিনটি < <()
প্রতিস্থাপন করছে যেখানে এটি প্রয়োজনীয় নাও হতে পারে। ইন wc
, দ্বিতীয়টি আরও কার্যকর হতে পারে। এটি অন্য কোথাও কম উপযোগী হতে পারে
< <
একটি সিনট্যাক্স ত্রুটি, সম্ভবত আপনি বোঝাতে পারেন command1 < <( command2 )
যা কোনও প্রক্রিয়া প্রতিস্থাপনের পরে একটি সাধারণ ইনপুট পুনঃনির্দেশ এবং খুব অনুরূপ তবে এর সমতুল্য নয়:
command2 | command1
আপনি যে চালনা bash
করছেন command1
তা ধরে নিয়ে পার্থক্যটি প্রথম ক্ষেত্রে বর্তমান শেলটিতে চালিত হওয়ার পরে দ্বিতীয় ক্ষেত্রে একটি সাবশেলে চালানো হয়। তার মানে সেট করা ভেরিয়েবলগুলি command1
প্রক্রিয়া প্রতিস্থাপনের বৈকল্পিকের সাথে হারাবে না।
< <
একটি সিনট্যাক্স ত্রুটি দেবে। যথাযথ ব্যবহার নিম্নরূপ:
উদাহরণগুলির সাহায্যে ব্যাখ্যা:
উদাহরণস্বরূপ < <()
:
while read line;do
echo $line
done< <(ls)
উপরের উদাহরণে, while লুপের ইনপুটটি ls
কমান্ড থেকে আসবে যা echo
লুপে রেখা এবং এড দ্বারা পঠনযোগ্য ।
<()
প্রক্রিয়া বিকল্পের জন্য ব্যবহৃত হয়। আরও তথ্য এবং উদাহরণ <()
এই লিঙ্কে পাওয়া যাবে: