सामान्य समस्या
मैं एक स्क्रिप्ट लिखना चाहता हूं जो उपयोगकर्ता के साथ बातचीत करती है, भले ही यह पाइप की एक श्रृंखला के बीच में हो।
ठोस उदाहरण
इसके विपरीत, यह एक file
या लेता है stdin
, लाइनों को प्रदर्शित करता है (लाइन नंबर के साथ), उपयोगकर्ता को एक चयन या लाइन नंबर इनपुट करने के लिए कहता है, और फिर संबंधित लाइनों को प्रिंट करता है stdout
। चलिए इस स्क्रिप्ट को कहते हैं selector
। फिर मूल रूप से, मैं ऐसा करने में सक्षम होना चाहता हूं
grep abc foo | selector > myfile.tmp
अगर foo
होता है
blabcbla
foo abc bar
quux
xyzzy abc
फिर selector
मुझे विकल्प पर (टर्मिनल में नहीं myfile.tmp
!) प्रस्तुत करता है
1) blabcbla
2) foo abc bar
3) xyzzy abc
Select options:
जिसके बाद मैं टाइप करता हूं
2-3
और अंत के साथ
foo abc bar
xyzzy abc
की सामग्री के रूप में myfile.tmp
।
मुझे एक चयनकर्ता स्क्रिप्ट मिली है और चल रही है, और मूल रूप से यह पूरी तरह से काम कर रहा है अगर मैं इनपुट और आउटपुट को रीडायरेक्ट नहीं करता हूं। इसलिए
selector foo
जैसा मैं चाहता हूँ वैसा ही व्यवहार करता है। हालांकि, जब उपरोक्त उदाहरण में एक साथ चीजों को पाइप करते हैं, selector
तो प्रस्तुत विकल्पों को प्रिंट myfile.tmp
करता है और ग्रीप किए गए इनपुट से चयन पढ़ने की कोशिश करता है।
मेरा दृष्टिकोण
मैंने के -u
झंडे का उपयोग करने की कोशिश की read
है
exec 4< /proc/$PPID/fd/0
exec 4> /proc/$PPID/fd/1
nl $INPUT >4
read -u4 -p"Select options: "
लेकिन यह वह नहीं करता है जो मुझे उम्मीद थी कि यह होगा।
प्रश्न: मुझे वास्तविक उपयोगकर्ता सहभागिता कैसे मिलेगी?
cmd | { some processing; read var </dev/tty; } | cmd
alias selector='{ TMPFILE=$(mktemp); cat > $TMPFILE; nl -s") " $TMPFILE | column -c $(tput cols); read -e -p"Select options: " < /dev/tty; rangeselect -v range="$REPLY" $TMPFILE; rm $TMPFILE; }'
बहुत अच्छा काम है। हालाँकि grep b foo | selector | wc -l
यहाँ पर टूट जाता है। किसी भी विचार कैसे तय करने के लिए? वैसे, rangeselect
जो मैंने इस्तेमाल किया है वह पास्टबिन . com / VAxTSSHs पर पाया जा सकता है । यह एक सरल AWK स्क्रिप्ट है, जो किसी दी गई श्रेणी की लिनन्यूट्स के अनुरूप फाइल की लाइनों को प्रिंट करता है। (रंग "3-10, 12,14,16-20" जैसी चीजें हो सकते हैं।)
alias
है, बल्कि selector() { all of that stuff...; }
एक समारोह में। कार्य के एक सरल कमांड में एक यौगिक कमांड पैक करते समय, सरल कमांड काalias
नाम बदलें ।