एक चर को निर्देशित डायलॉग बॉक्स इनपुट कैसे प्राप्त करें?


18

मैं खुद को बैश स्क्रिप्टिंग सिखा रहा हूं और एक मुद्दे पर चला गया हूं। मैंने 'रीड' कमांड का उपयोग करके, उपयोगकर्ता से इनपुट लेने के लिए एक स्क्रिप्ट लिखी है, और उस इनपुट को स्क्रिप्ट में बाद में उपयोग करने के लिए एक चर बना सकता है। स्क्रिप्ट काम करती है, लेकिन ...।

मैं 'संवाद' का उपयोग करके इसे सेटअप करने में सक्षम होना चाहूंगा। मुझे उसका पता चल गया

'संवाद - इनपुटबॉक्स' आउटपुट को 'स्टादर' तक पहुंचाएगा और उस इनपुट को एक चर के रूप में प्राप्त करने के लिए आपको इसे एक फ़ाइल पर निर्देशित करना होगा और फिर इसे पुनः प्राप्त करना होगा। मुझे यह समझाने के लिए कोड मिला है:

#!/bin/bash
dialog --inputbox \

"What is your username?" 0 0 2> /tmp/inputbox.tmp.$$

retval=$?

input=`cat /tmp/inputbox.tmp.$$`

rm -f /tmp/inputbox.tmp.$$

case $retval in
0)

echo "Your username is '$input'";;
1)

echo "Cancel pressed.";;

esac

मैं देखता हूं कि यह sdterr को 2> के साथ /tmp/inputbox.tmp.$$ पर भेज रहा है, लेकिन आउटपुट फाइल 'inputbox.tmp.21661' की तरह दिखती है। जब मैं कोशिश करता हूं और फाइल को कैट करता हूं तो यह मुझे एक त्रुटि देता है। इसलिए मैं अभी भी एक चर के रूप में --inputbox से उपयोगकर्ता इनपुट प्राप्त करने में असमर्थ हूं।

उदाहरण स्क्रिप्ट:

echo "  What app would you like to remove? "

read dead_app

sudo apt-get remove --purge $dead_app

तो जैसा कि आप देख सकते हैं कि यह एक मूल स्क्रिप्ट है। क्या चर को एक शब्द के रूप में प्राप्त करना संभव है dialog --inputbox?


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

जवाबों:


16

: DI इसे समझा नहीं सकता !!! यदि आप समझ सकते हैं कि वे उन्नत बैश-स्क्रिप्टिंग गाइड में क्या कह रहे हैं : अध्याय 20। I / O पुनर्निर्देशन , एक नया उत्तर लिखें और मैं आपको 50rep दूंगा :

exec 3>&1;
result=$(dialog --inputbox test 0 0 2>&1 1>&3);
exitcode=$?;
exec 3>&-;
echo $result $exitcode;

संदर्भ: बैश में डायलॉग चर को सही तरीके से नहीं पकड़ रहा है

^ उत्तर से @ उत्तर पुस्तिका (4 जुलाई 2014)

जैसा कि अनुरोध किया गया है, मैं यह समझाने की कोशिश करूंगा कि यह स्निपेट लाइन द्वारा क्या कर रहा है।

ध्यान दें कि मैं सभी ;अर्धविरामों को पंक्ति के अंत में छोड़ कर इसे सरल बना दूंगा , क्योंकि यदि हम प्रति पंक्ति एक कमांड लिखते हैं तो वे आवश्यक नहीं हैं।

I / O - स्ट्रीम:

सबसे पहले, आपको संचार धाराओं को समझने की आवश्यकता है। 10 धाराएँ हैं, जिनकी संख्या 0 से 9 तक है:

  • स्ट्रीम 0 ("STDIN"):
    "मानक इनपुट", कीबोर्ड से डेटा पढ़ने के लिए डिफ़ॉल्ट इनपुट स्ट्रीम।

  • स्ट्रीम 1 ("STDOUT"):
    "मानक आउटपुट", डिफ़ॉल्ट आउटपुट स्ट्रीम जिसका उपयोग टर्मिनल में सामान्य पाठ दिखाने के लिए किया जाता है।

  • स्ट्रीम 2 ("STDERR"): "मानक त्रुटि", टर्मिनल में विशेष उद्देश्यों के लिए त्रुटियों या अन्य पाठ को प्रदर्शित करने के लिए उपयोग की जाने वाली डिफ़ॉल्ट आउटपुट स्ट्रीम।


  • धाराएँ 3-9: अतिरिक्त, स्वतंत्र रूप से प्रयोग करने योग्य धाराएँ। वे डिफ़ॉल्ट रूप से उपयोग नहीं किए जाते हैं और तब तक मौजूद नहीं होते हैं जब तक कि कुछ उनका उपयोग करने का प्रयास नहीं करता है।

ध्यान दें कि सभी "स्ट्रीम" को आंतरिक रूप से फ़ाइल डिस्क्रिप्टर द्वारा दर्शाया जाता है /dev/fd(जो एक प्रतीकात्मक लिंक है /proc/self/fdजिसमें हर स्ट्रीम के लिए एक और प्रतीकात्मक लिंक शामिल है ... यह थोड़ा जटिल है और उनके व्यवहार के लिए महत्वपूर्ण नहीं है, इसलिए मैं यहां रुकता हूं।) मानक धाराएँ भी हैं /dev/stdin, /dev/stdoutऔर /dev/stderr(जो फिर से प्रतीकात्मक लिंक हैं, आदि ...)।

लिपी:

  • exec 3>&1

    बैश बिल्ट-इन execका उपयोग शेल में एक स्ट्रीम पुनर्निर्देशन लागू करने के लिए किया जा सकता है, इसका मतलब है कि यह सभी निम्न आदेशों को प्रभावित करता है। अधिक जानकारी के लिए, help execअपने टर्मिनल में दौड़ें ।

    इस विशेष मामले में, धारा 3 धारा 1 (STDOUT) पर पुनर्निर्देशित हो जाती है, जिसका अर्थ है कि हम जो कुछ भी धारा 3 में भेजते हैं, वह बाद में हमारे टर्मिनल में दिखाई देगा जैसे कि यह आमतौर पर STDOUT में मुद्रित होता है।

  • result=$(dialog --inputbox test 0 0 2>&1 1>&3)

    इस लाइन में कई भाग और वाक्य-संरचनाएँ शामिल हैं:

    • result=$(...)
      यह संरचना ब्रैकेट्स में कमांड को निष्पादित करती है और आउटपुट (STDOUT) को बैश वैरिएबल को असाइन करती है result। इसके माध्यम से पठनीय है $result। यह सब किसी भी तरह से वेजाइरी लूंग में वर्णित है man bash

    • dialog --inputbox TEXT HEIGHT WIDTH
      यह कमांड दिए गए TEXT, एक टेक्स्ट इनपुट फ़ील्ड और दो बटन OK और CANCEL के साथ एक TUI बॉक्स दिखाता है। यदि OK चयनित हो जाता है, तो कमांड स्टेटस 0 के साथ बाहर निकलता है और STDERR में दर्ज टेक्स्ट को प्रिंट करता है, यदि CANCEL चयनित हो जाता है, तो यह कोड 1 से बाहर निकल जाएगा और कुछ भी नहीं प्रिंट करेगा। अधिक जानकारी के लिए, पढ़ें man dialog

    • 2>&1 1>&3
      ये दो पुनर्निर्देशन आदेश हैं। उनकी व्याख्या दाएं से बाएं की जाएगी:

      1>&3 कस्टम स्ट्रीम 3 में कमांड की धारा 1 (STDOUT) को पुनर्निर्देशित करता है।

      2>&1 1 के बाद कमांड की धारा 2 (STDERR) को धारा 1 (STDOUT) पर पुनर्निर्देशित करता है।

      इसका मतलब है कि STDOUT में कमांड सब कुछ अब धारा 3 में दिखाई देता है, जबकि STDERR पर दिखाने के लिए जो कुछ भी था, वह अब STDOUT पर पुनर्निर्देशित हो जाता है।

    तो पूरी लाइन एक टेक्स्ट प्रॉम्प्ट प्रदर्शित करती है (STDOUT पर, जिसे 3 स्ट्रीम में रीडायरेक्ट किया गया है, जो शेल फिर से STDOUT में वापस रीडायरेक्ट करता है - exec 3>&1कमांड देखें ) और एंटर किए गए डेटा को असाइन करता है (STDERR के माध्यम से लौटा, फिर STDOUT पर रीडायरेक्ट किया गया) बैश चर को result

  • exitcode=$?

    यह कोड dialogआरक्षित बैश वैरिएबल $?(हमेशा अंतिम एग्जिट कोड) के माध्यम से पहले से निष्पादित कमांड के एक्जिट कोड (यहां से ) को प्राप्त करता है और बस इसे हमारे बैश वैरिएबल में संग्रहीत करता है exitcode। इसे $exitcodeफिर से पढ़ा जा सकता है । आप इसके बारे में अधिक जानकारी खोज सकते हैं man bash, लेकिन इसमें कुछ समय लग सकता है ...

  • exec 3>&-

    बैश बिल्ट-इन execका उपयोग शेल में एक स्ट्रीम पुनर्निर्देशन लागू करने के लिए किया जा सकता है, इसका मतलब है कि यह सभी निम्न आदेशों को प्रभावित करता है। अधिक जानकारी के लिए, help execअपने टर्मिनल में दौड़ें ।

    इस विशेष मामले में, धारा 3 "धारा -" के लिए पुनर्निर्देशित हो जाती है, जिसका अर्थ है कि इसे बंद कर दिया जाना चाहिए। धारा 3 में भेजे गए डेटा को अब से कहीं भी पुनर्निर्देशित नहीं किया जाएगा।

  • echo $result $exitcode

    यह सरल echoकमांड (अधिक जानकारी man echo) केवल दो बैश चर की सामग्री resultऔर exitcodeSTDOUT को प्रिंट करता है । जैसा कि हमारे यहाँ कोई स्पष्ट या निहित धारा पुनर्निर्देशन नहीं है, वे वास्तव में STDOUT पर दिखाई देंगे और इसलिए टर्मिनल में प्रदर्शित होंगे। क्या चमत्कार है! ;-)

सारांश:

सबसे पहले, हम शेल को सेट करने के लिए कस्टम स्ट्रीम 3 पर भेजे गए सब कुछ को रीडायरेक्ट करने के लिए खोल देते हैं, ताकि यह हमारे टर्मिनल में दिखाई दे।

फिर हम dialogकमांड चलाते हैं , इसकी मूल STDOUT को हमारे कस्टम स्ट्रीम 3 पर पुनर्निर्देशित करते हैं, क्योंकि इसे अंत में प्रदर्शित करने की आवश्यकता होती है, लेकिन हमें अस्थायी रूप से कुछ और के लिए STDOUT स्ट्रीम का उपयोग करने की आवश्यकता होती है।
हम कमांड के मूल STDERR को रीडायरेक्ट करते हैं, जहाँ संवाद विंडो का उपयोगकर्ता इनपुट वापस आ जाता है, बाद में STDOUT में।
अब हम STDOUT (जो STDERR से पुनर्निर्देशित डेटा रखता है) पर कब्जा कर सकते हैं और इसे हमारे चर में संग्रहीत कर सकते हैं $result। इसमें अब वांछित उपयोगकर्ता इनपुट शामिल है!

हम dialogकमांड का एग्जिट कोड भी चाहते हैं , जो हमें दिखाता है कि ओके या कैंसिल पर क्लिक किया गया था या नहीं। यह मान आरक्षित बैश चर में प्रस्तुत किया गया है $?और हम इसे अपने स्वयं के चर में कॉपी कर लेते हैं $exitcode

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

अंत में, हम आम तौर पर टर्मिनल के लिए दोनों चर $result(डायलॉग विंडो के उपयोगकर्ता इनपुट) और $exitcode(0 के लिए ठीक है, 1 के लिए सामग्री) की सामग्री का उत्पादन करते हैं ।


मुझे लगता है कि उपयोग execकरना अनावश्यक रूप से जटिल है। क्यों न हम इसके --stdoutलिए विकल्प चुनें dialogया इसके आउटपुट को रीडायरेक्ट करें 2>&1 >/dev/tty?
जर्नो

कृपया मेरा उत्तर देखें ।
जर्नो

3
बहुत बढ़िया जवाब! हालांकि, मेरा मानना ​​है कि आपके पास एक नोट है जो गलत है - आप कहते हैं कि "उन्हें सही से बाएं की व्याख्या की जाएगी" लेकिन मेरा मानना ​​है कि यह सच नहीं है। बैश मैनुअल gnu.org/software/bash/manual/html_node/Redirections.html से यह इंगित करता है कि पुनर्निर्देशन का सामना तब होता है जब उनका सामना होता है (यानी बाएँ से दाएँ)
ralfthewise

14

संवाद के अपने औजारों का उपयोग करना:

यदि आप डायलॉग के लिए मैन पेज पढ़ते हैं, तो विकल्प है --output-fd, जो आपको स्पष्ट रूप से सेट करने की अनुमति देता है कि आउटपुट कहां जाता है (STDOUT 1, STDERR 2), बजाय डिफ़ॉल्ट रूप से STDERR के।

Bellow आप मुझे नमूना dialogआदेश चलाते हुए देख सकते हैं , स्पष्ट रूप से यह बताते हुए कि आउटपुट को फाइल डिस्क्रिप्टर 1 में जाना चाहिए, जो मुझे इसे MYVAR में सहेजने की अनुमति देता है।

MYVAR=$(dialog --inputbox "THIS OUTPUT GOES TO FD 1" 25 25 --output-fd 1)

यहाँ छवि विवरण दर्ज करें

नामित पाइप का उपयोग करना

वैकल्पिक दृष्टिकोण जिसमें बहुत अधिक छिपी हुई क्षमता है, जिसे नामित पाइप के रूप में जाना जाता है ।

#!/bin/bash

mkfifo /tmp/namedPipe1 # this creates named pipe, aka fifo

# to make sure the shell doesn't hang, we run redirection 
# in background, because fifo waits for output to come out    
dialog --inputbox "This is an input box  with named pipe" 40 40 2> /tmp/namedPipe1 & 

# release contents of pipe
OUTPUT="$( cat /tmp/namedPipe1  )" 


echo  "This is the output " $OUTPUT
# clean up
rm /tmp/namedPipe1 

यहाँ छवि विवरण दर्ज करें

वैकल्पिक दृष्टिकोण के साथ user.dz के उत्तर का अधिक गहराई से अवलोकन

User.dz और ByteCommander की उस द्वारा दिए गए स्पष्टीकरण का मूल उत्तर दोनों एक अच्छा समाधान और यह क्या करता है का अवलोकन प्रदान करते हैं। हालाँकि, मेरा मानना ​​है कि एक गहन विश्लेषण यह समझाने में लाभदायक हो सकता है कि यह क्यों काम करता है।

सबसे पहले, दो चीजों को समझना महत्वपूर्ण है: हम किस समस्या को हल करने की कोशिश कर रहे हैं और शेल तंत्र के अंतर्निहित कामकाज क्या हैं जिसके साथ हम काम कर रहे हैं। कार्य कमांड प्रतिस्थापन के माध्यम से एक कमांड के आउटपुट को कैप्चर करना है। सभी को पता है कि सरलीकृत अवलोकन के तहत, कमांड प्रतिस्थापन stdoutएक कमांड पर कब्जा कर लेते हैं और इसे कुछ और द्वारा पुन: उपयोग किया जाता है। इस मामले में, result=$(...)भाग ...को एक चर नाम से जो भी कमांड निर्दिष्ट किया गया है उसके आउटपुट को सहेजना चाहिए result

हुड के नीचे, कमांड प्रतिस्थापन वास्तव में पाइप के रूप में कार्यान्वित किया जाता है, जहां एक बच्चे की प्रक्रिया होती है (वास्तविक कमांड जो चलती है) और पढ़ने की प्रक्रिया (जो चर को आउटपुट बचाता है)। यह सिस्टम कॉल के एक सरल ट्रेस के साथ स्पष्ट है। ध्यान दें कि फ़ाइल डिस्क्रिप्टर 3 पाइप का रीड एंड है, जबकि 4 राइट एंड है। की बाल प्रक्रिया के लिए echo, जो इसे लिखता है stdout- फाइल डिस्क्रिप्टर 1, वह फाइल डिस्क्रिप्टर वास्तव में फाइल डिस्क्रिप्टर 4 की कॉपी है, जो पाइप का राइट-एंड है। ध्यान दें कि stderrयहां एक भूमिका नहीं है, केवल इसलिए कि यह stdoutकेवल एक पाइप कनेक्ट है ।

$ strace -f -e pipe,dup2,write,read bash -c 'v=$(echo "X")'
...
pipe([3, 4])                            = 0
strace: Process 6200 attached
[pid  6199] read(3,  <unfinished ...>
[pid  6200] dup2(4, 1)                  = 1
[pid  6200] write(1, "X\n", 2 <unfinished ...>
[pid  6199] <... read resumed> "X\n", 128) = 2
[pid  6200] <... write resumed> )       = 2
[pid  6199] read(3, "", 128)            = 0
[pid  6200] +++ exited with 0 +++
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=6200, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
+++ exited with 0 +++

चलो एक दूसरे के लिए मूल उत्तर पर वापस जाएं। चूंकि अब हम जानते dialogहैं कि TUI बॉक्स को लिखता है stdout, उत्तर देता है stderr, और कमांड प्रतिस्थापन के भीतर stdoutकहीं और पाइप किया जाता है, हमारे पास पहले से ही समाधान का हिस्सा है - हमें फ़ाइल डिस्क्रिप्टर को इस तरह से stderrफिर से तैयार करने की आवश्यकता है जो रीडर प्रक्रिया के लिए पाइप किया जाएगा। यह 2>&1उत्तर का हिस्सा है। हालांकि, हम टीयूआई बॉक्स के साथ क्या करते हैं?

dup2()यहीं पर फाइल डिस्क्रिप्टर 3 आता है। syscall हमें फाइल डिस्क्रिप्टर को डुप्लिकेट करने की अनुमति देता है, जिससे वे प्रभावी रूप से एक ही स्थान पर संदर्भित होते हैं, फिर भी हम उन्हें अलग से जोड़ सकते हैं। उन प्रक्रियाओं के फ़ाइल डिस्क्रिप्टर जो टर्मिनल से जुड़े होते हैं, वास्तव में विशिष्ट टर्मिनल डिवाइस की ओर इशारा करते हैं। यह स्पष्ट है अगर तुम करते हो

$ ls -l /proc/self/fd
total 0
lrwx------ 1 user1 user1 64 Aug 20 10:30 0 -> /dev/pts/5
lrwx------ 1 user1 user1 64 Aug 20 10:30 1 -> /dev/pts/5
lrwx------ 1 user1 user1 64 Aug 20 10:30 2 -> /dev/pts/5
lr-x------ 1 user1 user1 64 Aug 20 10:30 3 -> /proc/6424/fd

/dev/pts/5मेरा वर्तमान छद्म टर्मिनल उपकरण कहां है। इस प्रकार, अगर हम किसी तरह इस गंतव्य को बचा सकते हैं, तो हम अभी भी टर्मिनल स्क्रीन पर टीयूआई बॉक्स लिख सकते हैं। वही exec 3>&1करता है। जब आप command > /dev/nullउदाहरण के लिए पुनर्निर्देशन के साथ एक कमांड को कॉल करते हैं , तो शेल यह stdout फाइल डिस्क्रिप्टर पास करता है और फिर dup2()उस फाइल डिस्क्रिप्टर को लिखने के लिए उपयोग करता है /dev/nullexecआदेश प्रदर्शन कुछ के लिए इसी तरहdup2() पूरे खोल सत्र के लिए फ़ाइल वर्णनकर्ता, इस प्रकार किसी भी कमांड इनहेरिट पहले से ही निर्देशित कर दिये फ़ाइल वर्णनकर्ता बना रही है। उसी के साथ exec 3>&1। फाइल डिस्क्रिप्टर 3अब कंट्रोलिंग टर्मिनल को इंगित / इंगित करेगा, और उस शेल सत्र में चलने वाले किसी भी कमांड को इसके बारे में पता चल जाएगा।

जब ऐसा result=$(dialog --inputbox test 0 0 2>&1 1>&3);होता है, तो शेल डायलॉग लिखने के लिए एक पाइप बनाता है, लेकिन 2>&1सबसे पहले कमांड की फाइल डिस्क्रिप्टर 2 को उस पाइप के राइट फाइल डिस्क्रिप्टर पर डुप्लिकेट किया जाएगा (इस प्रकार आउटपुट को पाइप के अंत और वेरिएबल में पढ़ने के लिए जाना जाता है) , जबकि फ़ाइल डिस्क्रिप्टर 1 को 3 पर डुप्लिकेट किया जाएगा। यह फ़ाइल डिस्क्रिप्टर 1 को अभी भी कंट्रोलिंग टर्मिनल को संदर्भित करेगा, और टीयूआई संवाद स्क्रीन पर दिखाई देगा।

अब, प्रक्रिया के वर्तमान नियंत्रण टर्मिनल के लिए वास्तव में एक शॉर्ट-हैंड है, जो है /dev/tty। इस प्रकार, फ़ाइल विवरणकों के उपयोग के बिना समाधान को सरल बनाया जा सकता है, बस इसमें:

result=$(dialog --inputbox test 0 0 2>&1 1>/dev/tty);
echo "$result"

याद रखने योग्य मुख्य बातें:

  • फ़ाइल डिस्क्रिप्टर प्रत्येक कमांड द्वारा शेल से विरासत में मिले हैं
  • कमांड प्रतिस्थापन को पाइप के रूप में लागू किया जाता है
  • डुप्लिकेट फ़ाइल डिस्क्रिप्टर एक ही मूल के रूप में एक ही स्थान को संदर्भित करेगा, लेकिन हम प्रत्येक फ़ाइल डिस्क्रिप्टर को अलग से जोड़ सकते हैं

यह सभी देखें


मैनपेज यह भी कहता है कि --stdoutविकल्प खतरनाक हो सकता है और कुछ प्रणालियों पर आसानी से विफल हो रहा है, और मुझे लगता --output-fd 1है कि वही कर रहा है : --stdout: Direct output to the standard output. This option is provided for compatibility with Xdialog, however using it in portable scripts is not recommended, since curses normally writes its screen updates to the standard output. If you use this option, dialog attempts to reopen the terminal so it can write to the display. Depending on the platform and your environment, that may fail.- हालांकि, नामित पाइप विचार अच्छा है!
बाइट कमांडर

@ByteCommander "मे फेल" एक बहुत ठोस नहीं है, क्योंकि यह उदाहरण प्रदान नहीं करता है। इसके अलावा, वे इस बारे में कुछ भी उल्लेख नहीं करते हैं --output-fd, कि मेरे पास यहां जो विकल्प है, वह नहीं --stdout। दूसरा, संवाद पहले स्टडआउट पर तैयार किया जा रहा है, जो आउटपुट दिया गया है वह दूसरा है। हम एक ही समय में ये दोनों काम नहीं करते हैं। हालाँकि, --output-fd विशेष रूप से fd 1 (STDOUT) का उपयोग करने के लिए किसी की आवश्यकता नहीं होती है। इसे आसानी से किसी अन्य फ़ाइल डिस्क्रिप्टर पर पुनः निर्देशित किया जा सकता है
सर्गी कोलोडाज़हनी

मुझे यकीन नहीं है, शायद यह हर जगह काम करता है, शायद यह ज्यादातर सिस्टम पर काम करता है। यह मेरा काम करता है और मैनपेज कहता है कि सावधानी के साथ एक समान विकल्प का उपयोग करें, मुझे यह सब पता है। लेकिन जैसा कि मैंने पहले ही कहा, +1 वैसे भी नामित पाइपों के लिए योग्य है।
बाइट कमांडर

मुझे यहाँ टिप्पणी करनी चाहिए, कुछ संतुलन रखने के लिए। मेरे लिए, यह एकमात्र प्रत्यक्ष कैनोनिकल उत्तर है (1) यह केवल एक ही टूल का उपयोग करता है और यह बिना किसी बाहरी टूल के विकल्प लागू करता है (2) यह उबंटू में काम करता है और सभी एयू के बारे में है। : / दुख की बात है कि ओपी इस सवाल को छोड़ देता है।
user.dz

यहां नियमित फ़ाइल के बजाय नामित पाइप का उपयोग करने का क्या फायदा है? क्या आप उपयोग के बाद पाइप को हटाना नहीं चाहते हैं?
जारो

7

: DI इसे समझा नहीं सकता !!! यदि आप समझ सकते हैं कि वे संदर्भ में क्या कह रहे हैं: उन्नत बैश-स्क्रिप्टिंग गाइड: अध्याय 20। I / O पुनर्निर्देशन , एक नया उत्तर लिखें और मैं आपको 50rep दूंगा

बाउंटी दिया गया था, स्पष्टीकरण के लिए बाइटकॉमर के जवाब देखें । :) यह इतिहास का एक हिस्सा है।

exec 3>&1;
result=$(dialog --inputbox test 0 0 2>&1 1>&3);
exitcode=$?;
exec 3>&-;
echo $result $exitcode;

स्रोत: बाश में डायलॉग चर को सही तरीके से नहीं पकड़ रहा है
संदर्भ: उन्नत बैश-स्क्रिप्टिंग गाइड: अध्याय 20। I / I नया विवरण


क्या यह प्रस्ताव अभी भी मान्य है? मुझे लगता है मैं समझा सकता है क्या तुम वहाँ डेढ़ साल पहले मिला ... :-)
बाइट कमांडर

@ByteCommander, लेकिन फिर भी अगर आप यह प्रदान कर सकते हैं, तो मैं आपको दे दूंगा, मैं अपने शब्दों में लिखूंगा: डी।
user.dz

@ByteCommander, कृपया, पोस्ट करने के बाद मुझे पिंग करें।
user.dz

1
ख़त्म होना! askubuntu.com/a/704616/367990 मुझे आशा है कि आप सब कुछ समझेंगे और "यूरेका" का आनंद लेंगे। पल। :-D एक टिप्पणी छोड़ दो अगर कुछ भी अस्पष्ट नहीं छोड़ा गया था।
बाइट कमांडर

4

यह मेरे लिए काम करता है:

#!/bin/bash
input=$(dialog --stdout --inputbox "What is your username?" 0 0)
retval=$?

case $retval in
${DIALOG_OK-0}) echo "Your username is '$input'.";;
${DIALOG_CANCEL-1}) echo "Cancel pressed.";;
${DIALOG_ESC-255}) echo "Esc pressed.";;
${DIALOG_ERROR-255}) echo "Dialog error";;
*) echo "Unknown error $retval"
esac

मैनुअल पेज पेज के dialogबारे में बताता है:

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

क्या कोई बता सकता है कि यह किस मंच या वातावरण में काम नहीं करता है? क्या इसके बजाय dialogआउटपुट को पुनर्निर्देशित 2>&1 >/dev/ttyकरना बेहतर है?


4

यदि कोई व्यक्ति Google से यहां आया है, और यद्यपि यह प्रश्न विशेष रूप से बैश के लिए पूछता है, तो यहां एक और विकल्प है:

आप ज़ेनिटी का उपयोग कर सकते हैं । ज़ेनिटी एक ग्राफिकल यूटिलिटी है जिसका उपयोग बैश स्क्रिप्ट के अंदर किया जा सकता है। लेकिन निश्चित रूप से इसके लिए X सर्वर की आवश्यकता होगी क्योंकि user877329 ने सही बताया है।

sudo apt-get install zenity

फिर आपकी स्क्रिप्ट में:

RETVAL=`zenity --entry --title="Hi" --text="What is your username"`

उपयोगी लिंक


3
जब तक कोई X सर्वर नहीं है
user877329

1
ओपी के बारे में जानना चाहता है dialog। जैसे मैं आते हैं और आप से पूछना? "मैं यह कैसे लिख सकते हैं और अजगर में है कि है" यह है, लेकिन तुम मुझे मार दे - मैं बहुत खुश इस अलग तरह से किया जा सकता है, लेकिन है कि मैं क्या पूछ रहा हूँ नहीं है
सर्गी Kolodyazhnyy

@ आपकी टिप्पणी अमान्य है, मेरा जवाब नहीं है: उपयोगिता ओपी द्वारा पूछे गए समाधान के लिए पूरी तरह से वैध और सरल विकल्प प्रदान करती है।
वेटावर

3

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

#!/bin/bash
t=$(mktemp -t inputbox.XXXXXXXXX) || exit
trap 'rm -f "$t"' EXIT         # remove temp file when done
trap 'exit 127' HUP STOP TERM  # remove if interrupted, too
dialog --inputbox \
    "What is your username?" 0 0 2>"$t"
retval=$?
input=$(cat "$t")  # Prefer $(...) over `...`
case $retval in
  0)    echo "Your username is '$input'";;
  1)    echo "Cancel pressed.";;
esac

इस मामले में, अस्थायी फ़ाइल से बचना एक बेहतर समाधान होगा, लेकिन कई स्थितियाँ ऐसी होंगी जहाँ आप किसी अस्थायी फ़ाइल से बच नहीं सकते।

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