বাশ যদি [মিথ্যা]; সত্য ফিরে


151

এই সপ্তাহে বাশ শিখতে পেরে একটি ছিনতাইয়ের মধ্যে পড়ে।

#!/bin/sh

if [ false ]; then
    echo "True"
else
    echo "False"
fi

এটি সর্বদা সত্য আউটপুট দেবে যদিও শর্তটি অন্যথায় নির্দেশ করে বলে মনে হচ্ছে। আমি যদি বন্ধনীগুলি অপসারণ করি []তবে এটি কার্যকর হয় তবে কেন তা বুঝতে পারছি না।


3
আপনাকে শুরু করার জন্য এখানে কিছু।
কীসার

10
বিটিডাব্লু, একটি স্ক্রিপ্ট দিয়ে শুরু করা #!/bin/shকোনও বাশ স্ক্রিপ্ট নয় - এটি একটি পজিএক্স শ স্ক্রিপ্ট। এমনকি যদি আপনার সিস্টেমে পসিক্স শ দোভাষীর ব্যাশ সরবরাহ করা থাকে তবে এটি একগুচ্ছ এক্সটেনশান বন্ধ করে দেয়। যদি আপনি বাশ স্ক্রিপ্টগুলি লিখতে চান, তবে #!/bin/bashস্থানীয়ভাবে উপযুক্ত সমতুল্য ( #!/usr/bin/env bashPATH- এ প্রথম ব্যাশ ইন্টারপ্রেটার ব্যবহার করতে) ব্যবহার করুন use
চার্লস ডাফি

[[ false ]]এটিও প্রভাবিত করে।
সিএমসিডিগ্রাগনকাই

উত্তর:


192

আপনি "(মিথ্যা") যুক্তি দিয়ে [(ওরফে test) কমান্ডটি চালাচ্ছেন, আদেশটি চালাচ্ছেন না false। যেহেতু "মিথ্যা" একটি খালি নয় স্ট্রিং, testআদেশটি সর্বদা সফল হয়। কমান্ডটি আসলে চালাতে কমান্ডটি ড্রপ করুন [

if false; then
   echo "True"
else
   echo "False"
fi

4
কমান্ড, এমনকি একটি স্ট্রিং হিসাবে ভুয়া ধারণাটি আমার কাছে অদ্ভুত বলে মনে হয় তবে আমি অনুমান করি এটি কার্যকর হয়েছে। ধন্যবাদ।
টেনমিলস

31
bashকোনও বুলিয়ান ডেটা টাইপ নেই, এবং তাই সত্য এবং মিথ্যা উপস্থাপন করে এমন কোনও কীওয়ার্ড নেই। ifবিবৃতি নিছক চেক কমান্ড আপনাকে এটা দিতে সফল অথবা ব্যর্থ হয় পারেন। testকমান্ড একটি অভিব্যক্তি নেয় এবং যদি অভিব্যক্তি সত্য সফল; খালি খালি স্ট্রিংটি এমন একটি অভিব্যক্তি যা অন্যান্য বেশিরভাগ প্রোগ্রামিং ভাষায় যেমন সত্য হিসাবে মূল্যায়ন করে। falseএকটি আদেশ যা সর্বদা ব্যর্থ হয়। (সাদৃশ্য অনুসারে, trueএকটি আদেশ যা সর্বদা সফল হয়))
শেপনার

2
if [[ false ]];সত্যও ফিরে আসে। যেমন আছে if [[ 0 ]];। এবং if [[ /usr/bin/false ]];ব্লকটি এড়িয়ে যায় না। মিথ্যা বা 0 কীভাবে শূন্যের মূল্যায়ন করতে পারে? অভিশাপ এই হতাশাজনক। যদি এটি গুরুত্বপূর্ণ হয় তবে ওএস এক্স 10.8; বাশ 3.
jww

7
falseবুলিয়ান ধ্রুবক বা 0একটি পূর্ণসংখ্যার আক্ষরিক জন্য ভুল করবেন না ; উভয়ই কেবল সাধারণ স্ট্রিং। হাইফেন দিয়ে শুরু না হওয়া কোনও স্ট্রিংয়ের [[ x ]]সমতুল্য । নেই কোনো কোনো প্রেক্ষাপটে বুলিয়ান ধ্রুবক। পূর্ণসংখ্যার মতো দেখতে পাওয়া স্ট্রিংগুলি অভ্যন্তরীণ হিসাবে বা অপারেটরগুলির সাথে যেমন বা অভ্যন্তরের হিসাবে বিবেচিত হয় । [[ -n x ]]xbash(( ... ))-eq-lt[[ ... ]]
চিপনার

2
@ tbc0, কিছু পড়ার চেয়ে অনেক বেশি উদ্বেগ রয়েছে। কোডগুলি যদি ভেরিয়েবলগুলি পুরোপুরি আপনার নিয়ন্ত্রণে থাকে না (বা যা বাহ্যিকভাবে ম্যানিপুলেট করা যেতে পারে, এটি অস্বাভাবিক ফাইলের নাম দ্বারা বা অন্যথায় if $predicateহতে পারে ), সহজেই এমনভাবে প্রতিকূল কোড চালানোতে আপত্তিজনক ব্যবহার করা যেতে পারে if [[ $predicate ]]
চার্লস ডাফি

55

বাশের জন্য একটি দ্রুত বুলিয়ান প্রাইমার

দ্য ifবিবৃতি একটি আর্গুমেন্ট হিসাবে কমান্ড লাগে (কি হিসাবে &&, ||ইত্যাদি)। কমান্ডের পূর্ণসংখ্যার ফলাফলের কোডটি বুলিয়ান (0 / নাল = সত্য, 1 / অন্য = মিথ্যা) হিসাবে ব্যাখ্যা করা হয়।

testবিবৃতি অপারেটর ও আর্গুমেন্ট হিসাবে operands লাগে এবং একই বিন্যাসে ফলে কোড নিয়ে এসেছে iftestবিবৃতিটির একটি উপনাম [, যা প্রায়শই ifআরও জটিল তুলনা সম্পাদন করতে ব্যবহৃত হয় ।

trueএবংfalse বিবৃতি কিছুই করতে এবং এর ফলে কোড আসতে (0 এবং 1 যথাক্রমে)। সুতরাং এগুলি ব্যাশে বুলিয়ান আক্ষরিক হিসাবে ব্যবহার করা যেতে পারে। তবে আপনি যদি বিবৃতিগুলি এমন জায়গায় রেখে দেন যেখানে সেগুলি স্ট্রিং হিসাবে ব্যাখ্যা করা হয়, আপনি সমস্যাগুলিতে চলে যাবেন। তোমার ক্ষেত্রে:

if [ foo ]; then ... # "if the string 'foo' is non-empty, return true"
if foo; then ...     # "if the command foo succeeds, return true"

তাই:

if [ true  ] ; then echo "This text will always appear." ; fi;
if [ false ] ; then echo "This text will always appear." ; fi;
if true      ; then echo "This text will always appear." ; fi;
if false     ; then echo "This text will never appear."  ; fi;

এটি যেমন কিছু করার অনুরূপ echo '$foo' বনাম এরecho "$foo"

testবিবৃতি ব্যবহার করার সময় , ফলাফল ব্যবহৃত অপারেটরগুলির উপর নির্ভর করে।

if [ "$foo" = "$bar" ]   # true if the string values of $foo and $bar are equal
if [ "$foo" -eq "$bar" ] # true if the integer values of $foo and $bar are equal
if [ -f "$foo" ]         # true if $foo is a file that exists (by path)
if [ "$foo" ]            # true if $foo evaluates to a non-empty string
if foo                   # true if foo, as a command/subroutine,
                         # evaluates to true/success (returns 0 or null)

সংক্ষেপে , আপনি যদি পাস / ব্যর্থ (ওরফে "সত্য" / "মিথ্যা") হিসাবে কিছু পরীক্ষা করতে চান তবে আপনার কাছে একটি আদেশ পাঠানif&& বন্ধনী ছাড়াই বা ইত্যাদির বিবৃতিতে । জটিল তুলনার জন্য, সঠিক অপারেটরগুলির সাথে বন্ধনী ব্যবহার করুন।

এবং হ্যাঁ, আমি সচেতন যে বাশে নেটিভ বুলিয়ান টাইপের মতো কোনও জিনিস নেই, এবং এটি ifএবং [এবং trueপ্রযুক্তিগতভাবে "কমান্ডগুলি" এবং "বিবৃতি" নয়; এটি কেবল একটি খুব মৌলিক, কার্যকরী ব্যাখ্যা।


1
এফওয়াইআই, আপনি যদি নিজের কোডটিতে 1/0 টি সত্য / মিথ্যা হিসাবে ব্যবহার করতে চান তবে if (( $x )); then echo "Hello"; fiএটি বার্তার x=1জন্য x=0বা x=(অপরিজ্ঞাত) নয়।
জোনাথন এইচ

3

আমি দেখতে পেয়েছি যে এই জাতীয় কিছু চালিয়ে আমি কিছু প্রাথমিক যুক্তি করতে পারি:

A=true
B=true
if ($A && $B); then
    C=true
else
    C=false
fi
echo $C

6
কেউ পারেন , তবে এটি সত্যিই খারাপ ধারণা। ( $A && $B )একটি আশ্চর্যজনকভাবে অপারেশন অপারেশন - আপনি কলিংয়ের মাধ্যমে একটি সাবপ্রসেস তৈরি করছেন fork(), তারপরে $Aউপাদানগুলির তালিকা তৈরি করার জন্য সামগ্রীগুলির স্ট্রিং-বিভক্তকরণ (এক আকারের ক্ষেত্রে এই ক্ষেত্রে) এবং প্রতিটি উপাদানকে গ্লোব হিসাবে মূল্যায়ন করুন ( এক্ষেত্রে প্রথমটি যা নিজেই মূল্যায়ন করে), তারপরে কমান্ড হিসাবে ফলাফলটি চালানো (এই ক্ষেত্রে, একটি বিল্টিন কমান্ড)।
চার্লস ডাফি

3
তদুপরি, যদি আপনার trueএবং falseস্ট্রিংগুলি অন্য কোথাও থেকে আগত হয় তবে তাদের ঝুঁকি রয়েছে যে সেগুলিতে আসলে trueবা অন্য ব্যতীত অন্য সামগ্রী থাকতে পারে falseএবং আপনি স্বেচ্ছাসেবক কমান্ড কার্যকর করতে এবং অপ্রত্যাশিত আচরণ পেতে পারেন।
চার্লস ডাফি

6
এটি লিখতে অনেক বেশি নিরাপদ A=1; B=1এবং if (( A && B ))- এগুলিকে সংখ্যাসূচক হিসাবে [[ $A && $B ]]গণ্য করা - বা , যা খালি স্ট্রিংটিকে মিথ্যা এবং খালি খালি স্ট্রিংকে সত্য হিসাবে গণ্য করে।
চার্লস ডাফি

3
(নোট করুন যে আমি উত্তরের দ্বারা প্রতিষ্ঠিত কনভেনশনগুলি অনুসরণ করতে উপরের সমস্ত-ক্যাপগুলি ভেরিয়েবলের নামগুলি ব্যবহার করছি - পসিক্স বাস্তবে পরিবেশের ভেরিয়েবল এবং শেল বিল্টিনগুলির জন্য ব্যবহৃত সমস্ত ক্যাপের নামগুলি স্পষ্টভাবে নির্দিষ্ট করে এবং অ্যাপ্লিকেশন ব্যবহারের জন্য ছোট ছোট নাম সংরক্ষণ করে; ভবিষ্যতের ওএস পরিবেশের সাথে দ্বন্দ্ব এড়ানোর জন্য, বিশেষত শেল ভেরিয়েবল নির্ধারণের ফলে কোনও পরিবেশ-সংক্রান্ত পরিবেশ পরিবর্তনশীল ওভাররাইট হয়ে যায়, এই সিদ্ধান্তটি নিজের স্ক্রিপ্টে সম্মান করা সর্বদা আদর্শ)।
চার্লস ডাফি

অন্তর্দৃষ্টি জন্য ধন্যবাদ!
রডরিগো

2

সত্য / মিথ্যা ব্যবহার করা কিছু বন্ধনী বিশৃঙ্খলা অপসারণ করে ...

#! /bin/bash    
#  true_or_false.bash

[ "$(basename $0)" == "bash" ] && sourced=true || sourced=false

$sourced && echo "SOURCED"
$sourced || echo "CALLED"

# Just an alternate way:
! $sourced  &&  echo "CALLED " ||  echo "SOURCED"

$sourced && return || exit

আমি এটি সহায়ক পেয়েছি কিন্তু উবুন্টুতে 18.04 $ 0 ছিল "-বাশ" এবং বেস নাম কমান্ডটি একটি ত্রুটি ছুঁড়েছিল। [[ "$0" =~ "bash" ]] স্ক্রিপ্টটি আমার পক্ষে কাজ করতে টেস্টটি পরিবর্তন করা ।
ওয়্যারিংহারনেস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.