पाइप कमांडर और अलग-अलग आदेशों के लिए stdout (न केवल फ़ाइलों के लिए)


11

मैं ldap के लिए एक बैकअप स्क्रिप्ट बना रहा हूँ। मैं चाहता हूं कि त्रुटियां / var / लॉग में फ़ाइल में जाएं और बैकअप फ़ोल्डर में किसी अन्य फ़ाइल पर जाने के लिए आउटपुट। वर्तमान में मैं एक अस्थायी फ़ाइल पर पुनर्निर्देशित कर रहा हूँ और फिर लॉग में अस्थायी फ़ाइल भेज रहा हूँ। मैं हालांकि एक लाइनर के रूप में यह करूँगा ...

/usr/bin/ldapsearch -x -LLL -b "dc=contoso,dc=com" "(objectclass=*)" -h ldap.server -v 2>>/tmp/ldaptmp.err |
  gzip -c > /mnt/backups/ldap/`date +\%Y\%m\%d`.ldif.gz || 
  logger -t ldapbackup -p local6.err error exit $?

cat /tmp/ldaptmp.err | grep -v "ldap_initialize( ldap://ldap.server )" | 
  grep -v "filter: (objectclass=\*)" |
  grep -v "requesting: All userApplication attributes" >$ERR_LOG
rm -f /tmp/ldaptmp.err

इस कमांड को 1 लाइन में संघनित करने के लिए अलग-अलग पाइपों में स्ट्रेडर और स्टडआउट को पुनर्निर्देशित करने के बारे में कोई विचार? या कोई बेहतर तरीका है?


1
इस प्रदर्शन पर एक नज़र डालें: stackoverflow.com/a/16283739/1765658 या इस अन्य अर्थ का नमूना: unix.stackexchange.com/a/84012/27653
F.

जवाबों:


10

जैसा कि यूनिक्स एसई में इस जवाब से संकेत मिलता है :

MyWeirdCommand.sh

#!/bin/bash
echo "1 2   3"
echo "4 5   6" >&2

testRedirection.sh:

#!/bin/bash
(./MyWeirdCommand.sh | cut -f1 >stdout.log) 3>&1 1>&2 2>&3 | cut -f3 >stderr.log

पैदावार की पैदावार:

  • stderr.log 6

  • stdout.log 1


24

बैश में, आप अपने लिए अतिरिक्त फ़ाइल डिस्क्रिप्टर का प्रबंधन करने के लिए प्रक्रिया प्रतिस्थापन का उपयोग कर सकते हैं। आप फ़ाइल डिस्क्रिप्टर स्वैप विधि की तुलना में इसे थोड़ा सा देख सकते हैं।

command > >(process_stdout) 2> >(process_stderr)

आपकी आज्ञा कुछ इस तरह दिख सकती है:

/usr/bin/ldapsearch -x -LLL -b "dc=contoso,dc=com" "(objectclass=*)" -h ldap.server -v \
  > >( \
    gzip -c > /mnt/backups/ldap/$(date '+%Y%m%d').ldif.gz || 
    logger -t ldapbackup -p local6.err error exit $?
  ) \
  2> >( \
    grep -Ev "ldap_initialize( ldap://ldap.server )|filter: (objectclass=\*)|requesting: All userApplication attributes" > "$err_log" \
  )

1
यह सही जवाब है।
माइकल मार्टिनेज

यदि आप किसी फ़ाइल में रीडायरेक्ट करने के बजाय चेन को रखना चाहते हैं, तो आप आउटपुट को वापस stderr पर पुनर्निर्देशित करना चाह सकते हैं: कुछ इस तरह: sh f>> (sed -e "s / ^ / stdout: /") 2> () sed -e "s / ^ / stderr: /"> और 2)
जेम्स मूर

>(process)नोटेशन का तकनीकी नाम क्या है ?
jchook

1
@jchook मैं पहले वाक्य में इस शब्द का उपयोग करता हूं: "प्रक्रिया प्रतिस्थापन"।
अगली सूचना तक रोक दिया गया।

1

यह है कि मैं स्टैडआउट और स्टडर को टाइमस्टैम्प के साथ अलग-अलग फाइलों में प्रिंट करता हूं (डेबियन मोरुटिल्स पैकेज से टीएस के लिए पाइपिंग):

(./my_little_script.pl | ts %F\ %T > out.log) 2>&1 | ts > err.log

PS अगर आपके पास ts नहीं है, तो अपना खुद का उपनाम बनाएं:

alias ts='while IFS= read -r line; do printf "%s %s\n" "$(date +%F\ %T)" "$line"; done'
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.