যুক্তি ছাড়াই বা ছাড়াই কোনও স্ক্রিপ্ট কীভাবে লিখবেন?


13

আমার কাছে বাশ স্ক্রিপ্ট রয়েছে যা এরকম কিছু হয়:

#!/bin/bash

if [ $1 = "--test" ] || [ $1 = "-t" ]; then
    echo "Testing..."
    testing="y"

else
    testing="n"
    echo "Not testing."

fi

সুতরাং আমি যা করতে সক্ষম হতে চাই তা কেবল এটির সাথে ./script --testবা চালাতে হবে না ./script -tতবে কোনও যুক্তি (ন্যায়বিচার ./script) না দিয়েই চলবে , তবে আপাতদৃষ্টিতে যদি আমি এটি বর্তমান কোড দিয়ে করি তবে আউটপুটটি কেবল:

./script: line 3: [: =: unary operator expected
./script: line 3: [: =: unary operator expected
Not testing.

সুতরাং আমি এটি কীভাবে প্রোগ্রাম করব যাতে কোনও যুক্তি elseছাড়াই এটি চালানো ত্রুটি না ছুঁড়েই করণীয় ? আমি কি ভুল করছি?


1
আপনার চেকগুলির চারপাশে আপনার ডাবল বন্ধনী প্রয়োজন। [[]]
— টেরেন্স


@ টেরেন্স আপনার প্রয়োজন নেই, যদিও আপনি বাশকে টার্গেট করেন তবে এগুলি ব্যবহার করা উচিত।
— Ruslan

উত্তর:


1

শেল স্ক্রিপ্টিংয়ে দীর্ঘ বিকল্পগুলি ব্যবহারের "যথাযথ উপায়" হ'ল getopt GNU ইউটিলিটি । এর রয়েছে getopts একটি ব্যাশ বিল্ট-ইন যে , কিন্তু এটি শুধুমাত্র মত সংক্ষিপ্ত অপশন দেয় -t। getoptব্যবহারের কয়েকটি উদাহরণ এখানে পাওয়া যাবে ।

এখানে এমন একটি স্ক্রিপ্ট রয়েছে যা দেখায় যে আমি কীভাবে আপনার প্রশ্নের কাছে যেতে পারি। বেশিরভাগ পদক্ষেপের ব্যাখ্যাটি স্ক্রিপ্টের মধ্যেই মন্তব্য হিসাবে যুক্ত করা হয়।

#!/bin/bash

# GNU getopt allows long options. Letters in -o correspond to
# comma-separated list given in --long.

opts=$(getopt -o t --long test -- "$*")
test $? -ne 0 && exit 2 # error happened

set -- $opts # some would prefer using eval set -- "$opts"
# if theres -- as first argument, the script is called without
# option flags
if [ "$1" = "--"  ]; then
    echo "Not testing"
    testing="n"
    # Here we exit, and avoid ever getting to argument parsing loop
    # A more practical case would be to call a function here
    # that performs for no options case
    exit 1
fi

# Although this question asks only for one 
# option flag, the proper use of getopt is with while loop
# That's why it's done so - to show proper form.
while true; do
    case "$1" in
        # spaces are important in the case definition
        -t | --test ) testing="y"; echo "Testing" ;;
    esac
    # Loop will terminate if there's no more  
    # positional parameters to shift
    shift  || break
done

echo "Out of loop"

কয়েকটি সরলীকরণ এবং সরানো মন্তব্য সহ, এটিকে ঘনীভূত করা যেতে পারে:

#!/bin/bash
opts=$(getopt -o t --long test -- "$*")
test $? -ne 0 && exit 2 # error happened
set -- $opts    
case "$1" in
    -t | --test ) testing="y"; echo "Testing";;
    --) testing="n"; echo "Not testing";;
esac

16

বিভিন্ন পথ; দুটি সবচেয়ে সুস্পষ্ট:

  • $1ডাবল উদ্ধৃতি রাখুন :if [ "$1" = "--test" ]
  • $ # ব্যবহার করে আর্গুমেন্টের সংখ্যা পরীক্ষা করুন

আরও ভাল, getopts ব্যবহার করুন।


2
Getopts ব্যবহারের জন্য +1। এটিই যাওয়ার সেরা উপায়।
— শেঠ

3
আর একটি প্রচলিত প্রথা হ'ল [ "x$1" = "x--test" ]কমান্ড-লাইন যুক্তিগুলি রক্ষা করা যা কমান্ডের জন্য বৈধ অপারেটর [। (এটি [[ ]]পছন্দ করার কারণে আরও একটি কারণ : এটি শেল সিনট্যাক্সের অংশ, কেবল একটি বিল্টিন কমান্ড নয়))
— পিটার কর্ডেস

7

শর্তের ভিতরে আপনার ভেরিয়েবলগুলি উদ্ধৃত করতে হবে। প্রতিস্থাপন করুন:

if [ $1 = "--test" ] || [ $1 = "-t" ]; then

সঙ্গে:

if [ "$1" = '--test' ] || [ "$1" = '-t' ]; then  

তাহলে এটি কাজ করবে:


Not ~ ./test.sh পরীক্ষা করা হচ্ছে না।

সর্বদা আপনার ভেরিয়েবলগুলি ডাবল উদ্ধৃতি!


একক-কোটগুলি কী প্রয়োজনীয় বা এর পরিবর্তে কেউ ডাবল-কোট ব্যবহার করতে পারে?

সুনির্দিষ্ট উত্তরটি আপনি কোন শেলটি ব্যবহার করছেন তার উপর নির্ভর করে তবে আপনার প্রশ্ন থেকে আমি ধরে নিয়েছি আপনি বোর্ন-শেল বংশধর ব্যবহার করছেন। একক এবং ডাবল উদ্ধৃতিগুলির মধ্যে প্রধান পার্থক্য হ'ল ভেরিয়েবল প্রসারণটি ডাবল কোটের অভ্যন্তরে ঘটে, তবে একক উদ্ধৃতিতে নয়: OO এফইও = বার $ প্রতিধ্বনি "$ এফইও" বার $ প্রতিধ্বনি '$ এফও' $ এফইও (এইচএম .... পারেন ' মন্তব্যে টি ফর্ম্যাট কোড ...)
— জেইয়ে

@ পরানয়েডপান্ডা আপনার একক উদ্ধৃতি ব্যবহার করতে হবে না, তবে স্ট্রিং লিটারে এগুলি ব্যবহার করা ভাল অনুশীলন। আপনার স্ট্রিং ডেটাতে একটি প্রতীক বাশ প্রসারিত হতে চাইলে আপনি পরে অবাক হবেন না।
— শেঠ

@ পরনয়েড পান্ডা @ জায়ে বলেছেন: একক উদ্ধৃতি সহ আউটপুটে কোনও পরিবর্তনশীল প্রসারণ foo=bar echo '$foo'প্রিন্ট নেই $foo, পরিবর্তে foo=bar echo "$foo"প্রিন্ট রয়েছে bar।
— ইকনস

4

আপনি বাশ ব্যবহার করছেন। ব্যাশ করার জন্য একটি মহান বিকল্প আছে [: [[। এর সাথে [[, আপনাকে উদ্ধৃতি দেওয়ার বিষয়ে চিন্তা করতে হবে না এবং এর [জন্য যথাযথ সমর্থন সহ আপনি আরও অনেক অপারেটর পাবেন ||:

if [[ $1 = "--test" || $1 = "-t" ]]
then
    echo "Testing..."
    testing="y"
else
    testing="n"
    echo "Not testing."
fi

অথবা আপনি নিয়মিত প্রকাশ করতে পারেন:

if [[ $1 =~ ^(--test|-t) ]]
then
    echo "Testing..."
    testing="y"
else
    testing="n"
    echo "Not testing."
fi

অবশ্যই, যথাযথ উদ্ধৃতি সর্বদা করা উচিত, তবে [ব্যাশ ব্যবহারের সাথে লেগে থাকার কোনও কারণ নেই ।


3

যুক্তি উপস্থিত রয়েছে কিনা তা পরীক্ষা করার জন্য (সাধারণভাবে এবং তদনুসারে ক্রিয়াগুলি করুন) এটি কাজ করা উচিত:

#!/bin/bash

check=$1

if [ -z "$check" ]; then
  echo "no arguments"
else echo "there was an argument"
fi

না কেন [ -z "$1" ]?
— ইকনস

@। এই ক্ষেত্রে, অবশ্যই, সাধারণত স্ক্রিপ্টগুলিতে, আমি পরিবর্তনশীলটিকে একবারে কল করি, পদ্ধতিগুলিতে এটি উল্লেখ করি, যা সাধারণত একবারে হয়। নমুনায় প্রোটোকল রাখার সিদ্ধান্ত নিয়েছে।
— জ্যাকব ভিলিজম

এই নমুনায় আপনি $checkএকবার ব্যবহার করেছেন বলে মনে হয় shift, যে কোনও এস এর আগে , তাই $1পরিবর্তে এটি ব্যবহার করা ভাল ।
— ইকনস

@ ΈρικΚωνσταντόπουλος অবশ্যই উল্লিখিত নয়, এটি স্ক্রিপ্টগুলিতে ব্যবহার করার জন্য একটি নমুনা । স্ক্রিপ্টগুলিতে বার বার একই কাজ করা খারাপ অভ্যাস।
— জ্যাকব Vlijm

আপনি কী বলতে চাইছেন তা আমি বুঝতে পেরেছি, তবে #!নমুনা সরবরাহ করার সময় শেবাং ব্যবহার না করা ভাল অনুশীলন (আপনার কোডের বাইরে শেলটি বর্ণনা করা উচিত)।
— ইকনস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.