Stdout और Stderr को दो अलग-अलग धाराओं में प्रदर्शित करें


13

मैं नेत्रहीन अलग stdout और stderr के लिए एक रास्ता खोज रहा हूं, ताकि वे इंटरलेव न करें और ताकि उन्हें आसानी से पहचाना जा सके। आदर्श रूप से, stdout और stderr में स्क्रीन पर अलग-अलग क्षेत्र होते हैं, जिसमें वे प्रदर्शित होते हैं, जैसे अलग-अलग कॉलम में। उदाहरण के लिए, आउटपुट जो इस तरह दिखता होगा:

~$ some command
some useful output info
ERROR: an error
more output
ERROR: has occurred
another message
~$ 

इसके बजाय कुछ इस तरह दिखेगा:

~$ some command          |
some useful output info  |
more output              |  ERROR: an error
another message          |  ERROR: has occurred
~$                       |


यह सवाल एक ही बात नहीं पूछ रहा है, और कोई भी उत्तर यह नहीं प्रदान करता है कि यहां क्या पूछा गया है।
माइकल होमर

2
क्या धाराओं को दो अलग-अलग लॉग फ़ाइलों में पुनर्निर्देशित करना और फिर उन पर मल्टीटेल जैसी किसी चीज़ का उपयोग करना उपयोगी होगा? vanheusden.com/multitail
Kusalananda

क्या एनोटेट-आउटपुट उपयोगिता उपयोगी लगती है, या क्या आपको कॉलम में आउटपुट की आवश्यकता है?
जेफ स्कालर

जवाबों:


5

आप GNU screenकी खड़ी विभाजन सुविधा का उपयोग कर सकते हैं :

#! /bin/bash -
tmpdir=$(mktemp -d) || exit
trap 'rm -rf "$tmpdir"' EXIT INT TERM HUP

FIFO=$tmpdir/FIFO
mkfifo "$FIFO" || exit

conf=$tmpdir/conf

cat > "$conf" << 'EOF' || exit
split -v
focus
screen -t stderr sh -c 'tty > "$FIFO"; read done < "$FIFO"'
focus
screen -t stdout sh -c 'read tty < "$FIFO"; eval "$CMD" 2> "$tty"; echo "[Command exited with status $?, press enter to exit]"; read prompt; echo done > "$FIFO"'
EOF

CMD="$*"
export FIFO CMD

screen -mc "$conf"

उदाहरण के लिए उपयोग करने के लिए:

that-script 'ls / /not-here'

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

हम दूसरी विंडो के लिए एक नामित पाइप का उपयोग उसके पहले डिवाइस को संप्रेषित करने के लिए करते हैं, और दूसरे के लिए यह भी कहते हैं कि जब कमांड किया जाता है तो पहले वाले के लिए।

पाइप-आधारित दृष्टिकोणों की तुलना में अन्य लाभ यह है कि कमांड के stdout और stderr अभी भी tty उपकरणों से जुड़े हुए हैं, इसलिए यह बफरिंग को प्रभावित नहीं करता है। दोनों पैन को स्वतंत्र रूप से ऊपर और नीचे स्क्रॉल किया जा सकता है ( screenकॉपी कॉपी मोड का उपयोग करके )।

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

के मामले में bash, आप जो टाइप करते हैं उसकी प्रतिध्वनि दूसरी खिड़की पर भी दिखाई देगी क्योंकि उस प्रतिध्वनि का उत्पादन शेल पर होता है (साथ ही स्टैडर bashपर) के मामले में भी। कुछ अन्य गोले की तरह के साथ ksh93, यह पहली खिड़की पर (दिखाएगा गूंज , टर्मिनल डिवाइस ड्राइवर द्वारा उत्पादन, खोल नहीं) जब तक आप में खोल रखा emacsया viसाथ मोड set -o emacsया set -o vi


1

यह annotate-outputडेबियन ANNOTATE-OUTPUT (1) की स्क्रिप्ट पर आधारित एक बदसूरत समाधान है । निश्चित नहीं है कि यह वही है जिसे आप ढूंढ रहे हैं लेकिन इसके साथ कुछ शुरू हो सकता है:

#!/bin/bash 

readonly col=150 # column to start error output 

add_out ()
{
    while IFS= read -r line; do
        echo "$1: $line"
    done
    if [ ! -z "$line" ]; then
        echo -n "$1: $line"
    fi
}

add_err ()
{
    while IFS= read -r line; do
        printf "%*s  %s %s: %s\n" $col "|" "$1" "$line"
    done
    if [ ! -z "$line" ]; then
        printf "%*s %s: %s" $col "$1" "$line"
    fi
}

cleanup() { __st=$?; rm -rf "$tmp"; exit $__st; }
trap cleanup 0
trap 'exit $?' 1 2 13 15

tmp=$(mktemp -d --tmpdir annotate.XXXXXX) || exit 1
OUT=$tmp/out
ERR=$tmp/err

mkfifo $OUT $ERR || exit 1

add_out OUTPUT < $OUT &
add_err ERROR < $ERR &

echo "I: Started $@"
"$@" > $OUT 2> $ERR ; EXIT=$?
rm -f $OUT $ERR
wait

echo "I: Finished with exitcode $EXIT"

exit $EXIT

आप इसका उपयोग करके परीक्षण कर सकते हैं ./this_script another_scriptया command


1

मैं आपके प्रश्न के निम्नलिखित भाग का विश्लेषण करने का प्रयास करूंगा:

इसके बजाय कुछ इस तरह दिखेगा:

 ~ $ कुछ कमांड
 कुछ उपयोगी आउटपुट जानकारी |
 अधिक उत्पादन | त्रुटि: एक त्रुटि
 एक और संदेश | त्रुटि हो गई है
 ~ $ 

यदि कोई चाहता है कि आप जो चाहते हैं वह टूट जाए:

1) stdoutधारा प्रत्येक पंक्ति CR LFको एक '' के बजाय एक '' के साथ समाप्त नहीं करेगी । चरित्र। यह निश्चित रूप से दो धाराओं को एक साथ संरेखित नहीं करेगा, और संरेखण प्रश्न से बाहर है क्योंकि इसमें भविष्य की लाइनों की लंबाई का अनुमान लगाना होगा stdout, जो कि निश्चित रूप से असंभव है।

2) मान लें कि हम संरेखण के बारे में भूल जाते हैं तो हम stderrप्रत्येक लाइन की शुरुआत में "ERROR:" को जोड़ने वाली पाइपलाइन द्वारा संसाधित होने के बाद बस उत्पादन करेंगे । मुझे लगता है कि यह एक सरल स्क्रिप्ट बनाकर काफी आसान है और सुनिश्चित करें कि stderrइस स्क्रिप्ट के माध्यम से हमेशा सामने आता है।

लेकिन यह इस तरह एक उत्पादन पैदा करेगा:

~ $ कुछ कमांड
 कुछ उपयोगी आउटपुट जानकारी |
 अधिक उत्पादन | त्रुटि: एक त्रुटि
 एक और संदेश | त्रुटि हो गई है

जो वास्तव में सहायक नहीं है, क्या वह है? इसके अलावा, मुझे विश्वास नहीं है, यह वही है जो आप भी हैं!

प्रारंभिक प्रश्न के साथ समस्या, मुझे लगता है कि आप एक धारा में संलग्न प्रत्येक पंक्ति की धारावाहिक प्रकृति को ध्यान में नहीं रखते हैं, इस तथ्य के संबंध में कि दोनों धाराओं को अतुल्यकालिक रूप से लिखा जा सकता है।

मुझे विश्वास है कि निकटतम संभव समाधान का उपयोग करना होगा ncurses
देख।
[ Http://www.tldp.org/HOWTO/html_single/NCURSES-Programming-HOWTO/]
[ http://invisible-island.net/ncurses/ncurses-intro.html#updating]

ऐसा करने के लिए कि आप दोनों धाराओं को बफर करने की आवश्यकता के बाद क्या कर रहे हैं और दोनों बफर से तत्वों को लेने वाले तीसरे बफर का उत्पादन करने के लिए उन्हें संयोजित करें। फिर टर्मिनल स्क्रीन को मिटाकर तीसरे बफर को बदलने पर हर बार तीसरे बफर को टर्मिनल स्क्रीन में डंप करें। लेकिन यह तरीका ncursesकाम करता है, इसलिए पहिया को फिर से क्यों लगाया जाए और इसे वहां से न उठाया जाए?
किसी भी स्थिति में, आपको टर्मिनल स्क्रीन को पूरी तरह से चित्रित करने का तरीका संभालना होगा ! और स्क्रीन के पुनर्मुद्रित संस्करण में पाठ को पुन: डिज़ाइन करें जैसा आप चाहते हैं। टर्मिनल वर्णों के साथ वीडियो गेम की तरह।
मुझे आशा है कि मेरा उत्तर आपके बाद की सीमाओं को स्पष्ट करने में सहायक होगा ...
मुझे इसे दोहराने के लिए क्षमा करें, लेकिन आपने जो दिखाया उससे सबसे बड़ी समस्या यह है कि कैसे stdoutऔर stderrधाराओं के "प्रोसेसर" को पहले से पता चल जाएगा कि भविष्य की रेखाओं की लंबाई उन्हें ठीक से संरेखित करने के लिए इसमें जोड़ा गया है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.