বাশ বা শেল এবং অন্যান্য শেলগুলির মধ্যে পরীক্ষা বা [বা [[আরও বহনযোগ্য উভয়ই)?


44

আমি দেখতে পাচ্ছি

$ [ -w /home/durrantm ] && echo "writable"
writable

অথবা

$ test -w /home/durrantm && echo "writable"
writable

অথবা

$ [[ -w /home/durrantm ]] && echo "writable"
writable

আমি তৃতীয় বাক্য গঠন ব্যবহার করতে পছন্দ করি। তারা সব উপায়ে এবং সব নেতিবাচক এবং প্রান্ত ক্ষেত্রে সমতুল্য? বহনযোগ্যতার মধ্যে কি কোনও পার্থক্য রয়েছে, যেমন উবুন্টু এবং ওএস এক্স বা পুরানো / নতুন বাশ সংস্করণগুলির মধ্যে উদাহরণস্বরূপ, ৪.০ এর আগে / পরে এবং তারা উভয়ই কি একইভাবে অভিব্যক্তি প্রসারিত করে?


2
জন্য [ … ]বনাম [[ … ]]বনাম test …সেখানে আরও সম্পূর্ণ উত্তর এই বেশিরভাগই ডুপ্লিকেট প্রশ্ন
গিলস 16'14


1
একটি প্রবাদ আছে: "এখানে কোনও পোর্টেবল কোড নেই, কেবলমাত্র কোড যা পোর্ট করা হয়েছে"। এ সম্পর্কে আমার পরামর্শ: সর্বাধিক পঠনযোগ্য ফর্মটি (সম্ভবত [[...]]) ব্যবহার করুন এবং আপনি সমর্থন করতে চান এমন সমস্ত প্ল্যাটফর্মগুলিতে এটি ব্যবহার করে দেখুন। আপনার স্ক্রিপ্টগুলিকে অস্পষ্ট করার ক্ষেত্রে তেমন কোন ব্যবহার নেই কারণ এগুলি প্রাচীন প্ল্যাটফর্মগুলিতে চালিত হয় যা আপনি বা আপনার লক্ষ্য দর্শক কেউই ব্যবহার করেন না। এটি কেবল আপনার কোডটি পড়া, অপ্রয়োজনীয় বাগ এবং এমনকি সুরক্ষার সমস্যাগুলি (যেমন এটি ওপেনসেলের জন্য করেছিল) প্রবর্তন করা শক্ত করে তুলবে।
stefan.schwetschke

উত্তর:


31

[testকমান্ডের প্রতিশব্দ এবং এটি একই সাথে একটি ব্যাশ বিল্টিন এবং পৃথক কমান্ড। তবে [[এটি একটি বাশ কীওয়ার্ড এবং কিছু সংস্করণে কেবল কাজ করে। সুতরাং বহনযোগ্যতার কারণে আপনি একক []বা ব্যবহার করা ভাল bettertest

[ -w "/home/durrantm" ] && echo "writable"

2
[পসিক্স অন্তর্নির্মিত বা বাশ বিল্টিন?
স্যান্ডবুর্গ 11

@ স্যান্ডবুর্গ পোসিক্স একটি মান, সুতরাং এটি বিল্ট-ইনগুলি না থাকতে পারে। দোভাষীর মধ্যে কিছু তৈরি করা উচিত কিনা তা এটি সংজ্ঞায়িত করে না, কেবল তার কী করতে হবে। এই নিয়মগুলি উভয় ফর্ম testএবং [একই রকমের জন্য প্রযোজ্য । যদি একটি শেল নিজে থেকে মূল্যায়ন করতে পারে তবে এটি আপনাকে একটি প্রক্রিয়া বাঁচায় এবং কিছুটা দ্রুত করে তোলে, তবে ফলাফলটি একই রকম হতে হবে।
বাচসৌ

@ বাছসৌ যে এখনও প্যান্ডিক্সের আচরণের [সংজ্ঞা দেওয়া হয়েছে এবং সর্বাধিকভাবে বহনযোগ্য (যা আমি ভুল না
বললে

@ সানডবার্গ (এবং অন্য যে কেউ এটিকে হোঁচট খাচ্ছেন): হ্যাঁ, এটি উভয়ের মতোই [এবং test পসিক্সউভয়ই "প্রস্তাবিত" বলে মনে হচ্ছে না, যদিও আমি তাদের মধ্যে কেবলমাত্র পার্থক্য (?) চিহ্নিত করতে পারি তা হ'ল test"-" যুক্তিটি [বিকল্পগুলির শেষের ইঙ্গিতকারী একটি সীমানা হিসাবে স্বীকৃতি দেবে না] "(? - বোঝায় যে" - "এর পক্ষে যুক্তি হিসাবে শেষ হিসাবে স্বীকৃত [, যা আমি যাইহোক যাইহোক ভাল পরীক্ষার ক্ষেত্রে আসতে পারি না But তবে আমি ডিগ্রি করি you আপনি যা চান তা ব্যবহার করুন IM আইএমও, [মার্জিত দেখায় তবে testভিন্নভাবে একটি কমান্ড)
জেমস

35

হ্যাঁ, পার্থক্য আছে। সর্বাধিক বহনযোগ্য testবা হয় [ ]। এগুলি উভয়ই পসিএক্স testস্পেসিফিকেশনের অংশ ।

if ... fiকনস্ট্রাক্ট হয় POSIX দ্বারা সংজ্ঞায়িত এবং সম্পূর্ণরূপে পোর্টেবল হওয়া উচিত।

[[ ]]একটি হল kshবৈশিষ্ট্য এছাড়াও কিছু সংস্করণ উপস্থিত যে bash( সব আধুনিক বেশী ), মধ্যে zshএবং সম্ভবত অন্যদের মধ্যে কিন্তু উপস্থিত নেই shবা dashবা অন্যান্য বিভিন্ন সহজ শেল।

সুতরাং, আপনার স্ক্রিপ্টগুলি পোর্টেবল, ব্যবহার [ ], testবা তৈরি করতে if ... fi


10
কেবল লক্ষ্য করার জন্য, bashএবং একটি দীর্ঘ সময়ের জন্য zshসমর্থন [[করেছে ( bashএটি zsh২০০০ এর পরে নয় , 90 এর দশকের শেষের দিকে যুক্ত হয়েছে , এবং এর যদি কখনও সমর্থন না থাকে তবে আমি অবাক হয়ে যাব ), সুতরাং আপনি কোনওটি ছাড়া কোনও সংস্করণের মুখোমুখি হওয়ার সম্ভাবনা নেই [[। একটি আলাদা POSIX- কমপ্লায়েন্ট শেল (যেমন dash) এর সাথে মিলিয়ে যাওয়ার সম্ভাবনা অনেক বেশি।
চিপনার

1
এর একটি আকর্ষণীয় বৈশিষ্ট্য [[হ'ল প্যারামিটারের বিস্তৃতি উদ্ধৃত করতে হবে না: হোয়াইটস্পেসের অক্ষর [[-f $file]]থাকলে ইভেন্টটি কাজ করে $file
হেল্পারমোথড

2
@ হেল্পারমোথডও, অন্তর্নির্মিত নিয়মিত অভিব্যক্তি[[ $a =~ ^reg.*exp.*$' ]]
GnP

20

দয়া করে মনে রাখবেন, এটি নির্মাণের [] && cmdমতো নয় if .. fi

কখনও কখনও এটির আচরণটি এর মতো একইরকম হয় এবং আপনি এর [] && cmdপরিবর্তে ব্যবহার করতে পারেন if .. fi। তবে শুধুমাত্র কখনও কখনও। যদি আপনার আরও থাকে তবে শর্তটি কার্যকর করতে একটি কমান্ড বা আপনার if .. else .. fiসতর্কতা অবলম্বন করা উচিত এবং যুক্তিটি কী করা উচিত।

উদাহরণ দুটি:

[ -z "$VAR" ] && ls file || echo wiiii

যেমন হয় না

if [ -z $VAR ] ; then
  ls file
else
  echo wiii
fi

কারন যদি lsব্যর্থ হবে, echoমৃত্যুদন্ড কার্যকর করা হবে, যা দিয়ে ঘটবে না if

আরেকটি উদাহরণ:

[ -z "$VAR" ] && ls file && echo wiii

যেমন হয় না

if [ -z "$VAR" ] ; then
   ls file
   echo $wiii
fi

যদিও এই নির্মাণ একই কাজ করবে

[ -z "$VAR" ] && { ls file ; echo wiii ; }

দয়া করে নোট করুন ;প্রতিধ্বনির পরে গুরুত্বপূর্ণ এবং অবশ্যই তা অবশ্যই রয়েছে।

সুতরাং উপরের বিবৃতি পুনরায় শুরু করা আমরা বলতে পারি

[] && cmd == যদি প্রথম কমান্ড সফল হয় তবে পরবর্তীটি কার্যকর করুন

if .. fi == যদি শর্ত থাকে (যা টেস্ট কমান্ডও হতে পারে) তবে কমান্ড কার্যকর করুন

সুতরাং কেবল [এবং [[ব্যবহারের মধ্যে বহনযোগ্যতার জন্য [

ifPOSIX সামঞ্জস্যপূর্ণ। সুতরাং আপনি যদি নিজের কাজটি এবং প্রত্যাশিত আচরণের মধ্যে থেকে বেছে নিতে চান [এবং ifবেছে নিতে পারেন।


আমি সম্ভবত কেবল ঘন হয়ে যাচ্ছি, তবে পার্থক্যটি কী হবে তা আমি দেখছি না ... আপনি দয়া করে একটি উদাহরণ দিতে পারেন যেখানে এই দুটি নির্মাণ বিভিন্ন ফলাফল দেয়?
16:44

1
@ ইভিলসপ, আপডেট হয়েছে। আমি হতে পারি আমি সেরা ব্যাখ্যাকারী না, যদিও আমি আশা করি এটি এখন পরিষ্কার হয়ে যাবে।
রাশ

1
খুব ভাল পয়েন্ট, রাশ। আমি অনুমান আপনার 1 ম উদাহরণস্বরূপ একটি নিরাপদ ফর্ম হবে: [ -z "$VAR" ] && { ls file; true; } || echo wiiii। এটি কিছুটা ভার্বোজ, তবে এটি এখনও if...fiনির্মাণের চেয়ে ছোট ।
প্রধানমন্ত্রী 2 রিং

প্রশ্নটিকে [বনাম [[বনাম পরীক্ষা এবং এটি সম্পর্কেও নয় তবে ... ফাই বনাম && এটিকে একটি প্রশ্ন করা) তৈরি করে। দুর্ভাগ্যক্রমে এটি করা এই উত্তরটিকে বিন্দু মনে করে। প্রশ্নটি আকরিক প্রাথমিকভাবে কেন্দ্রীভূত না হওয়ার জন্য ক্ষমাপ্রার্থী যার ফলে এটি ঘটেছে। লাইভ এবং (চেষ্টা) শিখুন। :)
মাইকেল ডুরান্ট

আমি হ্রাস পেয়েছি কারণ ক) এটি মূলত একটি ভাল উত্তর, তবে এটি বিভিন্ন প্রশ্নের উত্তর। খ) তোমরা কি উপস্থিত [এবং ifsubtitutes যেমন, কিন্তু তারা নয়। এটি আসলে এটি &&প্রতিস্থাপন করছে if[কিছু কোডকে কার্যকর করে এবং স্থিতি ফিরিয়ে, অনেক মত lsএবং grepwould। ifকমান্ডের (স্টেটমেন্ট) রিটার্নের স্ট্যাটাসের উপর নির্ভর করে শাখার এক্সিকিউটিশন যদি দেওয়া হয় তবে এটি কোনও কমান্ড (বিবৃতি) হতে পারে। &&পূর্ববর্তীটি 0 টি ফিরে আসে কেবল তখনই পরবর্তী বিবৃতিটি কার্যকর করে if..then..fi
জিএনপি

9

এটি আসলে এটি &&প্রতিস্থাপন করছে if, এটি নয় test: ifশেল স্ক্রিপ্টিংয়ের বিবৃতিতে কোনও আদেশ একটি "সফল" (শূন্য) প্রস্থান স্থিতি ফিরিয়ে দিয়েছে কিনা; আপনার উদাহরণে, আদেশটি হল [

সুতরাং, এখানে দুটি জিনিস রয়েছে যা আপনি এখানে পরিবর্তিত হচ্ছেন: পরীক্ষা চালানোর জন্য ব্যবহৃত কমান্ড এবং সেই পরীক্ষার ফলাফলের উপর ভিত্তি করে কোডটি কার্যকর করতে সিনট্যাক্স ব্যবহৃত হত।

পরীক্ষার আদেশগুলি:

  • testহয় একটি প্রমিত কমান্ড স্ট্রিং এবং ফাইল বৈশিষ্ট্য মূল্যায়নের; আপনার উদাহরণে, আপনি কমান্ড চালাচ্ছেনtest -w /home/durrantm
  • [হ'ল এই আদেশের একটি উপন্যাস, সমানভাবে প্রমিত, যা ]বন্ধনীযুক্ত মত প্রকাশের মতো দেখতে সর্বশেষ যুক্তিযুক্ত যুক্তিযুক্ত থাকে ; বোকা বোকা বানাবেন না, এটি এখনও একটি কমান্ড (আপনি এমনকি আপনার সিস্টেমে একটি ফাইল বলেও দেখতে পাবেন /bin/[)
  • [[কিছু শেলের মধ্যে নির্মিত পরীক্ষা কমান্ডের বর্ধিত সংস্করণ, তবে একই পসিক্স স্ট্যান্ডার্ডের অংশ নয়; এতে অতিরিক্ত বিকল্প রয়েছে যা আপনি এখানে ব্যবহার করছেন না

শর্তাধীন অভিব্যক্তি:

  • &&অপারেটর ( এখানে মান ) একটি লজিক্যাল এবং অপারেশন সঞ্চালিত দুই কমান্ড মূল্যায়নের এবং 0 ফিরে (যা সত্য প্রতিনিধিত্ব করে) দ্বারা যদি তারা উভয় রিটার্ন 0; এটি কেবলমাত্র দ্বিতীয় কমান্ডকে মূল্যায়ন করবে যদি প্রথমটি শূন্য ফিরে আসে তবে এটি সাধারণ শর্তসাপেক্ষ হিসাবে ব্যবহার করা যেতে পারে
  • if ... then ... fiকনস্ট্রাক্ট ( এখানে মান ) "সত্য" বিচার একই পদ্ধতি ব্যবহার করে, কিন্তু এ বিবৃতির একটি যৌগ তালিকা জন্য করতে পারবেন thenবরং একটি দ্বারা afforded একক কমান্ড চেয়ে দফা &&শর্ট সার্কিট, এবং উপলব্ধ elifএবং elseক্লজ, যা লিখতে কঠিন শুধুমাত্র &&এবং ||নোট করুন যে ifবিবৃতিতে শর্তের আশেপাশে কোনও বন্ধনী নেই

সুতরাং, নিম্নলিখিতটি সমস্ত সমানভাবে বহনযোগ্য এবং সম্পূর্ণ সমতুল্য, আপনার উদাহরণের রেন্ডারিং:

  • test -w /home/durrantm && echo "writable"
  • [ -w /home/durrantm ] && echo "writable"
  • if test -w /home/durrantm; then echo "writable"; fi
  • if [ -w /home/durrantm ]; then echo "writable"; fi

যদিও নিম্নলিখিতগুলিও সমতুল্য, তবে অ-মানক প্রকৃতির কারণে কম পোর্টেবল [[:

  • [[ -w /home/durrantm ]] && echo "writable"
  • if [[ -w /home/durrantm ]]; then echo "writable"; fi

হ্যাঁ আমি এইটিকে 1 টি প্রশ্ন করার জন্য if .... ফাই অংশটি সরিয়েছি।
মাইকেল ডুরান্ট

7

বহনযোগ্যতার জন্য, test/ ব্যবহার করুন [। তবে আপনার নিজের এবং অন্যদের স্ক্রিপ্টের ব্যবহার পড়ার বোধগম্যতার জন্য যদি আপনার বহনযোগ্যতার প্রয়োজন না হয় [[। :)

আরো দেখুন What is the difference between test, [ and [[ ?মধ্যে BashFAQ


7

আপনি যদি বোর্নের মতো বিশ্বের বাইরে বহনযোগ্যতা চান তবে:

test -w /home/durrantm && echo writable

সবচেয়ে বহনযোগ্য। এটি বোর্নের শেল cshএবং rcপরিবারগুলিতে কাজ করে।

test -w /home/durrantm && echo "writable"

হায় আউটপুট "writable"পরিবর্তে writableএর শাঁস মধ্যে rcপরিবার ( rc, es, akanga, যেখানে "না বিশেষ)।

[ -w /home/durrantm ] && echo writable

যে সিস্টেমে কমান্ড নেই তাদের সিস্টেমে cshবা rcপরিবারগুলির শেলগুলিতে কাজ করবে না (কারও কারও কাছে এটির নাম নেই তবে পরিচিত রয়েছে )।[$PATHtest[

if [ -w /home/durrantm ]; then echo writabe; fi

শুধুমাত্র বোর্ন পরিবারের শেলগুলিতে কাজ করে।

[[ -w /home/durrantm ]] && echo writable

কেবলমাত্র ksh(যেখানে এটি উদ্ভূত হয়েছিল) zshএবং bash(বোর্ন পরিবারে সমস্ত 3) কাজ করে।

আপনার যে fishশেলটি দরকার সেখানে কোনও কাজ করবে না :

[ -w /home/durrantm ]; and echo writable

বা:

if [ -w /home/durrantm ]; echo writable; end

0

পারেন চয়নের জন্য আমার সবচেয়ে গুরুত্বপূর্ণ কারণ if foo; then bar; fiবা foo && barগুরুত্বপূর্ণ কিনা পুরো কমান্ডের প্রস্থান অবস্থা হয়।

তুলনা করা:

#!/bin/sh
set -e
foo && bar
do_baz

সঙ্গে:

#!/bin/sh
set -e
if foo; then bar; fi
do_baz

আপনি ভাবতে পারেন তারা একই কাজ করে; তবে যদি fooব্যর্থ হয় (বা আপনার দৃষ্টিভঙ্গির উপর নির্ভর করে মিথ্যা) তবে প্রথম উদাহরণে do_বাজ কার্যকর করা হবে না, কারণ স্ক্রিপ্টটি বেরিয়ে গেছে ... set -eকোনও কমান্ড একটি মিথ্যা স্থিতি ফিরিয়ে দিলে শেলটিকে তত্ক্ষণাত্ প্রস্থান করার নির্দেশ দেয়। আপনি যদি এমন কিছু করেন তবে খুব কার্যকর:

cd /some/directory
rm -rf *

আপনি চান না যে cdকোনও কারণেই ব্যর্থ হলে স্ক্রিপ্টটি চলতে থাকবে ।


1
কোনও ব্যর্থতা fooউভয় ক্ষেত্রেই স্ক্রিপ্টটি বাতিল করবে না। এটি set -eশর্ত হিসাবে (যখন কমান্ডটি শর্ত হিসাবে মূল্যায়ন করা হয় (কিছু && / || এর বাম দিকে অথবা যদি / কখন / অবধি / এলসিফ ... শর্ত)) ব্যর্থ হয় barতবে উভয় ক্ষেত্রে শেলটি প্রস্থান করতে পারে
স্টাফেন চেজেলাস

2
আপনি চান cd /some/directory && rm -rf -- *বা cd /some/directory || exit; rm -rf -- *(এখনও লুকানো ফাইলগুলি সরাবে না)। আমি ব্যক্তিগতভাবে set -eসঠিক কোড লেখার চেষ্টা না করার জন্য একটি অজুহাত হিসাবে ব্যবহার করার ধারণা পছন্দ করি না ।
স্টাফেন চেজেলাস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.