আমি কীভাবে টিপি ব্যবহার করব গ্রিপতে পুনর্নির্দেশ করতে


13

আমার কাছে টি ব্যবহারের খুব বেশি অভিজ্ঞতা নেই, তাই আমি আশা করি এটি খুব মৌলিক নয়।

এই প্রশ্নের উত্তরগুলির একটি দেখার পরে আমি একটি অদ্ভুত আচরণের সাথে এসেছিলাম tee

আমার প্রথম লাইন এবং একটি সন্ধান করা লাইন আউটপুট করার জন্য, আমি এটি ব্যবহার করতে পারি:

ps aux | tee >(head -n1) | grep syslog
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
syslog     806  0.0  0.0  34600   824 ?        Sl   Sep07   0:00 rsyslogd -c4

যাইহোক, প্রথমবার যখন আমি এটি চালিত (zsh) ফলাফলটি ভুল ক্রমে ছিল, কলামের শিরোনামগুলি গ্রেপের ফলাফলের নীচে ছিল (এটি অবশ্য আবার ঘটেনি), তাই আমি কমান্ডগুলি চারপাশে বদলে নেওয়ার চেষ্টা করেছি:

ps aux | tee >(grep syslog) | head -n1
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND

কেবল প্রথম লাইনটিই মুদ্রিত, আর কিছুই না! আমি কি গ্রে ব্যবহার করে পুনর্নির্দেশ করতে টি ব্যবহার করতে পারি, বা আমি এটি ভুল পদ্ধতিতে করছি?

আমি যখন এই প্রশ্নটি টাইপ করছিলাম, দ্বিতীয় কমান্ডটি আসলে আমার জন্য একবার কাজ করেছিল, আমি এটি আবার পাঁচবার চালিয়েছিলাম এবং তারপরে আবার এক লাইনের ফলাফলে ফিরে এসেছি। এটা কি শুধু আমার সিস্টেম? (আমি tmux মধ্যে zsh চালাচ্ছি)।

অবশেষে, কেন প্রথম কমান্ডটি "গ্রেপ সিস্লগ" ফলাফল হিসাবে দেখানো হয়নি (কেবলমাত্র একটি ফলাফল রয়েছে)?

নিয়ন্ত্রণের জন্য এখানে ছাড়াই গ্রেপ tee

ps aux | grep syslog
syslog     806  0.0  0.0  34600   824 ?        Sl   Sep07   0:00 rsyslogd -c4
henry    2290  0.0  0.1  95220  3092 ?        Ssl  Sep07   3:12 /usr/bin/pulseaudio --start --log-target=syslog
henry   15924  0.0  0.0   3128   824 pts/4    S+   13:44   0:00 grep syslog

আপডেট: দেখে মনে হচ্ছে যে হেড পুরো কমান্ডকে ছাঁটাই করছে (নীচের উত্তরে বর্ণিত হিসাবে) নীচের কমান্ডটি এখন নিম্নলিখিতটি ফিরিয়ে দিচ্ছে:

ps aux | tee >(grep syslog) | head -n1
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
syslog     806

আপনার প্রশ্নের সরাসরি উত্তর নয় তবে এটির মতো কিছু করা আরও পরিষ্কার ps aux | sed -n -e '1p' -e '/syslog/p'
jw013

আমি কখনও সেডের কথা ভাবি নি, আমি মনে করি এটি এখানে সম্পর্কিত প্রশ্নের উপযুক্ত উত্তর হতে পারে তবে আমি এই কমান্ডগুলির অসামঞ্জস্যপূর্ণ আচরণের তথ্য অনুসন্ধান করছি!
Rqomey

উত্তর:


19
$ ps aux | tee >(head -n1) | grep syslog
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND 
syslog     806  0.0  0.0  34600   824 ?        Sl   Sep07   0:00 rsyslogd -c4

grepএবং headকমান্ড একই সময় সম্পর্কে এ শুরু, এবং উভয় তাদের নিজস্ব অবসর সময়ে একই ইনপুট ডেটা গ্রহণ, কিন্তু সাধারণভাবে, যেমন ডেটা উপলব্ধ হয়ে ওঠে। কিছু জিনিস রয়েছে যা 'আনসক্রোনাইজড' আউটপুট প্রবর্তন করতে পারে যা লাইনগুলি ফ্লিপ করে; উদাহরণ স্বরূপ:

  1. teeমূলত বাস্তবায়নের উপর নির্ভর করে একাধিক প্রক্রিয়াতে মূলত মাল্টিপ্লেক্সযুক্ত ডেটা প্রেরণ করা হয় tee। একটি সাধারণ teeবাস্তবায়ন readকিছু পরিমাণ ইনপুট দেয় এবং তারপরে writeএটি দু'বার: একবার স্টডআউট এবং একবার তার যুক্তিতে। এর অর্থ এই যে কোনও গন্তব্যগুলির মধ্যে প্রথমে ডেটা পাবেন।

    যাইহোক, পাইপ সব বাফার হয়। সম্ভবত এই বাফারগুলি প্রতিটি 1 টি লাইন, তবে এগুলি আরও বড় হতে পারে, যা grepঅন্য কমান্ড ( head) -এ কোনও তথ্য প্রাপ্ত হওয়ার আগে আউটপুটটির জন্য প্রয়োজনীয় সমস্ত কিছু দেখতে (যেমন প্যাড লাইন) দেখাতে পারে one সব।

  2. উপরোক্ত সত্ত্বেও, এটিও সম্ভব যে এই কমান্ডগুলির মধ্যে একটি ডেটা গ্রহণ করে তবে সময়মতো এটি সহ কিছু করতে অক্ষম হয় এবং তারপরে অন্যান্য কমান্ড আরও ডেটা গ্রহণ করে এবং দ্রুত এটি প্রক্রিয়া করে।

    উদাহরণস্বরূপ, এমনকি যদি headএবং grepএকবারে ডেটা এক লাইনে প্রেরণ করা হয় তবে headকীভাবে এটি মোকাবেলা করতে না জানি (বা কার্নেলের সময়সূচী দ্বারা বিলম্বিত হবে) এমনকি grepতার headসুযোগ পাওয়ার আগেও তার ফলাফলগুলি প্রদর্শন করতে পারে। প্রদর্শন করতে, একটি বিলম্ব যোগ করার চেষ্টা করুন: ps aux | tee >(sleep 1; head -n1) | grep syslogএটি প্রায় অবশ্যই আউটপুট আউটপুট হবে grep

$ ps aux | tee >(grep syslog) | head -n1
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND

আমি বিশ্বাস করি আপনি প্রায়শই এখানে কেবল একটি লাইন headপান , কারণ ইনপুটটির প্রথম লাইনটি গ্রহণ করে এবং তার স্টিডিনটি বন্ধ করে প্রস্থান করে। যখন teeদেখবে যে এর স্টাডআউটটি বন্ধ হয়ে গেছে, তখন এটি তার নিজস্ব স্টিডিন (আউটপুট থেকে ps) বন্ধ করে প্রস্থান করে। এটি বাস্তবায়ন নির্ভর হতে পারে।

কার্যকরভাবে, কেবলমাত্র ডেটা যা psপ্রেরণ করতে পারে তা হ'ল প্রথম লাইন (অবশ্যই, কারণ headএটি নিয়ন্ত্রণ করছে), এবং সম্ভবত তাদের স্টিডিন বর্ণনাকারীদের আগে head& teeবন্ধ করে দেয়।

দ্বিতীয় লাইনটি প্রদর্শিত হবে কিনা তার সাথে অসঙ্গতিটি সময় দ্বারা প্রবর্তন করা হয়েছিল: headস্টিডিন বন্ধ করে দেয়, তবে psএখনও ডেটা প্রেরণ করে। এই দুটি ইভেন্ট ভাল-সিঙ্ক্রোনাইজ করা হয়নি, সুতরাং লাইনটি syslogএখনও রয়েছে এটির teeযুক্তি ( grepকমান্ড) এ তৈরি করার সুযোগ রয়েছে । এটি উপরের ব্যাখ্যাগুলির সাথে সমান।

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

ps aux | tee >(grep syslog) | awk 'NR == 1'

তবে নোট করুন যে লাইনগুলি এখনও উপরে যেমন আদেশ-বহিঃপ্রকাশে উপস্থিত হতে পারে, যা দ্বারা প্রদর্শিত হতে পারে:

ps aux | tee >(grep syslog) | (sleep 1; awk 'NR == 1')

আশা করি এটি খুব বেশি বিশদ ছিল না, তবে একে অপরের সাথে ইন্টারঅ্যাক্ট করার অনেকগুলি বিষয় রয়েছে। পৃথক প্রক্রিয়াগুলি কোনও সিঙ্ক্রোনাইজেশন ছাড়াই এক সাথে চলমান, যাতে কোনও নির্দিষ্ট রানে তাদের ক্রিয়াগুলি পৃথক হতে পারে; কখনও কখনও এটি কেন তা ব্যাখ্যা করতে অন্তর্নিহিত প্রক্রিয়াগুলির গভীর গভীরতায় সহায়তা করে।


1
দুর্দান্ত উত্তর! আমি প্রকৃতপক্ষে জিজ্ঞাসা করেছি কারণ আমি অন্তর্নিহিত প্রক্রিয়াগুলিতে আগ্রহী। বিষয়গুলি যখন অসুবিধে হয় তখন আমি এটি আকর্ষণীয় মনে করি। স্ট্যান্ডআউট ps aux | tee >(grep syslog) | head -n1বন্ধ করা headবন্ধ করে দেওয়ার জন্য আরও কি ভাল উপায় আছে ? বাহ, এই কমান্ডটি এখনই আউটপুট দেওয়া শুরু করেছে, তবে আপনার উত্তর অনুসারে এটি কেটে গেছে বলে মনে হচ্ছেUSER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND syslog 806
রিকোমি

1
আপনি এমন কিছু ব্যবহার করতে পারেন যা পরিবর্তে স্টিডিনটি বন্ধ করে দেয় না head। আমি এই উদাহরণটি দিয়ে উত্তরটি আপডেট করেছি:ps aux | tee >(grep syslog) | awk 'NR == 1'
এমআরবি

1
@ ক্রিজিস্জটোফ অ্যাডামস্কি, আপনি যখন ব্যবহার করবেন >(cmd)তখন শেলটি একটি নামযুক্ত পাইপ তৈরি করে এবং এটি কমান্ডের যুক্তি হিসাবে পাস করে ( tee)। তারপরে teestdout (পাইপযুক্ত awk) এবং সেই যুক্তিতেও লিখছেন । এটি mkfifo a_fifo ; grep ... a_fifoএকটি শেলের মতো এবং ps | tee a_fifo | awk ...অন্যটিতে একই রকম ।
এমআরবি

1
@ ক্রিজিসটফএডামসকি gnu.org/software/bash/manual/html_node/… - চেষ্টা করুন echo >(exit 0), যা শেলের মাধ্যমে প্রাপ্ত প্রকৃত যুক্তির প্রতিধ্বনি করবে (আমার ক্ষেত্রে এটি হয়ে যায় /dev/fd/63)। এটি ব্যাশ এবং zsh এ একই কাজ করা উচিত।
এমআরবি

1
@ এমআরবি: এটি অত্যন্ত আকর্ষণীয় বৈশিষ্ট্য যা আমি আগে জানতাম না, আপনাকে ধন্যবাদ। এটি বাশতে কিছু অদ্ভুত উপায়ে কাজ করছে, তবে, পেস্টবিন . com/ এক্সএফজিআরসিজেডিএফ দেখুন । দুর্ভাগ্যক্রমে আমার এখন এটি তদন্ত করার সময় নেই তবে আমি আগামীকাল এটি করব।
ক্রিজিসটফ অ্যাডামস্কি

2

grep syslogসময় অনুযায়ী নির্ভর করে তাই সর্বদা প্রদর্শিত হয় না। শেল পাইপলাইন ব্যবহার করার সময়, আপনি প্রায় একই সাথে কমান্ডগুলি চালাচ্ছেন। তবে এখানে মূল বিষয়টি হল "প্রায়" শব্দটি। psগ্রেপ চালু হওয়ার আগে যদি সমস্ত প্রক্রিয়া স্ক্যান করা শেষ করে তবে তা তালিকায় থাকবে না। সিস্টেমের বোঝার উপর নির্ভর করে আপনি এলোমেলো ফলাফল পেতে পারেন etc.

আপনার টি সঙ্গে একই জিনিস ঘটে। এটি সাবশেলে পটভূমিতে চালিত হয় এবং এটি গ্রেপের আগে বা পরে বহিস্কার করা হতে পারে। এই কারণেই আউটপুট ক্রমটি বেমানান।

টি প্রশ্ন হিসাবে, এটি আচরণ বেশ আশ্চর্যজনক। এটি কারণ এটি সাধারণভাবে ব্যবহৃত হয় না। এটি কোনও যুক্তি ছাড়াই পরিচালিত হয় যার অর্থ এটি কেবল স্ট্যান্ডিন থেকে স্টাডআউটে ডেটা অনুলিপি করা উচিত। তবে এটি স্টাডাউটটি সাব-শেলিং হেডে (প্রথম ক্ষেত্রে) বা গ্রেপ (২ য় ক্ষেত্রে) এ পুনঃনির্দেশিত হয়েছে। তবে এটি পরবর্তী কমান্ডে পাইপ করা হয়েছে। আমি মনে করি যে এই ক্ষেত্রে যা ঘটে তা আসলে বাস্তবায়ন নির্ভর। উদাহরণস্বরূপ আমার বাশ ৪.২.২৮-তে, সাবস্কেল স্টিডিনে কখনও কিছুই লেখা হয় না। Zsh এ, এটি আপনার পছন্দ মতো নির্ভরযোগ্যভাবে কাজ করে (PS এর প্রথম লাইন এবং অনুসন্ধান লাইন উভয় মুদ্রণ), প্রতিবার চেষ্টা করার পরে,


এটি যেভাবেই একটি বিষয় ব্যাখ্যা করে, আমি আশ্চর্য হয়েছি যে টি একটি গ্রেপ্তার লক্ষণীয় পর্যায়ে দেরি করে!
Rqomey

0

কিছুটা হ্যাকিশ, তবে psgrep()শেল ফাংশনটি আমি ব্যবহার করি এর আকারে এটি আমার সমাধান :

psশিরোনাম সারিটি STDERRএরপরে পুনঃনির্দেশ grepকরুন STDOUT, তবে প্রথমে grepকমান্ডটি নিজেই সরিয়ে ফেলুন, নিজের থেকে উদ্ভূত "শব্দ" সারিটি এড়ানোর জন্য grep:

psgrep() { ps aux | tee >(head -1>&2) | grep -v " grep $@" | grep "$@" -i --color=auto; }
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.