यह `grep -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

मैं $(...)उद्धरण में उद्धरण संलग्न करता हूं और यह "ऐसी कोई फ़ाइल या निर्देशिका" समस्या को ठीक करने के लिए नहीं लगता है। हालाँकि, मेरा कनेक्शन अभी भी छपा हुआ है, भले ही मेरे tty ( 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

@don_crissti आह, मैं देख रहा हूं; यह मुझे बता रहा है कि मैं वास्तव में grep"ट्टी नहीं" हूं । आप यह कैसे सुझाएंगे कि मैं इसके आसपास पहुंचूं?
शायद म्मेबेहर्री

एक चर का उपयोग करें: 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 %"
axxis

20

Tty जानकारी पृष्ठ से।

'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}"

@Christopher क्या आप अपने कंप्यूटर में लॉग इन हैं?
ज़ाचारी ब्रैडी

@ क्रिसटन, अजीब। तो 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))
dave_thompson_085

1
कृपया अस्वीकरण न जोड़ें। हालांकि इरादे प्रशंसनीय हैं, वे वास्तव में उत्तर की मदद नहीं करते हैं। यदि कोई आपके उत्तर में कोई दोष बताता है, तो सुधार को शामिल करने के लिए अपने उत्तर को संपादित करें।
terdon
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.