পাইপ এবং এখানে স্ট্রিং ব্যবহার করে রিসোর্স ব্যবহার


16

নিম্নলিখিত দুটি ব্যবহার করে আমরা একই ফলাফল পেতে পারি bash,

echo 'foo' | cat

এবং

cat <<< 'foo'

আমার প্রশ্নটি ব্যবহৃত সম্পদগুলির হিসাবে এই দুটিয়ের মধ্যে পার্থক্য কী এবং কোনটি আরও ভাল?

আমার ধারণা হ'ল পাইপ ব্যবহার করার সময় আমরা একটি অতিরিক্ত প্রক্রিয়া echoএবং পাইপ ব্যবহার করছি যখন এখানে স্ট্রিংয়ের সাথে কেবল একটি ফাইল বর্ণনাকারী ব্যবহার করা হচ্ছে cat

উত্তর:


17

পাইপ হ'ল একটি ফাইল যা ইন-কার্নেল ফাইল-সিস্টেমে খোলা থাকে এবং অন-ডিস্কে নিয়মিত ফাইল হিসাবে অ্যাক্সেসযোগ্য হয় না। এটি স্বয়ংক্রিয়ভাবে কেবলমাত্র একটি নির্দিষ্ট আকারে বাফার হয় এবং পরিপূর্ণরূপে অবরুদ্ধ হবে। ব্লক-ডিভাইসগুলিতে উত্সযুক্ত ফাইলগুলির বিপরীতে পাইপগুলি চরিত্রের ডিভাইসের মতো আচরণ করে এবং তাই সাধারণত সমর্থন করে না lseek()এবং সেগুলি থেকে পড়া ডেটা আবার পড়তে পারে না কারণ আপনি নিয়মিত ফাইলটি করতে পারেন।

এখানে স্ট্রিংটি একটি নিয়মিত ফাইল যা মাউন্ট করা ফাইল-সিস্টেমে তৈরি হয়। শেলটি ফাইলটি তৈরি করে এবং তার বর্ণনাকারীটিকে ধরে রাখে যখন তত্ক্ষণাত্ এটির কেবল ফাইল-সিস্টেমের লিঙ্কটি মুছে ফেলা হয় (এবং তাই এটি মুছে ফেলা হয়) এটি ফাইলের / থেকে বাইট লেখার আগে / পড়ার আগে। কার্নেল সমস্ত প্রক্রিয়া এর জন্য সমস্ত বর্ণনাকারী প্রকাশ না করা পর্যন্ত ফাইলের জন্য প্রয়োজনীয় স্থানটি বজায় রাখবে। যদি এই জাতীয় বর্ণনাকারী থেকে পড়া শিশুটির এমনটি করার ক্ষমতা থাকে তবে এটিকে lseek()আবার ঘেঁটে আবার পড়া যায়।

উভয় ক্ষেত্রেই টোকেন রয়েছে <<<এবং |ফাইল-বর্ণনাকারীদের উপস্থাপন করে এবং অগত্যা ফাইলগুলি নিজেরাই করে না। আপনি এই জাতীয় জিনিসগুলি করে কী চলছে তার একটি ভাল ধারণা পেতে পারেন:

readlink /dev/fd/1 | cat

... অথবা ...

ls -l <<<'' /dev/fd/*

দুটি ফাইলের মধ্যে সর্বাধিক উল্লেখযোগ্য পার্থক্য হ'ল এখানে-স্ট্রিং / ডকটি বেশ একবারে-একবারে সম্পর্কযুক্ত - শেলটি শিশুর কাছে পড়ার বিবরণ দেওয়ার আগে সমস্ত তথ্য এতে লিখে দেয়। অন্যদিকে, শেলটি উপযুক্ত বর্ণনাকারীদের উপর পাইপটি খোলায় এবং পাইপগুলি পরিচালনা করার জন্য বাচ্চাদের কাঁটাচামচ করে দেয় - এবং তাই এটি উভয় প্রান্তে একযোগে লেখা / পড়া হয়।

এই প্রভেদ, যদিও, শুধুমাত্র সাধারণত সত্য। যতদূর আমি সচেতন (যা আসলে এতটা দূরের নয়) এটি প্রতিটি শেলের ক্ষেত্রে সত্য যা একক ব্যতিক্রমের সাথে এখানে ডকুমেন্টের পুনঃনির্দেশের <<<জন্য <<এখানে স্ট্রিংয়ের শর্ট হ্যান্ড পরিচালনা করে yashyash, busybox, dash, এবং অন্যান্য ashরূপগুলো পাইপ দিয়ে করার জন্য এখানে-দস্তাবেজ, যদিও, এবং তাই ঐ শাঁস সেখানে সত্যিই সব পরে দুজনের মধ্যে খুব সামান্য পার্থক্য আছে ঝোঁক না।

ঠিক আছে - দুটি ব্যতিক্রম। এখন যেহেতু আমি এটি সম্পর্কে চিন্তা করছি, ksh93আসলে কোনও পাইপই করি না |, বরং পুরো ব্যবসায় ডাব্লু / সকেটগুলি পরিচালনা করে - যদিও এটি <<<*অন্যদের মতো মুছে ফেলা টিএমপি ফাইলটি করে । আরও কী, এটি কেবল সাব-শেল পরিবেশে পাইপলাইনের পৃথক বিভাগ রাখে যা কমপক্ষে এটি সাবসেলের মতো কাজ করে এবং এটি কাঁটাচামচ করে না এমন একটি ধরণের পসিক্স উচ্চারণের ধরণ

আসল বিষয়টি হ'ল @ পিএসকোকিকের বেঞ্চমার্ক (যা খুব দরকারী) ফলাফলগুলি বিভিন্ন কারণে ব্যাপকভাবে পরিবর্তিত হতে পারে এবং এর বেশিরভাগই বাস্তবায়ন নির্ভর। এখানে-দলিল সেটআপের জন্য সবচেয়ে বড় কারণগুলি ${TMPDIR}হ'ল টার্গেট ফাইল-সিস্টেমের ধরণ এবং বর্তমান ক্যাশে কনফিগারেশন / উপলভ্যতা এবং তারপরেও আরও কত পরিমাণে ডেটা লিখতে হবে। পাইপের জন্য এটি নিজেই শেল প্রক্রিয়াটির আকার হবে কারণ প্রয়োজনীয় কাঁটাচামচগুলির জন্য অনুলিপি তৈরি করা হয়। এই পথ bashহল ভয়ানক পাইপলাইন সেটআপ এ (অন্তর্ভুক্ত করা $(কমান্ড )বদল) - কারণ এটা বড় এবং খুব ধীর, কিন্তু সঙ্গে ksh93এটা সব সময়ে কমই কোনো পার্থক্য তোলে।

শেল কীভাবে পাইপলাইনের জন্য সাবশেলগুলি বিভক্ত করে তা দেখানোর জন্য এখানে আরও একটি ছোট শেল স্নিপেট রয়েছে:

pipe_who(){ echo "$$"; sh -c 'echo "$PPID"'; }
pipe_who
pipe_who | { pipe_who | cat /dev/fd/3 -; } 3<&0

32059  #bash's pid
32059  #sh's ppid
32059  #1st subshell's $$
32111  #1st subshell sh's ppid
32059  #2cd subshell's $$
32114  #2cd subshell sh's ppid

পাইপযুক্ত pipe_who()কল কল এবং বর্তমান শেলটিতে একটি রান করার রিপোর্টের মধ্যে পার্থক্য হ'ল এটি প্রসারিত হওয়ার পরে পিতামাতার শেলের (পিড )দাবি করার সাবস্কেলের নির্দিষ্ট আচরণের কারণে $$। যদিও bashসাবশেলগুলি অবশ্যই পৃথক প্রক্রিয়া, $$বিশেষ শেল প্যারামিটার এই তথ্যের একটি নির্ভরযোগ্য উত্স নয়। তবুও সাবসেলের শিশু shশেলটি সঠিকভাবে এটি জানাতে অস্বীকার করে না $PPID


খুব উপকারী. ইন-কার্নেল ফাইল সিস্টেম, এর কোনও নাম আছে? এর অর্থ কি এটি কার্নেল স্পেসে বিদ্যমান?
utlamn

2
@ ইউট্লামন - আসলে, হ্যাঁ - কেবল পাইপগুলি । কিন্তু - এটা সব ইন-কার্নেলের (ফিউজ মত সরাইয়া কাপড় থেকে) তাই সব ফাইল I / O
মাইকজার্ভ

10

বেঞ্চমার্কিংয়ের বিকল্প নেই:

pskocik@ProBook:~ 
$ time (for((i=0;i<1000;i++)); do cat<<< foo >/dev/null; done  )

real    0m2.080s
user    0m0.738s
sys 0m1.439s
pskocik@ProBook:~ 
$ time (for((i=0;i<1000;i++)); do echo foo |cat >/dev/null; done  )

real    0m4.432s
user    0m2.095s
sys 0m3.927s
$ time (for((i=0;i<1000;i++)); do cat <(echo foo) >/dev/null; done  )
real    0m3.380s
user    0m1.121s
sys 0m3.423s

এবং একটি বৃহত পরিমাণে ডেটার জন্য:

TENMEG=$(ruby -e 'puts "A"*(10*1024*1024)')
pskocik@ProBook:~ 
$ time (for((i=0;i<100;i++)); do echo "$TENMEG" |cat >/dev/null; done  )

real    0m42.327s
user    0m38.591s
sys 0m4.226s
pskocik@ProBook:~ 
$ time (for((i=0;i<100;i++)); do cat<<< "$TENMEG" >/dev/null; done  )

real    1m26.946s
user    1m23.116s
sys 0m3.681s
pskocik@ProBook:~ 

$ time (for((i=0;i<100;i++)); do cat <(echo "$TENMEG") >/dev/null; done  )

real    0m43.910s
user    0m40.178s
sys 0m4.119s

এটি প্রদর্শিত হবে পাইপ সংস্করণে একটি বৃহত্তর সেটআপ ব্যয় রয়েছে তবে শেষ পর্যন্ত এটি আরও দক্ষ।


পছন্দ করেছেন আমি প্রচুর পরিমাণে ডেটা সহ একটি বেঞ্চমার্ক যুক্ত করেছি।
পিএসকোকিক

2
echo foo >/dev/shm/1;cat /dev/shm/1 >/dev/nullউভয় ক্ষেত্রেই দ্রুত বলে মনে হয়েছিল ...
ব্যবহারকারীর 3030

@ user23013 এটি উপলব্ধি করে। আমি দেখতে পাচ্ছি না কেন হয় echo "$longstring"বা <<<"$longstring"দক্ষতার জন্য এবং সংক্ষিপ্ত স্ট্রিংগুলির সাথে টুইঙ্ক করা হবে, দক্ষতা যাই হোক না কেন তেমন গুরুত্ব দেয় না।
পিএসকোকিক

এটি আকর্ষণীয় যে আমার ক্ষেত্রে (উবুন্টু 14.04 এ, ইনটেল কোয়াড কোর আই 7) এর cat <(echo foo) >/dev/nullচেয়ে দ্রুত echo foo | cat >/dev/null
পাবউক

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