বুলিয়ান পরিবর্তনশীল বিপরীত করুন


26

আমি সহজ স্ক্রিপ্ট চেষ্টা করতে চাই

flag=false
while !$flag
do
   read x
   if [ "$x" -eq "true" ]
   then
     flag=true
   fi
   echo "${x} : ${flag}"
done

তবে আমি যখন এটি চালাব, আমি টাইপ করলে আমি trueতা দেখতে পাব x="true"এবং flag="true", তবে চক্রটি শেষ হয় না। স্ক্রিপ্টে কী ভুল? আমি কীভাবে একটি বুলিয়ান ভেরিয়েবলকে সঠিকভাবে উল্টাতে পারি?



ধন্যবাদ! আমি এখন এটি পেয়েছি
বরিশস

উত্তর:


21

আপনার স্ক্রিপ্টে দুটি ত্রুটি রয়েছে। প্রথমটি হ'ল আপনার !এবং এর মধ্যে একটি স্থান প্রয়োজন $flag, অন্যথায় শেলটি একটি আদেশযুক্ত সন্ধান করে !$flag। দ্বিতীয় ত্রুটিটি হল -eqপূর্ণসংখ্যার তুলনার জন্য, তবে আপনি এটি একটি স্ট্রিংয়ে ব্যবহার করছেন। আপনার শেলের উপর নির্ভর করে হয় আপনি একটি ত্রুটি বার্তা দেখতে পাবেন এবং লুপটি চিরতরে অবিরত থাকবে কারণ শর্তটি [ "$x" -eq "true" ]সত্য হতে পারে না, বা প্রতিটি অ-পূর্ণসংখ্যার মান 0 হিসাবে গণ্য হবে এবং আপনি কোনও স্ট্রিং প্রবেশ করলে (সহ false) লুপটি প্রস্থান করবে including 0 থেকে পৃথক একটি সংখ্যা ছাড়া অন্য।

যদিও ! $flagসঠিক, একটি স্ট্রিংকে কমান্ড হিসাবে বিবেচনা করা খারাপ ধারণা। এটি কার্যকর হবে, তবে এটি আপনার স্ক্রিপ্টে পরিবর্তনের ক্ষেত্রে খুব সংবেদনশীল হবে, যেহেতু আপনাকে নিশ্চিত করা দরকার যে $flagএটি কখনও trueবা কিছুই হতে পারে না false। নীচের পরীক্ষার মতো এখানে স্ট্রিং তুলনাটি ব্যবহার করা ভাল।

flag=false
while [ "$flag" != "true" ]
do
   read x
   if [ "$x" = "true" ]
   then
     flag=true
   fi
   echo "${x} : ${flag}"
done

আপনার পরে যুক্তি প্রকাশ করার আরও ভাল উপায় আছে। উদাহরণস্বরূপ, আপনি যখন সমাপ্তির শর্তটি শনাক্ত করেন তখন আপনি একটি অসীম লুপ তৈরি করতে এবং তা ভেঙে ফেলতে পারেন।

while true; do
  read -r x
  if [ "$x" = "true" ]; then break; fi
  echo "$x: false"
done

সঙ্গে [এর builtin ksh, [ x -eq y ]যদি সত্যি আসতে xগাণিতিক এক্সপ্রেশন সমাধান করা হিসাবে একই নম্বরে yতাই উদাহরণস্বরূপ গাণিতিক এক্সপ্রেশন x=2 true=1+1 ksh -c '[ x -eq true ] && echo yes'would আউটপুট হ্যাঁ।
স্টাফেন চেজেলাস

10

যদিও বাশে কোনও বুলিয়ান ভেরিয়েবল নেই, তবে গাণিতিক মূল্যায়ন ব্যবহার করে তাদের অনুকরণ করা খুব সহজ।

flag= # False
flag=0 # False
flag=1 # True (actually any integer number != 0 will do, but see remark below about toggling)
flag="some string" # Maybe False (make sure that the string isn't interpreted as a number)

if ((flag)) # Test for True
then
  : # do something
fi

if ! ((flag)) # Test for False
then
  : # do something
fi

flag=$((1-flag)) # Toggle flag (only works when flag is either empty or unset, 0, 1, or a string which doesn't represent a number)

এটি ksh এও কাজ করে। এটি যদি সমস্ত পসিক্স-কমপ্লায়েন্ট শেলগুলিতে কাজ করে তবে আমি অবাক হব না, তবে মানটি যাচাই করে নি।


1
! ! ((val))সি বা সি ++ এর মতো বাশেও কি কাজ করে? উদাহরণস্বরূপ, যদি val0 পরে 0 অবশেষ ! !। যদি val1 হয় তবে এটি 1 পরে থাকে ! !। তাহলে val8 পরে 1 থেকে নিচে টানা হয় ! !। নাকি আমার আর একটি প্রশ্ন জিজ্ঞাসা করা দরকার?

1
-1 | পসিক্স শ-এ, স্ট্যান্ডেলোন ((..)) অপরিজ্ঞাত; দয়া করে এটির রেফারেন্সটি সরিয়ে দিন
লিনাক্সসিকিউরিটিফের্ক

ভ্লাসটিমিল প্রশ্নটি বিশেষত বাশ সম্পর্কে - পজিক্স শেল নয়। প্রশ্নটি কেন এই বিষয়টির বিষয়ে নয়, কেন ভোট বাতিল করবেন?
নিক বুল

6

আপনি যদি নিশ্চিত হয়ে যেতে পারেন যে চলকটি 0 বা 1 এর মধ্যে থাকে তবে আপনি দুটি মানের মধ্যে ফ্লিপ করতে বিটওয়াইস এক্সওর-সমমান অপারেটরটি ব্যবহার করতে পারেন:

$ foo=0
$ echo $foo
0
$ ((foo ^= 1))
$ echo $foo
1
$ ((foo ^= 1))
$echo $foo
0

2

এটি আমার পক্ষে কাজ করে:

flag=false
while [[ "$flag" == "false" ]]
do
   read x
   if [[ "$x" == "true" ]]
   then
     flag=true
   fi
   echo "${x} : ${flag}"
done

তবে, আসলে, আপনার যা করা উচিত তা হ'ল এটির whileসাথে প্রতিস্থাপন :

while ! $flag

0

শেলটিতে বুলিয়ান ভেরিয়েবলের কোনও ধারণা নেই।
শেল ভেরিয়েবল শুধুমাত্র হতে পারে text(একটি স্ট্রিং), এবং কিছু ক্ষেত্রে, যে পাঠ্য (একটি পূর্ণসংখ্যা হিসেবে ব্যাখ্যা করা যেতে পারে 1, 0xa, 010, ইত্যাদি)।

অতএব, flag=trueএটি শেলের কাছে কোনও সত্যতা বা মিথ্যাচারকে বোঝায় না।

দড়ি

যা করা যায় তা হ'ল একটি স্ট্রিং তুলনা [ "$flag" == "true" ]বা কোনও কমান্ডের ভেরিয়েবল সামগ্রী ব্যবহার করে এবং এর পরিণামগুলি যেমন: এক্সিকিউট true( যেমন একটি এক্সিকিউটেবল বলা হয় trueএবং বলা হয় উভয়ই রয়েছে false) একটি আদেশ হিসাবে পরীক্ষা করে পরীক্ষা করে দেখুন যে সেই কমান্ডের প্রস্থান কোডটি শূন্য কিনা? (সফল)।

$flag; if [ "$?" -eq 0 ]; then ... fi

বা সংক্ষিপ্ত:

if "$flag"; then ... fi

যদি কোনও ভেরিয়েবলের বিষয়বস্তু কমান্ড হিসাবে !ব্যবহার করা হয় তবে কমান্ডের প্রস্থান স্থিতিটিকে অস্বীকার করার জন্য একটি ব্যবহার করা যেতে পারে, যদি উভয় ( ! cmd) এর মধ্যে একটি স্থান বিদ্যমান থাকে তবে :

if ! "$flag"; then ... fi

স্ক্রিপ্টটি এতে পরিবর্তন করা উচিত:

flag=false
while ! "$flag" 
do
   read x
   if [ "$x" == "true" ]
   then
     flag=true
   fi
   echo "${x} : ${flag}"
done

পূর্ণসংখ্যা

সংখ্যার মান এবং গাণিতিক বিস্তৃতি ব্যবহার করুন ।

এই ক্ষেত্রে, প্রদর্শন করে প্রস্থান কোড $((0))হল 1এবং প্রস্থান কোড $((1))হয় 0
ব্যাশে, ksh এবং zsh এ পাটিগণিতটি একটি এর অভ্যন্তরে বাহিত হতে পারে ((..))(লক্ষ্য করুন যে শুরুর $অনুপস্থিত)।

flag=0; if ((flag)); then ... fi

এই কোডের একটি বহনযোগ্য সংস্করণ আরও সংশ্লেষিত:

flag=0; if [ "$((flag))" -eq 0 ]; then ... fi      # test for a number
flag=0; if [ "$((flag))"  == 0 ]; then ... fi      # test for the string "0"

বাশ / কেএসএ / জেডএসে আপনি এটি করতে পারেন:

flag=0    
while ((!flag)) 
do
   read x
   [ "$x" == "true" ] && flag=1
   echo "${x} : ${flag}"
done

বিকল্পভাবে

আপনি "একটি বুলিয়ান ভেরিয়েবল ইনভার্ট করুন" (এটিতে একটি সংখ্যাসূচক মান থাকে তবে):

((flag=!flag))

যে হবে পরিবর্তন মান flagউভয় 0বা 1


দ্রষ্টব্য : দয়া করে আপনার কোডটিকে প্রশ্ন হিসাবে পোস্ট করার আগে https://www.shellcheck.net/ এ ত্রুটিগুলি পরীক্ষা করে দেখুন , সমস্যাটি খুঁজে পাওয়ার জন্য এটি বহুবার যথেষ্ট।


0

untilwhile !(এবং until, !বোর্নের বিপরীতে ) এর পক্ষে সংক্ষিপ্ত , তাই আপনি এটি করতে পারেন:

flag=false
until "$flag"
do
   IFS= read -r x
   if [ "$x" = true ]
   then
     flag=true
   fi
   printf '%s\n' "$x : $flag"
done

যা একই হিসাবে হওয়া উচিত:

flag=false
while ! "$flag"
do
   IFS= read -r x
   if [ "$x" = true ]
   then
     flag=true
   fi
   printf '%s\n' "$x : $flag"
done

আপনি এটি হিসাবে এটি লিখতে পারে:

until
   IFS= read -r x
   printf '%s\n' "$x"
   [ "$x" = true ]
do
   continue
done

until/ whileএবং এর মধ্যবর্তী অংশটি doএকটি একক আদেশ হতে হবে না।

!পসিক্স শেল সিনট্যাক্সের একটি কীওয়ার্ড। এটি সীমানাঙ্কিত করা দরকার, একটি টোকেন যা অনুসরণ করে তা থেকে পৃথক হয়ে যায় এবং পাইপলাইনের পূর্ববর্তী প্রথম টোকেন হতে পারে (পাইপলাইনটিকে ! foo | barঅবজ্ঞা করে এবং foo | ! barকিছু শাঁস এটি এক্সটেনশান হিসাবে স্বীকার করলেও অবৈধ)।

!true!trueকমান্ড হিসাবে ব্যাখ্যা করা হয় যার অস্তিত্বের সম্ভাবনা নেই। ! trueকাজ করা উচিত. !(true)পোক্স-কমপ্লায়েন্ট শেলগুলিতে কাজ করা উচিত !যেমন এটি একটি (টোকেন অনুসরণ করে যেমন সীমিত করা হয় তবে বাস্তবে এটি কাজ করে না ksh/ bash -O extglobযেখানে এটি !(pattern)বিস্তৃত গ্লোব অপারেটর এবং zsh (sh অনুকরণ ব্যতীত) যেখানে এটির সাথে দ্বন্দ্ব glob(qualifiers)করে bareglobqualএবং যেখানে এটির সাথে বিরোধ হয় ts glob(group)ছাড়া.


-1
[ ${FOO:-0} == 0 ] && FOO=1 || FOO=0

অথবা এমনকি:

[ ${FOO:-false} == false ] && FOO=true || FOO=false

কাজ করা উচিত

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