কিছু আদেশগুলি তাদের স্ট্যান্ডার্ড ইনপুট থেকে কেন পড়ে না?


19

আমি ভাবছি কখন আমাদের পাইপলাইন ব্যবহার করা উচিত এবং কখন আমাদের করা উচিত নয়।

উদাহরণস্বরূপ বলুন, পিডিএফ ফাইলগুলি পরিচালনা করে এমন নির্দিষ্ট প্রক্রিয়াটি মেরে ফেলতে নীচেরগুলি পাইপলাইন ব্যবহার করে কাজ করবে না:

ps aux | grep pdf | awk '{print $2}'|kill

পরিবর্তে, আমরা কেবল নিম্নলিখিত উপায়গুলি সহ এটি করতে পারি:

kill $(ps aux| grep pdf| awk '{print $2}')

অথবা

ps aux | grep pdf | awk '{print $2}'| xargs kill

man bash(সংস্করণ 4.1.2) অনুসারে :

The standard output of command is connected via a pipe to the standard input of command2.

উপরের দৃশ্যের জন্য:

  • এর স্টিন grepস্ট্যান্ডআউট ps। ওই কাজগুলো.
  • এর স্টিন awkস্ট্যান্ডআউট grep। ওই কাজগুলো.
  • এর স্টিন killস্ট্যান্ডআউট awk। যে কাজ করে না।

নিম্নলিখিত কমান্ডের stdout থেকে সর্বদা নীচের কমান্ডের স্টিডিন ইনপুট পাচ্ছে।

  • এটি কেন killবা সাথে কাজ করে না rm?
  • মধ্যে পার্থক্য কি kill, rmইনপুট grep, awkইনপুট?
  • কোন নিয়ম আছে?

1
এটি একটি উত্তর না কিন্তু আপনি কটাক্ষপাত আছে চাইবেন pgrep, pkillএবং killallকমান্ড।
টেরডন

2
@ এটারডন: পাইপলাইন ইস্যুটি দেখানোর জন্য আমি কেবল উপরের দৃশ্যের ব্যবহার করছি, আমি বুঝতে পেরেছি pgrepএবং বাকিরা এটি পুরোপুরি অর্জন করতে পারে :)
সাইলি

উত্তর:


17

প্রোগ্রামগুলিতে ইনপুট সরবরাহের দুটি সাধারণ উপায় রয়েছে:

  • প্রক্রিয়াগুলির STDIN এ ডেটা সরবরাহ করুন
  • কমান্ড লাইন আর্গুমেন্ট নির্দিষ্ট করুন

killকেবল কমান্ড লাইন আর্গুমেন্ট ব্যবহার করে। এটি STDIN থেকে পড়ে না। STDIN এর মতো প্রোগ্রামগুলি grepএবং awkপড়তে (যদি কোনও ফাইলের নাম কমান্ড লাইন আর্গুমেন্ট হিসাবে দেওয়া না হয়) এবং তাদের কমান্ড লাইন আর্গুমেন্ট (প্যাটার্ন, বিবৃতি, পতাকা, ...) অনুসারে ডেটা প্রক্রিয়া করে।

আপনি কেবলমাত্র অন্যান্য প্রক্রিয়াগুলির STDIN এ পাইপ করতে পারেন, লাইন আর্গুমেন্টকে কমান্ড না দিয়ে।

সাধারণ নিয়মটি হ'ল, প্রোগ্রামগুলি নির্বিচার পরিমাণে ডেটা প্রক্রিয়া করতে STDIN ব্যবহার করে। সমস্ত অতিরিক্ত ইনপুট পরামিতি বা, সাধারণত খুব কম কিছু থাকলে কমান্ড লাইন আর্গুমেন্ট দ্বারা পাস করা হয়। যদি কমান্ড লাইনটি খুব দীর্ঘ পেতে পারে, উদাহরণস্বরূপ দীর্ঘ awkপ্রোগ্রাম পাঠ্যের জন্য, অতিরিক্ত প্রোগ্রাম ফাইলগুলি ( -fবিকল্প awk) থেকে এটি পড়ার সম্ভাবনা প্রায়শই থাকে ।

কমান্ড লাইন আর্গুমেন্ট হিসাবে প্রোগ্রামগুলির STDOUT ব্যবহার করতে $(...), প্রচুর ডেটা ব্যবহার করুন বা ক্ষেত্রে xargsfindএটি সরাসরি সাথেও করতে পারে -exec ... {} +

সম্পূর্ণতার জন্য: STDOUT এ কমান্ড লাইন আর্গুমেন্ট লিখতে, ব্যবহার করুন echo


1
আমরা কীভাবে জানব যে কোনও আদেশ কেবল STDIN না নিয়ে যুক্তি নেবে? ম্যান পৃষ্ঠা থেকে অনুমান করা বা পড়ার চেয়ে কি কোনও নিয়মতান্ত্রিক বা প্রোগ্রামিক উপায় আছে? কেবল ম্যান পেজটি পড়ে, কমান্ডটি এসটিডিইন গ্রহণ করতে পারে বা নিতে পারে না সে সম্পর্কে দৃ specific় হওয়ার জন্য আমি কোনও নির্দিষ্ট চিহ্ন পেতে পারি নি, কারণ এসটিডিইএনও কোনও পুরুষ পৃষ্ঠা উপস্থিত হওয়ার দিক থেকে যুক্তিগুলির একটি অংশ। উদাহরণস্বরূপ, gzipSYNOPSIS এ, এটি ইনপুট হিসাবে কোনও ফাইল ফাইল নিতে হবে তা বলেনি। আমি এটি নির্ধারণ করার জন্য আরও নিয়মতান্ত্রিক উপায় দেখছি।
sylye

কিছু কমান্ডের জন্য "-" যুক্তি যার অর্থ "স্টিডিন" (বা "স্টডআউট") রয়েছে।
এমানুয়েল

xargsআপনাকে "পাইপ টু কমান্ড লাইন আর্গুমেন্ট" অবিকল অনুমতি দেবে না ?
টি ভেরন

@ টি.ভেরন হ্যাঁ, এটি হ'ল কাজ xargs। এটি একাধিকবার প্রয়োজন হলে কমান্ডকে কল করে (কমান্ড লাইনের আকার সীমিত) এবং প্রচুর অন্যান্য বিকল্প রয়েছে।
জোফেল

2
আপনি প্রোগ্রামটি কীভাবে ব্যবহার করতে পারবেন তা বর্ণনার টেক্সটটিতে বর্ণিত হবে। উদাহরণস্বরূপ, জিজিপ বলেছে: "জিজিপ প্রোগ্রাম লেম্পেল-জিভ কোডিং (এলজেড 77)) ব্যবহার করে ফাইলগুলি সংকুচিত করে এবং ডিকম্প্রেস করে। যদি কোনও ম্যান পেজ স্ট্যান্ডার্ড ইনপুট উল্লেখ না করে তবে এটি এটি ব্যবহার করবে না।
অ্যালান শুটকো

16

এটি একটি আকর্ষণীয় প্রশ্ন এবং এটি ইউনিক্স / লিনাক্স দর্শনের একটি অংশ নিয়ে কাজ করে।

সুতরাং, মত প্রোগ্রামের মধ্যে পার্থক্য কি grep, sed, sortএকদিকে এবং kill, rm, lsঅন্যদিকে? আমি দুটি দিক দেখতে পাচ্ছি।

ফিল্টার দৃষ্টিভঙ্গি

  • প্রথম ধরণের প্রোগ্রামগুলিকে ফিল্টারও বলা হয় । তারা কোনও ফাইল থেকে বা এসটিডিআইএন থেকে ইনপুট নেয়, এটিকে পরিবর্তন করে এবং বেশিরভাগ এসটিডিআউট থেকে কিছু আউটপুট উত্পন্ন করে। এগুলি উত্স এবং গন্তব্য হিসাবে অন্য প্রোগ্রামগুলির সাথে একটি পাইপে ব্যবহৃত হতে বোঝানো হয়।

  • দ্বিতীয় ধরণের প্রোগ্রামগুলি একটি ইনপুটটিতে কাজ করে তবে তারা যে আউটপুট দেয় তা প্রায়শই ইনপুটটির সাথে সম্পর্কিত হয় না। killএটি নিয়মিত কাজ করলে কোনও আউটপুট থাকে না, হয় না ls। সাফল্য দেখানোর জন্য স্রেফ একটি রিটার্ন মান রয়েছে। তারা সাধারণত STDIN থেকে ইনপুট নেয় না, তবে বেশিরভাগই STDOUT এ আউটপুট দেয়।

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

শব্দার্থিক দৃষ্টিভঙ্গি

  • ফিল্টারগুলির জন্য, তাদের ইনপুটটির কোনও অর্থগত অর্থ নেই । তারা কেবল ডেটা পড়ে, ডেটা পরিবর্তন করে, আউটপুট ডেটা। এটি সাংখ্যিক মান, কিছু ফাইলের নাম বা এইচটিএমএল উত্স কোডের তালিকা কিনা তা বিবেচ্য নয়। এই ডেটাটির অর্থ কেবলমাত্র আপনি ফিল্টারটি সরবরাহ করেনি কোড দ্বারা দেওয়া হয় : এর জন্য রেজেক্স grep, নিয়মের জন্য awkবা পার্ল প্রোগ্রাম।

  • অন্যান্য প্রোগ্রামগুলির জন্য, যেমন killবা ls, তাদের ইনপুটটির একটি অর্থ রয়েছে , একটি বর্ণচিহ্নkillপ্রক্রিয়া নম্বর প্রত্যাশা করে, lsফাইল বা পথের নাম প্রত্যাশা করে। তারা যথেচ্ছ ডেটা পরিচালনা করতে পারে না এবং সেগুলি বোঝায় না। তাদের অনেকের মতো কোনও ইনপুট বা প্যারামিটারের প্রয়োজন হয় না ps। এগুলি সাধারণত STDIN থেকে পড়ে না।

একটি সম্ভবত এই দুটি দিক একত্রিত করতে পারে: একটি ফিল্টার এমন একটি প্রোগ্রাম যা এর ইনপুটটির প্রোগ্রামটির অর্থগত অর্থ হয় না।

আমি নিশ্চিত যে আমি এই দর্শনটি কোথাও পড়েছি তবে দুঃখিত, এই মুহূর্তে কোনও উত্স মনে নেই remember কারও কাছে যদি কিছু উত্স উপস্থিত থাকে তবে দয়া করে বিনা দ্বিধায় সম্পাদনা করুন।


5

এর মতো কোনও "বিধি" নেই। কিছু প্রোগ্রাম এসটিডিআইএন থেকে ইনপুট নেয়, এবং কিছু গ্রহণ করে না। যদি কোনও প্রোগ্রাম STDIN থেকে ইনপুট নিতে পারে তবে এটিতে পাইপ দেওয়া যেতে পারে, যদি না হয় তবে তা পারে না।

কোনও প্রোগ্রাম কোনও কাজটি কী করে তা চিন্তা করেই ইনপুট নেবে কিনা তা আপনি সাধারণত বলতে পারেন। যদি প্রোগ্রামটির কাজটি কোনওভাবে কোনও ফাইলের বিষয়বস্তুগুলি হস্তান্তর করা হয় (যেমন, উদাহরণস্বরূপ)grep , sed, awkইত্যাদি), এটা সাধারণত stdin থেকে ইনপুট নেয়। তার কাজ ফাইল নিজেই (যেমন নিপূণভাবে হয় তাহলে mv, rm, cp) বা একটি প্রক্রিয়া (যেমন kill, lsof) অথবা কিছু সম্পর্কে রিটার্ন তথ্যে (যেমন top, find, ps) তারপর, এটা না।

এটি নিয়ে চিন্তা করার আর একটি উপায় হ'ল আর্গুমেন্ট এবং ইনপুটগুলির মধ্যে পার্থক্য। উদাহরণ স্বরূপ:

mv foo bar

উপরের কমান্ডটিতে এর mvমতো কোনও ইনপুট নেই। এটি যা দেওয়া হয়েছে তা দুটি যুক্তি। এটি ফাইলগুলির মধ্যে যা রয়েছে তা জানে না বা যত্ন করে না, এটি কেবল এটির আর্গুমেন্টগুলি জানে এবং এটি তাদের পরিচালনা করতে হবে।

অন্য দিকে

sed -e 's/foo/bar/' < file
--- -- ------------   ----
 |   |       |          |-> input
 |   |       |------------> argument        
 |   |--------------------> option/flag/switch
 |------------------------> command

এখানে, sedযুক্তির পাশাপাশি ইনপুট দেওয়া হয়েছে। যেহেতু এটি ইনপুট নেয়, এটি এটি STDIN থেকে পড়তে পারে এবং এটিতে পাইপ করা যায়।

এটি আরও জটিল হয় যখন কোনও যুক্তি ইনপুট হতে পারে । উদাহরণ স্বরূপ

cat file

এখানে, fileদেওয়া হয়েছিল যে যুক্তি cat। সুনির্দিষ্টভাবে বলতে গেলে, ফাইলের নামটি file আর্গুমেন্ট। তবে, যেহেতু catএকটি প্রোগ্রাম যা ফাইলগুলির বিষয়বস্তুগুলি পরিচালনা করে, তাই এর ইনপুটটি যা কিছু ভিতরে থাকে file

এটি straceএমন একটি প্রোগ্রাম ব্যবহার করে চিত্রিত করা যেতে পারে যা একটি প্রোগ্রাম যা প্রক্রিয়াগুলি দ্বারা সিস্টেম কলগুলি ট্র্যাক করে। যদি আমরা এর cat fooমাধ্যমে চালাই তবে আমরা straceদেখতে পাচ্ছি যে ফাইলটি fooখোলা আছে:

$ strace cat foo 2| grep foo
execve("/bin/cat", ["cat", "foo"], [/* 44 vars */]) = 0
open("foo", O_RDONLY)     

উপরের প্রথম সারিতে দেখায় যে প্রোগ্রামটি /bin/catআহ্বান করা হয়েছিল এবং এর তর্কগুলি ছিলcat এবং foo(প্রথম যুক্তিটি সর্বদা প্রোগ্রাম নিজেই হয়)। পরে, যুক্তিটি fooকেবল পঠন মোডে খোলা হয়েছিল। এখন, এর সাথে তুলনা করুন

$ strace ls foo 2| grep foo 
execve("/bin/ls", ["ls", "foo"], [/* 44 vars */]) = 0
stat("foo", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
lstat("foo", {st_mode=S_IFREG|0644, st_size=0, ...}) = 0
write(1, "foo\n", 4foo

এখানেও, lsনিজেকে এবং fooতর্ক হিসাবে গ্রহণ । তবে, কোনও openকল নেই, যুক্তিটিকে ইনপুট হিসাবে বিবেচনা করা হবে না। পরিবর্তে,ls ফাইলটির তথ্য পেতে সিস্টেমের statলাইব্রেরি (যা statকমান্ডের মতো একই জিনিস নয় ) কল করে foo

সংক্ষেপে, আপনি যে কমান্ডটি চালাচ্ছেন সেটি যদি তার ইনপুটটি পড়তে পারে তবে আপনি এটিতে পাইপ করতে পারেন, যদি তা না হয় তবে আপনি পারবেন না।


0
  • এটি কিল বা আরএম দিয়ে কাজ করে না কেন?

kill এবং rm এসটিডিনের দরকার নেই।

  • গ্রেপ, অ্যাজকে ইনপুট সহ কিল, আরএম ইনপুট এর মধ্যে কী আলাদা?

জন্য killএবং rmব্যবহারকারীরা আর্গুমেন্ট হিসাবে তাদের কাস্টমাইজ করা তথ্য প্রদানে এবং$(cmd) এর stdout- এ গ্রহণ সাহায্য করে cmdএবং এটি তথ্য যুক্তি রূপান্তর।

জন্য grepএবং awkব্যবহারকারীরা আর্গুমেন্ট এবং ছাড়াও, এছাড়াও প্রদান STDINবা নিয়মিত যে ফাইলটি হুকুমে প্রক্রিয়া করা হবে। STDINপাইপলাইন দিয়ে পাস করা যেতে পারে| বা ম্যানুয়ালি ইনপুট ।

  • কোন নিয়ম আছে?

ম্যানুয়াল বা উত্স কোডগুলি পড়ুন। এবং যদি আপনার প্রয়োজন মতো কিছু না পাওয়া যায় তবে আপনি একটি সহজ তবে সম্ভবত বিপজ্জনক পরীক্ষা করতে পারেন:

আপনি যে কমান্ডটি সম্পর্কে কৌতূহলীয় সেটিকে কেবল ইতিমধ্যে বুঝতে পারছেন এমন আর্গুমেন্টগুলি দিয়ে ইনপুট করুন এবং দেখুন কমান্ডটি বিরতি দেয় কিনা (কিছুই ঘটে না)। যদি এটি বিরতি দেয়, এটি আসলে এসটিডিনের জন্য অপেক্ষা করছে (আপনি চেষ্টা করতে পারেন catএবং ভিন্নটি echoদেখতে পারেন)। আপনি নিজে টাইপ করুনCtrl-D এবং কমান্ডটি এগিয়ে যায় (ফলাফল বা ত্রুটি দেখান) এবং ফিরে আসে। এই জাতীয় কমান্ডের সেই পরিস্থিতিতে এসটিডিআইএন প্রয়োজন (আপনার সরবরাহিত যুক্তি সহ)।

একই কমান্ডের বিভিন্ন পরিস্থিতিতে STDIN এর প্রয়োজন নাও হতে পারে (যেমন, catSTDIN এর জন্য অপেক্ষা করে তবে cat file.txtতা নয়)।

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