केवल सफलता पर शेल कमांड का आउटपुट छिपाएं?


12

शेल कमांड के आउटपुट को छुपाना आमतौर पर stderr और stdout को पुनर्निर्देशित करना शामिल है। क्या कोई अंतर्निहित सुविधा या कमांड है जो डिफ़ॉल्ट रूप से आउटपुट को छुपाता है लेकिन त्रुटि पर सभी संचित आउटपुट को डंप करता है? मैं इसे रिमोट sshकमांड के लिए एक आवरण के रूप में चलाना चाहूंगा । अब मैं उन्हें पुनर्निर्देशन का उपयोग कर रहा हूं, लेकिन मुझे कोई सुराग नहीं मिला है कि उन्हें क्या असफल बनाया गया है, और वे अभी बहुत क्रियात्मक हैं।

EDIT: अंत में मैंने @Belmin के उत्तर के आधार पर निम्नलिखित टेम्पलेट बनाया, जिसे मैंने स्क्रिप्ट से पिछली सभी कमांड को संचित करने के लिए थोड़ा बदल दिया, वर्तमान प्रक्रिया पहचानकर्ता का उपयोग करें, स्वचालित रूप से लॉग को हटा दें, और विफलता लाल त्रुटि जोड़ें संदेश जब कुछ गलत हो जाता है। इस टेम्पलेट में प्रारंभिक silentरैपर सफल होंगे, फिर तीसरी कमांड को विफल कर देंगे क्योंकि निर्देशिका पहले से मौजूद है:

#!/bin/sh

set -e

SILENT_LOG=/tmp/silent_log_$$.txt
trap "/bin/rm -f $SILENT_LOG" EXIT

function report_and_exit {
    cat "${SILENT_LOG}";
    echo "\033[91mError running command.\033[39m"
    exit 1;
}

function silent {
    $* 2>>"${SILENT_LOG}" >> "${SILENT_LOG}" || report_and_exit;
}

silent mkdir -v pepe
silent mkdir -v pepe2
silent mkdir -v pepe
silent mkdir -v pepe2

2
यदि आप केवल stdout को पुनर्निर्देशित करते हैं, तो stderr अभी भी दिखाई देगा; क्या यह आपके लिए पर्याप्त है, या क्या आप स्टडआउट देखना चाहते हैं यदि कोई त्रुटि है?
क्रोमाई

मैं दोनों को देखना चाहता हूं, लेकिन अगर कुछ गलत होता है, तो ही मैं कुछ भी देखना नहीं चाहता।
ग्रेजेगॉर एडम हंकीविज़

2
क्या मैं प्रिंट stdout और stderr एक logfile करने के लिए तो यह स्क्रीन अव्यवस्था नहीं है। मैं स्क्रीन पर stderr भी प्रिंट करता हूं, इसलिए यदि कोई त्रुटि है और मैं इसे देख सकता हूं। अगर मुझे विवरण चाहिए, तो मैं लॉगफ़ाइल की जांच कर सकता हूं, जिसमें प्रोग्राम आउटपुट और संदर्भ में प्रोग्राम की त्रुटियां हैं। इस तरह, मैं 'दोनों को देख सकता हूं लेकिन तभी कुछ गलत होगा'। क्या यह मदद करता है? देखें stackoverflow.com/questions/2871233/…
स्टीफन लासिवस्की

1
क्या दो अलग-अलग रीडायरेक्ट्स के साथ एक ही फाइल पर stderr और stdout को रीडायरेक्ट करना सुरक्षित है? मैंने सोचा था कि हमें हमेशा उपयोग करना चाहिए 2>&1, जैसे कुछ:$* >>"${SILENT_LOG}" 2>&1" || report_and_exit
psmith

जवाबों:


3

मैं इस तरह से एक bash फ़ंक्शन सेटअप करूँगा :

function suppress { /bin/rm --force /tmp/suppress.out 2> /dev/null; ${1+"$@"} > /tmp/suppress.out 2>&1 || cat /tmp/suppress.out; /bin/rm /tmp/suppress.out; }

फिर, आप बस कमांड चला सकते हैं:

suppress foo -a bar

एक हमलावर जिसके पास आपके सिस्टम पर गैर-रूट एक्सेस है, वह rm और कमांड कॉल के बीच एक सिमलिंक बनाने की कोशिश कर सकता है, जो /etc/passswdकिसी अन्य महत्वपूर्ण फ़ाइल को इंगित करेगा और सामग्री को अधिलेखित कर देगा।
मैथुन

1
BTW, ऊपर पुनर्निर्देश का क्रम होना चाहिए: $* > /tmp/surpress.out 2>&1यह वास्तव में स्टैडर को पकड़ लेता है।
मिठ्ठ

2
$*मनमाना इनपुट संभालने के लिए सबसे अच्छा नहीं है। खासकर जब इसमें स्पेस या झंडे हों। सबसे पोर्टेबल stackoverflow.com/questions/743454/… के${1+"$@"} अनुसार है
बालरूप

दोनों टिप्पणियों के अनुसार संशोधित। धन्यवाद --- अच्छी जानकारी।
बेलमिन फर्नांडीज


7

इस उद्देश्य के लिए स्क्रिप्ट लिखना काफी आसान होना चाहिए।

कुछ इस तरह पूरी तरह से बिना स्क्रिप्ट के।

OUTPUT=`tempfile`
program_we_want_to_capture &2>1 > $OUTPUT
[ $? -ne 0 ]; then
    cat $OUTPUT
    exit 1
fi
rm $OUTPUT

आज्ञाओं के लिए दूसरी ओर मैं एक स्क्रिप्ट के हिस्से के रूप में चलाता हूं, जिसे मैं आमतौर पर सभी आउटपुट प्रिंट करने से बेहतर कुछ चाहता हूं। मैं अक्सर वही करता हूं जो मैं अज्ञात को देखता हूं। यहाँ एक स्क्रिप्ट है जिसे मैंने एक दशक पहले पढ़ी गई किसी चीज़ से अनुकूलित किया था।

#!/bin/bash

the_command 2>&1 | awk '
BEGIN \
{
  # Initialize our error-detection flag.
  ErrorDetected = 0
}
# Following are regex that will simply skip all lines
# which are good and we never want to see
/ Added UserList source/ || \
/ Added User/ || \
/ init domainlist / || \
/ init iplist / || \
/ init urllist / || \
/ loading dbfile / || \
/^$/ {next} # Uninteresting message.  Skip it.

# Following are lines that we good and we always want to see
/ INFO: ready for requests / \
{
  print "  " $0 # Expected message we want to see.
  next
}

# any remaining lines are unexpected, and probably error messages.  These will be printed out and highlighted.
{
  print "->" $0 # Unexpected message.  Print it
  ErrorDetected=1
}

END \
{
  if (ErrorDetected == 1) {
    print "Unexpected messages (\"->\") detected in execution."
    exit 2
  }
}
'
exit $?

5

मुझे नहीं लगता कि ऐसा करने का एक साफ तरीका है, केवल एक चीज जो मैं सोच सकता हूं

  • कमांड के आउटपुट को कैप्चर करें।
  • कमांड का रिटर्न मान जांचें और यदि वह विफल हो गया है
    • कैप्चर किए गए आउटपुट को प्रदर्शित करें।

इसे लागू करना हालांकि एक दिलचस्प परियोजना हो सकती है लेकिन शायद प्रश्नोत्तर से परे है।


एक समारोह के साथ उल्लेखनीय होना चाहिए। हम्म, मुझे इसे आजमाइए।
बेलमिन फर्नांडीज

1

किसी चीज के साथ कम होना tehcommand &>/tmp/$$ || cat /tmp/$$

निर्भर करता है कि आपको कितनी उपयोगिता / टाइपिंग चाहिए / आवश्यकता है। (जैसे इसे एक पाइप के रूप में उपयोग करना या तर्क द्वारा कमांड पास करना)

@zoredache लघु स्क्रिप्ट मूल रूप से इसके लिए एक आद्य-आवरण है, जो अधिक मजबूती, संचालन संगामना, आदि प्रदान करेगा


1

ऐसा प्रयास करें:

out=`command args...` || echo $out

2
मैं के रूप में लिखते हैंout="$(command args...)" || echo "$out"
kasperd
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.