एक प्रक्रिया से दूसरी प्रक्रिया में आउटपुट कैसे करें, लेकिन केवल तभी निष्पादित करें जब पहला आउटपुट हो?


23

अगर वहाँ से आउटपुट है तो मैं केवल इस ईमेल को कैसे लिख सकता हूँ mailq | grep?

mailq | egrep 'rejected|refused' -A 5 -B 5 | mail -s 'dd' email@email

क्या यह एक लाइन पर भी संभव है?

देखें कि क्या पाइप खाली है और ईमेल भेजने की तुलना में अधिक सामान्य मामले के लिए नहीं है , तो डेटा पर एक कमांड चलाएं


जवाबों:


19

मुझे लगता है कि आपको इस ऑपरेशन के लिए एक अस्थायी फ़ाइल का उपयोग करना होगा ताकि आप &&ऑपरेटर को केवल मेल कमांड चलाने के लिए उपयोग कर सकें यदि grep एक निकास स्थिति लौटाता है जो कहता है कि यह इस तरह से मेल खाता था:

TMPFILE=`mktemp /tmp/mailqgrep.XXXXXX`; mailq | egrep 'rejected|refused' -A5 -B5 > "$TMPFILE" && mail -s 'dd' email@email < "$TMPFILE"; rm "$TMPFILE"

यदि आपने टेम्प फ़ाइल को कहीं से चिपका हुआ नहीं देखा है और इसके लिए एक स्थिर नाम का उपयोग कर सकते हैं, तो आप विशेष नामकरण और विलोपन मूल्य को छोड़ सकते हैं:

 mailq | egrep 'rejected|refused' -A5 -B5 > /tmp/mailqgrep && mail -s 'dd' email@email < /tmp/mailqgrep

संपादित करें: ग्लेन के जवाब को देखने के बाद मैंने इसके साथ कुछ और खेला और स्पष्ट रूप से $()वाक्यविन्यास का उपयोग करके एक चर असाइन करना कमांड के निकास कोड को वापस करता है, इसलिए आप उस स्ट्रिंग की लंबाई के लिए उपयोग किए गए परीक्षण को छोड़ सकते हैं और इसके बजाय उसका उपयोग कर सकते हैं। यहाँ यह सब एक आदेश में है:

data=$(mailq | egrep 'rejected|refused' -A 5 -B 5) && mail -s 'dd' email@email <<< "$data"

संपादन 2: साइमन का उत्तर देखने के बाद मैंने अपना mailकार्यक्रम देखा। यह उस तरीके से व्यवहार नहीं करता है जो वह डिफ़ॉल्ट रूप से वर्णन करता है, लेकिन उसके लिए एक विकल्प है। आदमी पृष्ठ से:

-Eयदि एक आउटगोइंग संदेश में उसके पहले या एकमात्र संदेश भाग में कोई पाठ नहीं है, तो उसे भेजें नहीं, लेकिन चुपचाप छोड़ दें, प्रभावी ढंग से प्रोग्राम स्टार्टअप पर Skipemptybody चर सेट कर रहा है। यह क्रोन (8) द्वारा शुरू की गई लिपियों से संदेश भेजने के लिए उपयोगी है।

इसे संभव बनाना:

mailq | egrep 'rejected|refused' -A 5 -B 5 | mail -E -s 'dd' email@email

1
सहयोग की शक्ति !!
ग्लेन जैकमैन

3
मेरा सुझाव है कि इस उत्तर को सबसे अच्छे समाधान को ऊपर ले जाकर बेहतर बनाया जा सकता है ।
मार्क बूथ

@Wildcard संपादित करना आवश्यक नहीं था, यह देखते हुए कि इनपुट पैरामीटर्स mktempको कुछ ऐसा वापस नहीं करना है, जिसे उद्धृत करने की आवश्यकता हो।
कालेब

2
मुझे पता है। आप कुछ लोग समझना महत्वपूर्ण है कि उद्धरण परेशान में से एक हैं कर रहे हैं कभी कभी आवश्यक (और उन्हें जानबूझ कर छोड़ देता है)। हालाँकि, जब तक आप स्पष्ट रूप से कॉल नहीं करना चाहते, तब तक डिफ़ॉल्ट को उद्धृत किया जाना चाहिएglob(split(var)) । यहां आपको शब्द विभाजन या फ़ाइल ग्लोब विस्तार की आवश्यकता नहीं है, इसलिए उनसे मत पूछिए। साथ ही, हमें इस साइट पर सही रास्ता दिखाने की जरूरत है
वाइल्डकार्ड

@Wildcard मेला काफी। मैं आम तौर पर चलाने zshऔर वास्तव में कर रहा हूँ नहीं इस तरह के मामलों में ग्लोबिंग या शब्द बंटवारे हो रही जब तक कि मैं उनके लिए पूछना है, लेकिन लक्ष्य पर्यावरण सिद्धांत से बाहर के हवाले से जानते हुए भी ठीक है जवाब की खातिर यहाँ और नहीं के लिए।
कालेब

11

उपयोगिता कार्यक्रम ifne इस उद्देश्य के लिए स्पष्ट रूप से मौजूद है: यदि मानक इनपुट खाली नहीं है, तो कमांड चलाने के लिए।

mailq | egrep 'rejected|refused' -A 5 -B 5 | ifne mail -s 'dd' email@email

Ifne कमांड, अधिक संख्या के पैकेज का हिस्सा है , जिसे "यूनिक्स उपकरणों के बढ़ते संग्रह के रूप में बिल किया गया है, जिसे किसी ने बहुत पहले लिखने के लिए नहीं सोचा था, जब यूनिक्स युवा था।"


8

आप आउटपुट को एक चर में सहेज सकते हैं, और फिर स्ट्रिंग की लंबाई गैर-शून्य होने पर मेल कमांड को भेज सकते हैं।

data=$(mailq | egrep 'rejected|refused' -A 5 -B 5)
[[ -n "$data" ]] && mail -s 'dd' email@email <<< "$data"

एक पंक्ति के लिए, दो आदेशों को अर्ध-बृहदान्त्र के साथ जोड़ दें।


1
एक अस्थायी फ़ाइल के बजाय एक चर का उपयोग करने के लिए सहारा। इससे मुझे यह सोचने में मदद मिली कि एक्ज़िट कोड उस कमांड से कहाँ जाता है जिसे आपने वेरिएबल असाइनमेंट के साथ किया था, और जाहिर तौर पर यह पास हो जाता है! देखिये मेरा अपडेटेड जवाब
कालेब

7

विकल्प के mailसाथ उपयोग करें -E। मेरे मैक पर, मेल (1) कहता है कि -Eझंडा खाली शरीर के साथ ईमेल नहीं भेजेगा।

-एक खाली शरीर के साथ संदेश न भेजें। यह क्रोन (8) स्क्रिप्ट से त्रुटियों को पाइप करने के लिए उपयोगी है।

अपने मैक पर, मैंने निम्नलिखित परीक्षण चलाया। ध्यान दें कि फ़ाइल file_does_existमौजूद नहीं है, लेकिन फ़ाइल file_does__not_existमौजूद नहीं है।

यह मुझे एक ईमेल भेजता है:

$ ls file_does_exist | egrep 'file' -A5 -B5 | mailx -E -s 'test' stefan@example.org

यह नहीं करता। ध्यान दें कि कमांड ls file_does_not_exist | egrep ...कोई आउटपुट नहीं देता है।

$ ls file_does_not_exist | egrep 'file' -A5 -B5 | mailx -E -s 'test' stefan@example.org
ls: file_does_not_exist: No such file or directory

कालेब ने आपको हरा दिया।
गिल्स एसओ- बुराई को रोकें '17

1
उन्होंने मुझे केवल 4.75 घंटे :) हराया। मैंने इस विवरण को उसके लंबे उत्तर में याद किया।
स्टीफन लासिवस्की

5

इस विशेष मामले में, यदि आपका mailसमर्थन करता है-E विकल्प विकल्प है , तो बस इसका उपयोग करें। सामान्य स्थिति में, आप एक चरित्र को पढ़ने की कोशिश कर सकते हैं; यदि कोई है, तो पोस्टप्रोसेसिंग कमांड शुरू करें और उस चरित्र को बाकी फ़ाइल से खिलाएं।

pipe_if_not_empty () {
  a=$(dd bs=1 count=1 2>/dev/null; echo .)  # read at most one character
  if [ "$a" != "." ]; then                  # if there were two characters,
    { printf %s "${a%.}";                   # then output the first character
      cat; } |                              # and the rest of the input   
    "$@"                                    # into the specified program
  fi
}

mailq | egrep 'rejected|refused' -A 5 -B 5 |
pipe_if_not_empty mail -s 'dd' email@email

के उपयोगी उपयोग पर ध्यान दें catecho .इस फ़ंक्शन को काम करने के अलावा भी अगर इनपुट में पहला चरित्र एक नईलाइन है (याद रखें कि $(…)निर्माण स्ट्रिप्स टर्मिनल newlines)।

अधिकांश गोले (zsh के अलावा कुछ भी, जहां तक ​​मुझे पता है), यदि फ़ाइल एक अशक्त चरित्र से शुरू होती है, तो यह कोड विश्वास करेगा कि यह खाली है। फिक्सिंग जो पाठक के लिए एक अभ्यास के रूप में छोड़ दिया जाता है। (संकेत: odपहली उपधारा में उपयोग करें और printfपहली बाइट प्रिंट करें।) (समाधान: पाइप खाली है या नहीं, इसकी जांच कैसे करें ) यदि फाइल बाइट के साथ शुरू होती है तो आप उसी मुद्दे पर चल सकते हैं जो वर्तमान में मान्य वर्ण नहीं है। स्थान में; इसके साथ इस कोड को चलाकर ठीक करना आसान है LC_ALL=C


हास्यास्पद के लिए +1 लेकिन संभवतः एक अन्य परिदृश्य में उपयोगी है :) जिज्ञासा से बाहर, खाली स्ट्रिंग के लिए परीक्षण के बजाय डॉट के लिए इंजेक्शन और परीक्षण क्यों करें? यदि इनपुट डॉट से शुरू होता है तो क्या यह समस्या नहीं है? क्या इसका उपयोग readसरल बनाने में मदद कर सकता है ?
कालेब

@ कालेब: हां, मुझे इस बात का उल्लेख करना चाहिए कि मैं शीर्षक में सवाल का जवाब दे रहा था, विशेष स्थिति को नहीं। डॉट के स्पष्टीकरण के लिए मेरा संपादन देखें। मुझे नहीं लगता कि आप readपोर्टेबल श में एक खाली फ़ाइल से एक खाली पहली पंक्ति को अलग कर सकते हैं (यह bash, ksh या zsh में संभव हो सकता है)।
गिल्स एसओ- बुराई को रोकें

3

mailयदि कोई खाली संदेश दिया जाता है तो IIRC BSD कमांड को निरस्त कर देता है।


1
मेरे GNU लिनक्स सिस्टम पर मेल प्रोग्राम (Heirloom mailx 12.4) डिफ़ॉल्ट रूप से इस तरह का व्यवहार नहीं करता है, लेकिन इसे सक्षम करने का एक -Eविकल्प है
कालेब

1

हाल ही में मैंने कमांड नाम के बारे में जाना है ifneजो moreutilsपैकेज का हिस्सा है । जहां आप इस विशिष्ट समस्या को हल करने के लिए इसका उपयोग कर सकते हैं।

ifne - मानक इनपुट खाली नहीं होने पर रन कमांड

मैन पेज से उदाहरण,

EXAMPLE
       find . -name core | ifne mail -s "Core files found" root

0

यदि आपकी ओर test -s /dev/stdinसे कोई आउटपुट है, तो यह जांचने के लिए आप अपने कमांड को फिर से लिख सकते हैं mailq | grep

- mailq | egrep 'rejected|refused' -A 5 -B 5 | mail -s 'dd' email@email
+ mailq | egrep 'rejected|refused' -A 5 -B 5 | (test -s /dev/stdin && cat) | mail -s 'dd' email@email
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.