কেন এই `গ্রেপ -v` প্রত্যাশার মতো কাজ করছে না?


12

আমার grep -vপ্রশ্নের সাথে সম্পর্কিত একটি অদ্ভুত সমস্যা আছে । আমাকে ব্যাখ্যা করার অনুমতি দিন:

সংযোগগুলি প্রদর্শন করতে আমি ব্যবহার করি who:

$ who
harry    pts/0        2016-12-08 20:41 (192.168.0.1)
james    pts/1        2016-12-08 19:28 (192.168.0.1)
timothy  pts/2        2016-12-08 02:44 (192.168.0.1)

ttyআমার টার্মিনালের বর্তমানpts/0

$ tty
/dev/pts/0
$ tty | cut -f3-4 -d'/'
pts/0

আমি নিজের সংযোগটি ব্যবহার করে বাদ দেওয়ার চেষ্টা করি grep -v $(tty | cut -f3-4 -d'/')। এই কমান্ডটির প্রত্যাশিত আউটপুটটি whoআমার সংযোগ ছাড়াই হওয়া উচিত । তবে আউটপুটটি সবচেয়ে অপ্রত্যাশিত:

$ who | grep -v $(tty | cut -f3-4 -d'/')
grep: a: No such file or directory
grep: tty: No such file or directory

আমি $(...)উদ্ধৃতিগুলি আবদ্ধ করেছি এবং এটি "এ জাতীয় কোনও ফাইল বা ডিরেক্টরি নেই" সমস্যাটি ঠিক করছে বলে মনে হচ্ছে। তবে, আমার সংযোগটি এখনও ছাপা হয়েছে যদিও আমার টিটি ( pts/0) বাদ দেওয়া উচিত ছিল:

$ who | grep -v "$(tty | cut -f3-4 -d'/')"
harry    pts/0        2016-12-08 20:41 (192.168.0.1)
james    pts/1        2016-12-08 19:28 (192.168.0.1)
timothy  pts/2        2016-12-08 02:44 (192.168.0.1)

এই বিন্দু হিসাবে, কেন grepকোয়েরিটি ত্রুটিযুক্ত তা আমার সম্পূর্ণ ধারণা নেই ।


4
set -xপ্রথমে কীভাবে ব্যবহার করবেন ... তারপরে আপনার কমান্ডটি চালান এবং দেখুন আপনি আসলে কী চেষ্টা করছেন grep...
don_crissti

@ ডন_ক্রিস্তি আহ, আমি দেখছি; এটি আমাকে বলছে আমি আসলে grep"টিটিআই নন" ing আমি কীভাবে আপনি এটি সম্পর্কে পরামর্শ দিতে চান?
মায়াবাহারীতে

একটি ভেরিয়েবল ব্যবহার করুন: tldp.org/HOWTO/Bash-Prompt-HOWTO/x721.html
don_crissti

উত্তর:


18

জাকারি সমস্যার উত্সটি ব্যাখ্যা করেছেন।

আপনি যখন এটিকে ঘিরে কাজ করতে পারেন তখন

tty=$(tty)
tty_without_dev=${tty#/dev/}
who | grep -v "$tty_without_dev"

উদাহরণস্বরূপ এটি ভুল হবে যে যদি টিটিটি হয় তবে pts/1আপনি সমস্ত লাইন সমেত বাদ দিয়ে শেষ করবেন pts/10। কিছু grepবাস্তবায়নে -wশব্দ অনুসন্ধান করার বিকল্প রয়েছে

who | grep -vw pts/1

মিলবে না pts/10কারণ pts/1সেখানে শব্দগুলি একটি অ-শব্দের চরিত্র অনুসরণ করে না।

অথবা আপনি awkদ্বিতীয় ক্ষেত্রের যথাযথ মান হিসাবে ফিল্টার করতে ব্যবহার করতে পারেন:

who | awk -v "tty=$tty_without_dev" '$2 != tty'

যদি আপনি এটি একটি আদেশে করতে চান:

{ who | awk -v "tty=$(tty<&3)" '$2 != substr(tty,6)'; } 3<&0

আসল স্টিডিনটি ফাইল বর্ণনাকারী 3 এ নকল করা হয়েছিল এবং ttyকমান্ডের জন্য পুনরুদ্ধার করা হয়েছে ।


3
এটি একটি কমান্ডে কীভাবে করা যায় তা নির্ধারণ করার জন্য এবং সেই ভুলটি নির্দেশ করার জন্য +1।
জাচারি ব্র্যাডি

আরও একটি লাইনার:tty | cut -f3-4 -d'/' | xargs -I % sh -c "who | grep -v %"
অক্ষ

20

Tty তথ্য পৃষ্ঠা থেকে।

'tty' এর স্ট্যান্ডার্ড ইনপুটটির সাথে সংযুক্ত টার্মিনালের ফাইলের নাম মুদ্রণ করে। স্ট্যান্ডার্ড ইনপুটটি টার্মিনাল না হলে এটি 'টিটি নয়' মুদ্রণ করে।

সমস্যাটি হ'ল আপনার উদাহরণে টিটির স্টিডিন একটি পাইপ, আপনার টার্মিনাল নয়।

আপনি এই উদাহরণ থেকে দেখতে পারেন।

$ tty
/dev/pts/29
$ echo | tty 
not a tty

চারপাশে কাজ করার জন্য আপনি এই জাতীয় কিছু করতে পারেন।

who | grep -wv "$(ps ax | awk "\$1 == $$ {print \$2}" )"

একটি দ্রুত / আরও কার্যকর উপায় আছে তবে এটিতে দুটি কমান্ডের প্রয়োজন।

t=$(tty)
who|grep -wv "${t:5}"

@ খ্রিস্টোফার আপনি কি কেবলমাত্র আপনার কম্পিউটারে লগইন করেছেন?
জাচারি ব্র্যাডি

ক্রিস্টোফার, অদ্ভুত সুতরাং who | grep -v "$(ps ax | grep "^$$" | awk '{ print $2 }')"উত্পাদিতগুলি আমার বাক্সে প্রত্যাশিত আউটপুট উত্পাদন করে এবং t=$(tty) who|grep -v "${t:5}"কিছুই উত্পাদন করে না।
জাচারি ব্র্যাডি

আপনি কোন শেল / সংস্করণ ব্যবহার করছেন? GNU bash, version 4.1.2
জাচারি ব্র্যাডি

2
ps ax | grep "^ *$$"ভুল-মিল হতে পারে যেমন আপনার শেলটি 123 এবং 1234 টি বিদ্যমান; ps ax -otty= $$আরও মজবুত এবং শুধুমাত্র একটি প্রক্রিয়া। তবে আমি আপনার ${t:5}বা ${t#/dev/}substr(t,6)
স্টিফেনের

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