কীভাবে ডায়ালগ বক্স ইনপুটটি ভেরিয়েবলের নির্দেশিত হয়?


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

আমি দেখতে পাচ্ছি যে এটি 2> সহ /tmp/inputbox.tmp.$$ এ sdterr প্রেরণ করছে, তবে আউটপুট ফাইলটি 'ইনপুটবক্স.টিএমপি .1616' এর মতো দেখাচ্ছে। আমি যখন ফাইলটি চেষ্টা করি এবং ক্যাট করি তখন এটি আমাকে একটি ত্রুটি দেয়। সুতরাং আমি এখনও ভেরিয়েবল হিসাবে - ইনপুটবক্স থেকে ব্যবহারকারী ইনপুট পেতে অক্ষম।

উদাহরণ স্ক্রিপ্ট:

echo "  What app would you like to remove? "

read dead_app

sudo apt-get remove --purge $dead_app

সুতরাং আপনি এটি দেখতে পারেন এটি একটি প্রাথমিক স্ক্রিপ্ট। এটি কি কোনও শব্দ হিসাবে পরিবর্তনশীল পাওয়া সম্ভব dialog --inputbox?


আমার অভিজ্ঞতায় স্ক্রিপ্টটি ঠিকঠাক কাজ করে, যদি আপনি ২ য় লাইনের পরে খালি লাইনটি সরিয়ে থাকেন। বিকল্পভাবে, আপনি mktempএকটি অস্থায়ী ফাইল তৈরি করতে কমান্ডটি ব্যবহার করতে পারেন ।
জার্নো

উত্তর:


16

: ডিআই এটি ব্যাখ্যা করতে পারে না !!! যদি আপনি বুঝতে পারেন যে তারা কীভাবে অ্যাডভান্সড ব্যাশ-স্ক্রিপ্টিং গাইডে বলছেন : অধ্যায় 20 I 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 - স্ট্রিমগুলি:

প্রথমত, আপনার যোগাযোগের স্ট্রিমগুলি বুঝতে হবে। 0 থেকে 9 পর্যন্ত সংখ্যাযুক্ত 10 টি স্ট্রিম রয়েছে:

  • স্ট্রিম 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 (এসটিডিওউট) এ পুনঃনির্দেশিত হয়, এর অর্থ আমরা পরে 3 স্ট্রিমে প্রেরণ করি এমন সমস্ত কিছু আমাদের টার্মিনালে উপস্থিত হবে যেন এটি স্টাডিউটে সাধারণত মুদ্রিত হয়েছিল।

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

    এই লাইনটি অনেকগুলি অংশ এবং সিনট্যাক্টিকাল স্ট্রাকচার নিয়ে গঠিত:

    • result=$(...)
      এই কাঠামোটি বন্ধনীগুলিতে কমান্ড কার্যকর করে এবং আউটপুট (STDOUT) বাশ ভেরিয়েবলকে বরাদ্দ করে result। এটি মাধ্যমে পাঠযোগ্য $result। এগুলি সমস্ত কিছু একরকম ভিজিরি লুংয়ে বর্ণিত হয়েছে man bash

    • dialog --inputbox TEXT HEIGHT WIDTH
      এই কমান্ডটি প্রদত্ত টেক্সট, একটি পাঠ্য ইনপুট ক্ষেত্র এবং দুটি বোতাম ওকে এবং ক্যানসেল সহ একটি টিউআই বাক্স দেখায়। যদি ওকে নির্বাচিত হয়ে যায়, কমান্ডটি 0 টি স্থিতি সহ প্রস্থান করে এবং প্রবেশ করা পাঠ্যটি এসটিডিআরআর প্রিন্ট করে, যদি ক্যানসেল নির্বাচিত হয়, এটি কোড 1 সহ প্রস্থান করবে এবং কিছুই প্রিন্ট করবে না। আরও তথ্যের জন্য, পড়ুন man dialog

    • 2>&1 1>&3
      এটি দুটি পুনর্নির্দেশ কমান্ড। ডান থেকে বামে তাদের ব্যাখ্যা করা হবে:

      1>&3 কমান্ডের স্ট্রিম 1 (STDOUT) কে কাস্টম স্ট্রিম 3 এ পুনঃনির্দেশ করে।

      2>&1 এরপরে কমান্ডের স্ট্রিম 2 (STDERR) 1 (STDOUT) প্রবাহে পুনঃনির্দেশ করে।

      এর অর্থ হ'ল এসটিডিআউট-এ কমান্ড মুদ্রিত সমস্ত কিছুই এখন 3 স্ট্রিমে প্রদর্শিত হবে, যখন এসটিডিআরআর-তে প্রদর্শিত হ'ল উদ্দেশ্যে করা সমস্ত কিছু এখন এসটিডিআউট-এ পুনঃনির্দেশিত হয়।

    সুতরাং পুরো লাইনটি একটি পাঠ্য প্রম্পট প্রদর্শন করে (STDOUT এ, যা স্ট্রিম 3 এ পুনঃনির্দেশিত হয়েছিল, যা শেলটি আবার শেষে exec 3>&1STDOUT এ পুনঃনির্দেশ করে - কমান্ডটি দেখুন) এবং প্রবেশ করা ডেটা বরাদ্দ করে (এসটিডিআরআর দিয়ে ফিরে, তারপরে পুনরায় পুনঃনির্দেশিত) বাশ ভেরিয়েবলের কাছে result

  • exitcode=$?

    এই কোডটি পূর্ব নির্বাহিত কমান্ডের প্রস্থান কোডটি (এখানে থেকে dialog) সংরক্ষিত বাশ ভেরিয়েবলের মাধ্যমে পুনরুদ্ধার করে $?(সর্বদা সর্বশেষ প্রস্থান কোডটি ধারণ করে) এবং কেবল এটি আমাদের নিজস্ব বাশ ভেরিয়েবলে সঞ্চয় করে exitcode। এটি $exitcodeআবার মাধ্যমে পড়া যেতে পারে । আপনি এতে আরও তথ্যের জন্য অনুসন্ধান করতে পারেন man bash, তবে এতে কিছুটা সময় লাগতে পারে ...

  • exec 3>&-

    বাশ অন্তর্নির্মিতটি execশেলটিতে স্ট্রিম রিডাইরেকশন প্রয়োগ করতে ব্যবহার করা যেতে পারে, এর অর্থ এটি নিম্নলিখিত সমস্ত কমান্ডকে প্রভাবিত করে। আরও তথ্যের জন্য, help execআপনার টার্মিনালে চালান ।

    এই বিশেষ ক্ষেত্রে, স্ট্রিম 3টি "স্ট্রিম -" এ পুনঃনির্দেশিত হয়, যার অর্থ এটি বন্ধ করা উচিত। 3 স্ট্রিমে প্রেরিত ডেটা এখন থেকে আর কোথাও পুনর্নির্দেশ করা হবে না।

  • echo $result $exitcode

    এই সাধারণ echoকমান্ডটি (আরও তথ্যের উপরে man echo) কেবল দুটি ব্যাশ ভেরিয়েবলের resultএবং exitcodeSTDOUT এর সামগ্রী মুদ্রণ করে । যেহেতু এখানে আর কোনও স্পষ্ট বা অন্তর্নিহিত স্ট্রিম পুনর্নির্দেশগুলি নেই, সেগুলি সত্যই STDOUT এ উপস্থিত হবে এবং তাই কেবল টার্মিনালে প্রদর্শিত হবে। কি অবাক ব্যাপার! ;-)

সারসংক্ষেপ:

প্রথমত, আমরা কাস্টম স্ট্রিমে প্রেরিত সমস্ত কিছু 3 টি পুনঃনির্দেশের জন্য আমরা শেলটি সেট আপ করি STDOUT এ, যাতে এটি আমাদের টার্মিনালে প্রদর্শিত হয়।

তারপরে আমরা dialogকমান্ডটি চালাচ্ছি , এর মূল STDOUTটিকে আমাদের কাস্টম স্ট্রিম 3 এ পুনঃনির্দেশ করুন, কারণ এটি শেষের দিকে প্রদর্শিত হওয়া দরকার, তবে অস্থায়ীভাবে অন্য কোনও কিছুর জন্য আমাদের STDOUT স্ট্রিমটি ব্যবহার করা দরকার।
আমরা কমান্ডের মূল এসটিডিআরআর পুনর্নির্দেশ করি যেখানে ডায়লগ উইন্ডোর ব্যবহারকারী ইনপুট ফিরে আসে, পরে এটি 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/Redireitions.html থেকে এটি ইঙ্গিত দেয় যে পুনরায়নির্দেশগুলি সম্মুখীন হওয়ার সাথে সাথে ঘটে (অর্থাত্ বাম থেকে ডানদিকে)
র‌্যালফটিওয়াইজ

14

কথোপকথনের নিজস্ব সরঞ্জামগুলি ব্যবহার করে: - আউটপুট-এফডি পতাকা

আপনি যদি ডায়লগের জন্য ম্যান পৃষ্ঠাটি পড়েন, তবে বিকল্প রয়েছে --output-fd, যা আপনাকে স্পষ্টভাবে সেট করতে দেয় যেখানে আউটপুট কোথায় যায় (STDOUT 1, STDERR 2), পরিবর্তে ডিফল্টর পরিবর্তে STDERR এ যায়।

বেলো আপনি আমাকে নমুনা dialogকমান্ডটি চালিত দেখতে পাচ্ছেন , স্পষ্টভাবে উল্লেখ করে যে আউটপুটটি অবশ্যই ফাইল বর্ণনাকারী 1 এ যেতে হবে, যা আমাকে এটি আমারওয়াইরে সংরক্ষণ করতে দেয়।

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 এর উত্তর সম্পর্কে আরও গভীরতর ওভারভিউ

ইউজার.ডিজেড দ্বারা মূল উত্তর এবং বাইটকম্যান্ডারের ব্যাখ্যা উভয়ই এটির একটি ভাল সমাধান এবং ওভারভিউ সরবরাহ করে। তবে, আমি বিশ্বাস করি যে এটি কেন কাজ করে তা ব্যাখ্যা করার জন্য একটি গভীর বিশ্লেষণ সুবিধাজনক হতে পারে ।

প্রথমত, দুটি বিষয় বোঝা গুরুত্বপূর্ণ: আমরা কী সমস্যাটি সমাধান করার চেষ্টা করছি এবং শেল প্রক্রিয়াগুলির অন্তর্নিহিত কাজগুলি যা আমরা পরিচালনা করছি। কাজ হ'ল কমান্ড প্রতিস্থাপনের মাধ্যমে একটি কমান্ডের আউটপুট ক্যাপচার করা। সরলতর পর্যালোচনার অধীনে যা সবাই জানেন, কমান্ডের বিকল্পগুলি stdoutএকটি কমান্ড ক্যাপচার করে এবং অন্য কিছু দ্বারা এটি পুনরায় ব্যবহার করা যাক let এই ক্ষেত্রে, 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টিউআই বাক্সটি লিখেছিল stdout, এর জবাব দিয়েছে stderrএবং কমান্ড প্রতিস্থাপনের মধ্যে stdoutঅন্য কোথাও পাইপ দেওয়া হয়েছে, আমাদের ইতিমধ্যে সমাধানটির কিছু অংশ রয়েছে - আমাদের ফাইল বিবরণকারীকে এমনভাবে পুনর্বিবেচনা করা দরকার stderrযা পাঠক প্রসেসে পাইপ করা হবে। এটি 2>&1উত্তরের অংশ। তবে, টিউআই বাক্সটি দিয়ে আমরা কী করব?

ফাইল বর্ণনাকারী 3 এখানে আসে That's dup2()সিস্কল আমাদের ফাইল বর্ণনাকারীদের নকল করতে দেয়, সেগুলি কার্যকরভাবে একই জায়গায় উল্লেখ করা যায়, তবুও আমরা তাদের আলাদাভাবে ম্যানিপুলেট করতে পারি। প্রসেসগুলির ফাইল বর্ণনাকারীগুলি যেগুলি নিয়ন্ত্রণ করে টার্মিনাল সংযুক্ত থাকে সেগুলি নির্দিষ্ট টার্মিনাল ডিভাইসে নির্দেশ করে। আপনি যদি এটি করেন তবে তা স্পষ্ট

$ 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উদাহরণস্বরূপ পুনঃনির্দেশ সহ একটি কমান্ড কল করার সময় , শেল এটি স্টডআউট ফাইল বর্ণনাকারী পাস করে এবং তারপরে dup2()সেই ফাইলটির বিবরণী লেখার জন্য ব্যবহার করে /dev/nullexecকমান্ড সঞ্চালিত কিছু অনুরূপdup2() পুরো শেল সেশনের জন্য ফাইল বর্ণনাকারী, এইভাবে কোনো কমান্ড উত্তরাধিকারী ইতিমধ্যে পুনঃনির্দেশিত ফাইল বর্ণনাকারী করে। একই সঙ্গে exec 3>&1। ফাইল বিবরণকারী 3এখন নিয়ন্ত্রণকারী টার্মিনাল / পয়েন্ট উল্লেখ করবে এবং যে শেল সেশনে চালিত কোনও কমান্ড এটি সম্পর্কে জানতে পারবে know

সুতরাং যখন result=$(dialog --inputbox test 0 0 2>&1 1>&3);ঘটবে, শেলটি ডায়ালগের জন্য লেখার জন্য একটি পাইপ তৈরি করে, তবে 2>&1প্রথমে কমান্ডের ফাইল বিবরণকারীটিকে সেই পাইপের লিখিত ফাইল বর্ণনাকারীর উপর নকল করা যায় (এভাবে আউটপুটটি পাইপের প্রান্তে এবং ভেরিয়েবলটিতে পড়ে) ফাইল বর্ণনাকারী 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.- তবে, নামযুক্ত পাইপ ধারণাটি দুর্দান্ত!
বাইট কমান্ডার

@ বাইটকম্যান্ডার "মে ব্যর্থ" খুব বিশ্বাসযোগ্য নয়, কারণ এটি উদাহরণ দেয় না। তদতিরিক্ত, তারা সম্পর্কে কিছুই উল্লেখ করে না --output-fd, আমি এখানে যে বিকল্পটি ব্যবহার করেছি তা নয় --stdout। দ্বিতীয়ত, স্টায়ডআউটে প্রথমে ডায়ালগটি আঁকা হচ্ছে, আউটপুট ফিরে এসেছে দ্বিতীয়। আমরা একই সাথে এই দুটি জিনিস করি না। তবে, --output-fd এফডি 1 (এসটিডিআউট) ব্যবহারের জন্য বিশেষত কোনওটির প্রয়োজন হয় না। এটি অন্য একটি ফাইল বর্ণনাকারীর কাছে সহজেই পুনঃনির্দেশ করা যায়
সের্গেই কলডিয়াজহনি

আমি নিশ্চিত নই, সম্ভবত এটি সর্বত্র কাজ করে, সম্ভবত এটি কেবল বেশিরভাগ সিস্টেমে কাজ করে। এটি খনিতে কাজ করে এবং ম্যানপেজটি সতর্কতার সাথে অনুরূপ বিকল্পটি ব্যবহার করার কথা নিশ্চিতভাবেই জানি is তবে আমি ইতিমধ্যে বলেছি, +1 যাইহোক নামযুক্ত পাইপগুলির জন্য প্রাপ্য।
বাইট কমান্ডার

কিছুটা ভারসাম্য বজায় রাখতে আমার এখানে মন্তব্য করা উচিত। আমার কাছে, এটি কেবলমাত্র প্রত্যক্ষ উত্তর (1) এটি কেবল একই সরঞ্জামটি ব্যবহার করে এবং এটি কোনও বাহ্যিক সরঞ্জাম ছাড়াই বিকল্পগুলি প্রয়োগ করে (২) এটি উবুন্টুতে কাজ করে এবং এটু সম্পর্কে যা কিছু আছে তা all : / দু: খজনকভাবে ওপি এই প্রশ্নটি পরিত্যাগ করছে বলে মনে হচ্ছে।
user.dz

এখানে নিয়মিত ফাইলের পরিবর্তে নামযুক্ত পাইপ ব্যবহারের সুবিধা কী? আপনি কি ব্যবহারের পরে পাইপটি মুছতে চান না?
জার্নো

7

: ডিআই এটি ব্যাখ্যা করতে পারে না !!! আপনি যদি বুঝতে পারেন যে তারা কীভাবে রেফারেন্সটিতে বলছে: অ্যাডভান্সড ব্যাশ-স্ক্রিপ্টিং গাইড: অধ্যায় 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 / O পুনঃনির্দেশ


যে প্রস্তাব এখনও বৈধ? আমি মনে করি দেড় বছর আগে আপনি সেখানে কী পেয়েছেন তা আমি ব্যাখ্যা করতে পেরেছিলাম ... :-)
বাইট কমান্ডার

@ বাইটকম্যান্ডার, তবে তবে আপনি যদি এটি সরবরাহ করতে পারেন তবে আমি আপনাকে তা দেব, আমি আমার কথায় থাকব: ডি।
user.dz

@ বাইটকম্যান্ডার, দয়া করে আপনি পোস্ট করার পরে আমাকে পিং করুন।
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--stdout সম্পর্কে জানায়:

স্ট্যান্ডার্ড আউটপুটে সরাসরি আউটপুট। এই বিকল্পটি এক্সডায়ালগের সাথে সামঞ্জস্যের জন্য সরবরাহ করা হয়, তবে এটি পোর্টেবল স্ক্রিপ্টগুলিতে ব্যবহার করার পরামর্শ দেওয়া হয় না, কারণ অভিশাপগুলি সাধারণত স্ক্রিন আপডেটগুলি স্ট্যান্ডার্ড আউটপুটে লেখায় writes আপনি যদি এই বিকল্পটি ব্যবহার করেন, ডায়ালগটি টার্মিনালটি আবার খোলার চেষ্টা করে যাতে এটি ডিসপ্লেতে লিখতে পারে। প্ল্যাটফর্ম এবং আপনার পরিবেশের উপর নির্ভর করে এটি ব্যর্থ হতে পারে।

কোন প্ল্যাটফর্ম বা পরিবেশে এটি কাজ করে না কেউ বলতে পারবেন? পরিবর্তে dialogআউটপুট পুনর্নির্দেশ 2>&1 >/dev/ttyকাজ কি আরও ভাল কাজ করে?


4

গুগল থেকে অন্য কেউ এখানে অবতরণের ক্ষেত্রে এবং যদিও এই প্রশ্নটি বিশেষত ব্যাশের জন্য জিজ্ঞাসা করে, এখানে অন্য বিকল্প রয়েছে:

আপনি Zenity ব্যবহার করতে পারেন । Zenity একটি গ্রাফিকাল ইউটিলিটি যা ব্যাশ স্ক্রিপ্টগুলির অভ্যন্তরে ব্যবহার করা যেতে পারে । তবে অবশ্যই এটির জন্য একটি এক্স সার্ভারের প্রয়োজন হবে ব্যবহারকারীর 878773৩29২ যথাযথভাবে নির্দেশিত।

sudo apt-get install zenity

তারপরে আপনার স্ক্রিপ্টে:

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

দরকারী লিঙ্ক


3
এক্স সার্ভার না থাকলে
ব্যবহারকারী 87737329

1
ওপি সম্পর্কে জানতে চান dialog। এটি আসার মত এবং আপনাকে জিজ্ঞাসা করার মতো "আমি কীভাবে এটি লিখি এবং তা অজগরটিতে?", তবে আপনি আমাকে বাশ দেন - আমি খুব খুশি যে এটি বিভিন্নভাবে করা যেতে পারে, তবে আমি যা বলছি তা নয়
সের্গি কোলোডিয়াজনি

@ সার্জ করুন আপনার মন্তব্যটি অবৈধ, আমার উত্তরটি নয়: ইউটিলিটি ওপি কর্তৃক জিজ্ঞাসা করা সমাধানের জন্য একটি সঠিক বৈধ এবং সহজ বিকল্প সরবরাহ করে।
ওয়াটওয়ার

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

এই ক্ষেত্রে, অস্থায়ী ফাইলটি এড়ানো আরও ভাল সমাধান হতে পারে তবে এমন অনেকগুলি পরিস্থিতি থাকবে যেখানে আপনি কোনও টেম্প ফাইলটি এড়াতে পারবেন না।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.