"$ ()" উদ্ধৃতি চিহ্নের সাথে পরিবর্তনশীল


12

আমি এই স্ক্রিপ্ট লিখেছি:

#!/bin/bash
while [ true ] 
do
    currentoutput="$(lsusb)"
    if [ "$currentoutput" != "$lastoutput" ]
    then
        echo "" date and Time >> test.log
        date +%x_r >> test.log
        lastoutput="$(lsusb)"
        lsusb >> test.log
    fi
    sleep 5
done

আমি একজন নবাবি দ্রুত শিখার চেষ্টা করছি এবং আমি ভেরিয়েবলের উদ্ধৃতি চিহ্নগুলি সম্পর্কে একটি প্রশ্ন পেয়েছি ।

$ () এর মধ্যে একটি পরিবর্তনশীল রাখুন, আমি এটি পেয়েছি, তবে কেন বিবৃতিতেও উদ্ধৃতি চিহ্নগুলি দরকার if? এটা কি নেস্টেড কমান্ড করা?


5
নোট যা while [ true ]একটি অসীম লুপ তৈরি করে, তবে সম্ভবত আপনি যে কারণে এটি মনে করেন তা নয়; while [ false ] এছাড়াও একটি অসীম লুপ উত্পাদন করে, কারণ একটি যুক্তি দিয়ে, [ ... ]যদি সেই তর্কটি একটি খালি স্ট্রিং হয় তবে সফল হয়। while trueআসলে একটি কমান্ড চালিত করবে true(যা সর্বদা সফল হয়)।
চিপনার

4
আপনি কোনও ভেরিয়েবল ভিতরে রাখেন না $()। আপনি ভিতরে একটি কমান্ড রাখুন$()
ওয়াইল্ডকার্ড

উত্তর:


23

উদ্ধৃতি চিহ্নগুলি "শব্দ বিভাজন" রোধ করে। এটি হ'ল: সাদা স্পেস অক্ষরগুলিতে একাধিক আইটেমগুলিতে ভেরিয়েবলগুলি ভাঙ্গা করা (বা ডিফল্ট $IFSশেল ভেরিয়েবলের মান হিসাবে সংজ্ঞায়িত হিসাবে স্পেস, ট্যাব এবং নিউলাইনগুলিতে আরও সঠিক হতে হবে )।

উদাহরণ স্বরূপ,

$ var="one two"
$ howmany(){ echo $#;  }
$ howmany $var
2
$ howmany "$var"
1

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

তথ্য সঠিকভাবে পাস করার জন্য এটি গুরুত্বপূর্ণ। উদাহরণস্বরূপ, যদি ভেরিয়েবলে ফাইলের পথ থাকে এবং ফাইলের নামের মধ্যে যে কোনও জায়গায় ফাঁকা জায়গা থাকে, আপনি যে কমান্ডটি চালনার চেষ্টা করছেন তা ব্যর্থ হতে পারে বা ভুল ফলাফল দিতে পারে। আমরা যদি $varভেরিয়েবলের সাহায্যে একটি ফাইল তৈরি করার চেষ্টা করতাম touch $varতবে দুটি ফাইল তৈরি করতে পারি, তবে touch "$var"কেবল একটি।

আপনার [ "$currentoutput" != "$lastoutput" ]অংশ হিসাবে একই । এই নির্দিষ্ট পরীক্ষা দুটি স্ট্রিংয়ের সাথে তুলনা করে। যখন পরীক্ষা চলবে, [কমান্ডটিতে 3 টি আর্গুমেন্ট দেখতে হবে - একটি পাঠ্য স্ট্রিং, !=অপারেটর এবং অন্য পাঠ্য স্ট্রিং। ডাবল কোট রাখা শব্দের বিভাজন রোধ করে এবং [কমান্ডটি ঠিক সেই 3 টি আর্গুমেন্টটি দেখে। এখন যদি ভেরিয়েবলগুলি নিরবচ্ছিন্ন হয় তবে কী হবে?

$ var="hello world"
$ foo="hi world"
$ [ $var != $foo ]
bash: [: too many arguments
$ 

এখানে, শব্দ বিভাজন ঘটে, এবং এর পরিবর্তে [দুটি স্ট্রিং দেখেন helloএবং worldঅনুসরণ !=, দুই অন্যান্য স্ট্রিং দ্বারা অনুসরণ hi world। মূল বিষয়টি হ'ল ডাবল কোট ব্যতীত ভেরিয়েবলের বিষয়বস্তুগুলি একটি সম্পূর্ণ আইটেমের চেয়ে পৃথক ইউনিট হিসাবে বোঝা যায়।

কমান্ড সাবস্টিটিউশন বরাদ্দকরণের মতো ডাবল কোট লাগবে না

var=$( df )

আপনার dfকমান্ডের আউটপুট সংরক্ষণ করা হবে var। যাইহোক, সর্বদা উদ্ধৃতি ভেরিয়েবল এবং কমান্ড প্রতিস্থাপনের দ্বিগুণ হওয়া ভাল অভ্যাস, $(...)যদি না আপনি বাস্তবে না চান তবে আউটপুটটিকে আলাদা আইটেম হিসাবে বিবেচনা করা হয়।


পাশের নোটে,

while [ true ]

অংশ হতে পারে

while true

[হ'ল একটি আদেশ যা তার যুক্তিগুলির মূল্যায়ন করে এবং [ whatever ]ভিতরে যা আছে তা নির্বিশেষে সবসময় সত্য। বিপরীতে, while trueকমান্ডটি ব্যবহার করে trueযা সর্বদা সাফল্যের প্রস্থান স্থিতি দেয় (এবং ঠিক এটিই whileলুপের প্রয়োজন)। পার্থক্যটি কিছুটা আরও স্পষ্টতা এবং কম পরীক্ষা করা হয়। বিকল্পভাবে, আপনি এর :পরিবর্তে ব্যবহার করতে পারেনtrue

echo "" date and Timeঅংশে ডাবল উদ্ধৃতি সম্ভবত মুছে ফেলা হতে পারে। এগুলি কেবল একটি খালি স্ট্রিং এবং আউটপুটটিতে অতিরিক্ত স্থান যুক্ত করে। যদি এটি পছন্দসই হয় তবে এগুলিকে সেখানে রাখতে দ্বিধা বোধ করবেন তবে এই ক্ষেত্রে কোনও নির্দিষ্ট কার্যকরী মূল্য নেই।

lsusb >> test.log

এই অংশটি সম্ভবত প্রতিস্থাপন করা যেতে পারে echo "$currentoutput" >> test.loglsusbএটি ইতিমধ্যে চালু হওয়ার পরে আবার চালানোর কোনও কারণ নেই currentoutput=$(lsusb)। যে ক্ষেত্রে নিউলাইনগুলি পিছনে আউটপুট সংরক্ষণ করতে হবে - কেউ কমান্ড চালানোর ক্ষেত্রে একাধিকবার মান দেখতে পারে, তবে ক্ষেত্রে এর lsusbপ্রয়োজন নেই। আপনি যত কম বাহ্যিক কমান্ড কল করবেন ততই ভাল, কারণ একটি অন্তর্নির্মিত কমান্ডের প্রতিটি কল সিপিইউ, মেমরির ব্যবহার এবং প্রয়োগের সময় ব্যয় করে (যদিও কমান্ডগুলি সম্ভবত স্মৃতি থেকে প্রাক-লোড হওয়া থাকে)।


আরো দেখুন:


1
দুর্দান্ত উত্তর, আপনি ইতিমধ্যে না থাকলে আপনার সম্পর্কে একটি বই লেখা উচিত bash। কিন্তু শেষ অংশে echo "$currentoutput" >> test.log আরও ভাল হওয়া উচিত নয় printf '%s\n' "$currentoutput" >> test.log?
pLumo

2
@ রভো হ্যাঁ, printfবহনযোগ্যতার জন্য পছন্দ করা উচিত। যেহেতু আমরা এখানে বাশ-নির্দিষ্ট স্ক্রিপ্ট ব্যবহার করছি এটি ব্যবহারের জন্য ক্ষমা হতে পারে echo। তবে আপনার পর্যবেক্ষণটি খুব সঠিক
সের্গেই কোলডিয়াজনি

1
@SergiyKolodyazhnyy ... আমি নিশ্চিত যে নই echoসম্পূর্ণভাবে নির্ভরযোগ্য এমনকি যখন শেল ব্যাশ (এবং এর মান হিসেবে পরিচিত হয় xpg_echoএবং posixপরিচিত হয় পতাকার); যদি আপনার মান হতে পারে -nবা -e, এটি মুদ্রণের পরিবর্তে অদৃশ্য হয়ে যেতে পারে ।
চার্লস ডাফি

4

ইন currentoutput="$(lsusb)"lsusb একটি পরিবর্তনশীল নয়, এটা একটি কমান্ড। এই বিবৃতিটি যা করে তা lsusbকমান্ডটি কার্যকর করে এবং এর আউটপুটটিকে currentoutputভেরিয়েবলের জন্য বরাদ্দ করে ।

এটির জন্য পুরানো বাক্য গঠন ছিল

currentoutput=`lsusb`

আপনি এটি অনেক উদাহরণ এবং স্ক্রিপ্টে খুঁজে পেতে পারেন

আপনার প্রশ্নের অন্য অংশের উত্তর দেওয়ার জন্য, if [ ]ঠিক কীভাবে বাক্যটির জন্য সিনট্যাক্স ifসংজ্ঞায়িত করা হয়। Https://www.tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_01.html এ আরও দেখুন


3
আমি মনে করি এটি বলা গুরুত্বপূর্ণ [ ]এটি আসলে testকমান্ড। আপনি ifঅন্যান্য কমান্ডের সাথে বিবৃতিও ব্যবহার করতে পারেন , কারণ এটি তাদের প্রস্থান কোডের 0 বা অ-শূন্য পরীক্ষার উপর নির্ভর করে।
অ্যারোনিকাল

... প্রকৃতপক্ষে, দৌড়ানোর if grep -qe "somestring" fileচেয়ে দৌড়ানো আরও ভাল grep -qe "somestring" file; if [ $? = 0 ]; then ..., সুতরাং সিনট্যাক্সের if [ ...সংজ্ঞার অংশ বলে দাবিটি ifকেবল বিভ্রান্তিকর নয়, খারাপ অভ্যাসের দিকে পরিচালিত করে।
চার্লস ডাফি

4

নিম্নলিখিতটি বাহ্যিক কমান্ড চালায় commandএবং এর ফলাফল প্রদান করে returns

"$(command)"

বন্ধনী / প্রথম বন্ধনী ব্যতীত, এটি কমান্ড চালানোর পরিবর্তে চলকটির সন্ধান করবে:

"$variable"

মধ্যে পার্থক্য হিসাবে $variableএবং "$variable", এই প্রাসঙ্গিক হয়ে যখন $variableস্পেস রয়েছে। ব্যবহার করার সময় "$variable", সামগ্রীর স্থানগুলি অন্তর্ভুক্ত করে এমনকি পুরো পরিবর্তনশীল সামগ্রীগুলি একটি একক স্ট্রিংয়ের মধ্যে .োকানো হবে। $variableভেরিয়েবলের সামগ্রীগুলি ব্যবহার করার সময় একাধিক যুক্তির তালিকার তালিকায় প্রসারিত হতে পারে।


এইচআই @ থোমাস্রুটটার, আমি দুঃখিত, আমার অর্থ উদ্ধৃতি চিহ্ন ... আমি এখন আমার মন্তব্য সম্পাদনা করছি!
শঙ্খরা

1

কনট্রিয়েন হতে - বাশ সুপারিশ করে যে আপনি পরীক্ষায় ভেরিয়েবলগুলি উদ্ধৃত না করা এবং তাই শব্দ বিভাজনের সাথে সম্পর্কিত সমস্যাগুলি যা অন্যরা উল্লেখ করেছে তা এড়াতে আপনি [[ ... ]]ওভার [ ... ]কনস্ট্রাক্টটি ব্যবহার করার পরামর্শ দেন।

[পসিক্সের সামঞ্জস্যের জন্য বাশকে সরবরাহ করা হয় স্ক্রিপ্টগুলির সাথে চালানো #!/bin/shবা বাশগুলিতে পোর্ট করা হচ্ছে - বেশিরভাগ ক্ষেত্রে, আপনার পক্ষে এটি এড়ানো উচিত [[

যেমন

# With [ - quotes are needed

$ foo='one two'; bar='one two'; [ $foo = $bar ] && echo "they're equal"
-bash: [: too many arguments

$ foo='one two'; bar='one two'; [ "$foo" = "$bar" ] && echo "they're equal"                                                                                                              
they're equal

# versus [[ - quotes not needed

$ foo='one two'; bar='one two'; [[ $foo = $bar ]] && echo "they're equal"
they're equal

bashএ জাতীয় কোনও সুপারিশ করে না; এটি সরবরাহ করে [[ ... ]] যা আরও বেশি সুবিধাজনক হতে পারে এবং এর কিছু কার্যকারিতা [ ... ]রয়েছে যা না করে তবে [ ... ] সঠিকভাবে ব্যবহার করতে কোনও সমস্যা নেই ।
চিপনার

@ চেপার - সম্ভবত আমার এখানে আরও পরিষ্কার হওয়া উচিত। নিশ্চিত যে এটি ব্যাশ ম্যানপেজে কোনও সুস্পষ্ট প্রস্তাবনা নয় তবে প্রদত্ত [[সমস্ত কিছু [করে এবং তারপরেও বহুবার [লোককে ট্রিপ করে এবং তারপরে ব্যর্থ হওয়ার জন্য [[ব্যাক ফিরিয়ে ফিরিয়ে ফিরিয়ে আনার বৈশিষ্ট্যগুলি চেষ্টা করে দেখুন [- এটি বলা ঠিক যে এটি একটি সম্প্রদায় সুপারিশ মধ্যে যতটা সর্বাধিক প্রাসঙ্গিক ব্যাশ শৈলী গাইড উপদেশ হবে না ব্যবহার[
শালম্ব
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.