বাশ স্ক্রিপ্টে পাস হওয়া আর্গুমেন্টের চেক করুন


726

আমি চাইব আমার বাশ স্ক্রিপ্টটি একটি ত্রুটি বার্তা প্রিন্ট করবে যদি প্রয়োজনীয় আর্গুমেন্ট গণনাটি পূরণ না হয়।

আমি নিম্নলিখিত কোড চেষ্টা করেছিলাম:

#!/bin/bash
echo Script name: $0
echo $# arguments 
if [$# -ne 1]; 
    then echo "illegal number of parameters"
fi

কিছু অজানা কারণে আমি নিম্নলিখিত ত্রুটি পেয়েছি:

test: line 4: [2: command not found

আমি কি ভুল করছি?


54
আপনার স্ক্রিপ্টটির নাম রাখা উচিত নয় test। এটি একটি স্ট্যান্ডার্ড ইউনিক্স কমান্ডের নাম, আপনি এটি ছায়া দিতে চান না।
বার্মার

20
সর্বদা ব্যবধান ব্যবহার প্রায় '[' ( '[[') বা '(' ( '((') তাহলে ব্যাশ মধ্যে বিবৃতির।
zoska

5
@ জোসকা মন্তব্যে যোগ করতে আপনার আগে একটি স্থান প্রয়োজন [কারণ এটি একটি আদেশ হিসাবে কার্যকর করা হয়েছে, 'যা [' চেষ্টা করুন।
ড্যানিয়েল দা কুনহা

1
আরও ভাল উদাহরণ নীচের লিঙ্কে দেওয়া হয়েছে: stackoverflow.com/questions/4341630/…
রামকৃষ্ণ

3
@ বার্মার অবশ্যই নামকরণ করছেন testযতক্ষণ না এটি পাঠে নেই ?
ব্যবহারকারী 253751

উত্তর:


1098

অন্য যে কোনও সাধারণ কমান্ডের মতো, [ ... ]বা testএর আর্গুমেন্টগুলির মধ্যে ফাঁকা স্থান প্রয়োজন।

if [ "$#" -ne 1 ]; then
    echo "Illegal number of parameters"
fi

অথবা

if test "$#" -ne 1; then
    echo "Illegal number of parameters"
fi

পরামর্শ

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

[[ $# -ne 1 ]]

এটিতে আরও কিছু বৈশিষ্ট্য রয়েছে যেমন আনকোটেড কন্ডিশন গ্রুপিং, প্যাটার্ন ম্যাচিং (এর সাথে বর্ধিত প্যাটার্ন মেলানো extglob) এবং রেজেক্স ম্যাচিং।

নিম্নলিখিত উদাহরণটি আর্গুমেন্ট বৈধ কিনা তা পরীক্ষা করে। এটি একটি একক তর্ক বা দুটি অনুমতি দেয়।

[[ ($# -eq 1 || ($# -eq 2 && $2 == <glob pattern>)) && $1 =~ <regex pattern> ]]

বিশুদ্ধ গাণিতিক এক্সপ্রেশন জন্য ব্যবহার (( ))কিছু এখনও ভালো হতে পারে, কিন্তু তারা এখনও সম্ভব [[ ]]চাই তার গাণিতিক অপারেটর সঙ্গে -eq, -ne, -lt, -le, -gt, অথবা -geএকটি একক পংক্তি আর্গুমেন্ট হিসাবে অভিব্যক্তি স্থাপন দ্বারা:

A=1
[[ 'A + 1' -eq 2 ]] && echo true  ## Prints true.

আপনার যদি এটির অন্যান্য বৈশিষ্ট্যগুলির সাথে একত্রিত করার প্রয়োজন হয় তবে এটি সহায়ক হবে [[ ]]

স্ক্রিপ্ট থেকে প্রস্থান করা হচ্ছে

এটিতে অবৈধ পরামিতিগুলি পাস করার পরে স্ক্রিপ্টটি প্রস্থান করাও যৌক্তিক। ইতিমধ্যে এ প্রস্তাব করা হয়েছে মন্তব্য দ্বারা ekangas কিন্তু কেউ এই উত্তর সম্পাদিত সঙ্গে এটি আছে -1, যেমন ফিরে মান তাই আমি ভাল হিসাবে এটা সঠিক করতে পারে।

-1যদিও বাশ দ্বারা আর্গুমেন্ট হিসাবে স্বীকৃত exitতা স্পষ্টভাবে নথিভুক্ত নয় এবং সাধারণ পরামর্শ হিসাবে ব্যবহার করা ঠিক নয়। 64এটি সর্বাধিক প্রথাগত মান হিসাবে এটি সংজ্ঞায়িত করা sysexits.hহয় #define EX_USAGE 64 /* command line usage error */। বেশিরভাগ সরঞ্জামগুলিও অবৈধ যুক্তিগুলিতে lsফিরে আসে 2। আমি 2আমার স্ক্রিপ্টগুলিতে ফিরে আসতাম তবে ইদানীং আমি আর সত্যিকারের যত্ন নিই না এবং কেবল 1সমস্ত ত্রুটিতে ব্যবহার করি । তবে আসুন 2এখানে কেবল রাখুন কারণ এটি সবচেয়ে সাধারণ এবং সম্ভবত ওএস-নির্দিষ্ট নয়।

if [[ $# -ne 1 ]]; then
    echo "Illegal number of parameters"
    exit 2
fi

তথ্যসূত্র


2
ওপি: মনে রাখবেন যে [কেবল অন্য আদেশ, চেষ্টা করুন which [
লিও

5
@ লিও কমান্ডগুলি অন্তর্নির্মিত হতে পারে, এবং তা হতে পারে না। ব্যাশ সালে [একটি builtin, যখন হয় [[একটি শব্দ হয়। কিছু পুরানো শেল মধ্যে, [এমনকি অন্তর্নির্মিত হয় না। [বেশিরভাগ সিস্টেমে বাহ্যিক কমান্ড হিসাবে স্বভাবতই কমান্ডগুলি সহ-উপস্থিত থাকে তবে অভ্যন্তরীণ কমান্ডগুলি শেল দ্বারা অগ্রাধিকার পায় যদি আপনি commandবা দিয়ে বাইপাস না করেন exec। শেলটির ডকুমেন্টেশন কীভাবে তারা মূল্যায়ন করে তা পরীক্ষা করুন। তাদের পার্থক্যটি নোট করুন এবং প্রতিটি শেলের মধ্যে তারা কীভাবে আলাদা আচরণ করতে পারে।
কনসোলবাক্স 21

77

আপনি সংখ্যার সাথে ডিল করছেন তবে পাটিগণিতের এক্সপ্রেশনগুলি ব্যবহার করা ভাল ধারণা হতে পারে ।

if (( $# != 1 )); then
    echo "Illegal number of parameters"
fi

বর্তমান ক্ষেত্রে কেন এটি একটি ভাল ধারণা হতে পারে? দক্ষতা, বহনযোগ্যতা এবং অন্যান্য বিষয় বিবেচনা করে, সবচেয়ে সহজ এবং সর্বজনীনভাবে বোঝা সিনট্যাক্স ব্যবহার করা ভাল নয়, অর্থাত্ [ ... ], যখন এই কাজটি ঠিকঠাক হয় এবং কোনও অভিনব ক্রিয়াকলাপের প্রয়োজন হয় না?
সর্বাধিক

@ ম্যাক্স গাণিতিক সম্প্রসারণ $(( ))অভিনব নয় এবং সমস্ত পসিক্স শেল দ্বারা এটি প্রয়োগ করা উচিত। তবে (( ))সিনট্যাক্স (ছাড়াই $) এর অংশ নয়। যদি আপনি কোনও কারণে সীমাবদ্ধ থাকেন তবে অবশ্যই [ ]পরিবর্তে আপনি এটি ব্যবহার করতে পারেন তবে মনে রাখবেন যে তখন আপনারও ব্যবহার করা উচিত নয় [[ ]]। আমি আশা করি আপনি [ ]কীভাবে এই বৈশিষ্ট্যগুলি বিদ্যমান তার কারণগুলি এবং কারণগুলি বুঝতে পেরেছেন । তবে এটি একটি বাশ প্রশ্ন ছিল তাই আমরা বাশকে উত্তর দিচ্ছি ( "থাম্বের নিয়ম হিসাবে, [[স্ট্রিং এবং ফাইলগুলির জন্য ব্যবহৃত হয় you আপনি যদি সংখ্যার তুলনা করতে চান তবে একটি অ্যারিমেটিক এক্সপ্রেসন ব্যবহার করুন" ))।
আলেকস-ড্যানিয়েল জাকিমেনকো-এ।

39

অন ​​[] :! =, =, == ... স্ট্রিং তুলনা অপারেটর এবং -eq, -জিটি ... গণিত বাইনারি রয়েছে।

আমি ব্যবহার করব:

if [ "$#" != "1" ]; then

বা:

if [ $# -eq 1 ]; then

9
==আসলে একটি অননুমোদিত বৈশিষ্ট্য, যা জিএনইউতে কাজ করার ক্ষেত্রে ঘটেtest । এছাড়া ঘটে FreeBSD 'র সাথে কাজ করার জন্য test, কিন্তু পারে কাজ নাও foo বিন্যাস testশুধুমাত্র মান তুলনা হয় =(ঠিক অবগতির জন্য)।
মার্টিন টর্নোইজ

1
এটি ব্যাশ ম্যান এন্ট্রি সম্পর্কিত নথিযুক্ত: যখন == এবং! = অপারেটরগুলি ব্যবহৃত হয় তখন অপারেটরের ডানদিকে স্ট্রিংটি একটি প্যাটার্ন হিসাবে বিবেচনা করা হয় এবং প্যাটার্ন ম্যাচিংয়ের অধীনে বর্ণিত নিয়ম অনুসারে মিলে যায়। শেল অপশনটি নোকাসেম্যাচ সক্ষম থাকলে, বর্ণমালার অক্ষরের ক্ষেত্রে বিবেচনা না করে ম্যাচটি সম্পাদিত হয়। যদি স্ট্রিংটি (==) মেলে বা (! =) প্যাটার্নের সাথে মেলে না, এবং অন্যথায় 1 টির সাথে প্রত্যাবর্তনের মান 0 হবে। প্যাটার্নটির যে কোনও অংশই স্ট্রিং হিসাবে মিলতে বাধ্য করার জন্য উদ্ধৃত করা যেতে পারে।
jvvaras

2
@ ঝাওয়ারস: কার্পেটস্মোকার ঠিক বলেছেন: এটি কিছু বাস্তবায়নে কাজ করতে পারে (এবং প্রকৃতপক্ষে, এটি ব্যাশে কাজ করে) তবে এটি পসিক্স-অনুগত নয় । উদাহরণস্বরূপ, এটি হবে ব্যর্থ সঙ্গে dash: dash -c '[ 1 == 1 ]'। পসিক্স কেবল নির্দিষ্ট করে =এবং না ==
gniourf_gniourf

34

যদি আপনি কেবলমাত্র কোনও যুক্তি অনুপস্থিত থাকে তবে জামিনে আগ্রহী, প্যারামিটার সাবস্টিটিউশন দুর্দান্ত:

#!/bin/bash
# usage-message.sh

: ${1?"Usage: $0 ARGUMENT"}
#  Script exits here if command-line parameter absent,
#+ with following error message.
#    usage-message.sh: 1: Usage: usage-message.sh ARGUMENT

বাশিজম দিয়ে বোঝা নেই?
ডুইট স্পেন্সার

নিবন্ধন করুন
কনসোলবক্স

@ টিমাক আপনার যদি নির্দিষ্ট প্রশ্ন থাকে তবে আমি এটি করতে পারি, তবে লিঙ্কযুক্ত টু নিবন্ধটি আমার চেয়ে আরও ভাল ব্যাখ্যা করে।
প্যাট

13

একটি সাধারণ একটি লাইনার যা কাজ করে তা ব্যবহার করে করা যেতে পারে:

[ "$#" -ne 1 ] && ( usage && exit 1 ) || main

এটি ভেঙে যায়:

  1. প্যারামিটারের আকারের জন্য ব্যাশ ভেরিয়েবল পরীক্ষা করুন $ # সমান নয় (আমাদের সাব কমান্ডের সংখ্যা)
  2. যদি সত্য হয় তবে ব্যবহারের কল করুন () ফাংশন এবং স্থিতি 1 সহ প্রস্থান করুন
  3. অন্যথায় কল করুন প্রধান () ফাংশন

মনে রাখবেন:

  • ব্যবহার () কেবলমাত্র "$ 0: params" প্রতিধ্বনি হতে পারে
  • প্রধান এক দীর্ঘ স্ক্রিপ্ট হতে পারে

1
আপনার যদি সেই লাইনের পরে লাইনগুলির আরও একটি সেট থাকে, তবে এটি ভুল হবে যেহেতু exit 1কেবলমাত্র এটি কেবলমাত্র সমার্থক হিসাবে তৈরি হওয়া সাবসেলের প্রসঙ্গে প্রযোজ্য ( usage; false )। অপশন-পার্সিংয়ের বিষয়টি যখন আসে তখন আমি সেই সরলকরণের সেই ভক্ত নই, তবে আপনি তার { usage && exit 1; }পরিবর্তে ব্যবহার করতে পারেন । অথবা সম্ভবত ঠিক { usage; exit 1; }
কনসোলবক্স

1
@ কনসোলবক্স (ব্যবহার ও& প্রস্থান 1) ksh, zsh এবং ব্যাশের জন্য ফিরে ফিরে 2.0 এ কাজ করে। {...} বাক্য গঠনটি কেবলমাত্র 4.0+ বাশ এর সাম্প্রতিক। যদি কোনওভাবে আপনার পক্ষে সূক্ষ্মভাবে কাজ করে তবে আমাকে ভুল করবেন না তবে মনে রাখবেন যে আপনারা যে ব্যাশের একই প্রয়োগ করেন তা সবাই ব্যবহার করে না এবং আমাদের উচিত বাশিজম নয় মানকে পিক্সিং করা উচিত।
ডুয়াইট স্পেন্সার

আপনি কী বলছেন তা আমি নিশ্চিত নই। {...}একটি সাধারণ বাক্য গঠন এবং এটি সমস্ত শেল ভিত্তিক না shহলেও বেশিরভাগের জন্য উপলব্ধ , এমনকি পুরাতন শেলগুলি পসিএক্স মান অনুসরণ করে না।
কনসোলবক্স

7

পরীক্ষা করে দেখুন এই ব্যাশ cheatsheet, এটা দর্শন সাহায্য করতে পারেন।

পাস হওয়া আর্গুমেন্টগুলির দৈর্ঘ্য পরীক্ষা করতে, আপনি ব্যবহার করুন "$#"

পাস হওয়া আর্গুমেন্টের অ্যারে ব্যবহার করতে, আপনি ব্যবহার করেন "$@"

দৈর্ঘ্য পরীক্ষা করা এবং পুনরাবৃত্তির উদাহরণ হ'ল:

myFunc() {
  if [[ "$#" -gt 0 ]]; then
    for arg in "$@"; do
      echo $arg
    done
  fi
}

myFunc "$@"

এই কৌতুকটি আমাকে সহায়তা করেছিল, তবে আমার এবং আমার পরিস্থিতির জন্য কয়েকটি জিনিস অনুপস্থিত ছিল। আশা করি এটি কাউকে সাহায্য করবে।


0

আপনি যদি নিরাপদে থাকতে চান তবে আমি গোটপটগুলি ব্যবহার করার পরামর্শ দিই।

এখানে একটি ছোট উদাহরণ:

    while getopts "x:c" opt; do
      case $opt in
        c)
          echo "-$opt was triggered, deploy to ci account" >&2
          DEPLOY_CI_ACCT="true"
          ;;
            x)
              echo "-$opt was triggered, Parameter: $OPTARG" >&2 
              CMD_TO_EXEC=${OPTARG}
              ;;
            \?)
              echo "Invalid option: -$OPTARG" >&2 
              Usage
              exit 1
              ;;
            :)
              echo "Option -$OPTARG requires an argument." >&2 
              Usage
              exit 1
              ;;
          esac
        done

এখানে আরও বিশদ দেখুন উদাহরণস্বরূপ http://wiki.bash-hackers.org/howto/getopts_tutorial


0

এখানে কেবল একটি প্যারামিটার দেওয়া হয়েছে কিনা তা পরীক্ষা করার জন্য একটি সাধারণ একটি লাইনার অন্যথায় স্ক্রিপ্ট থেকে প্রস্থান করুন:

[ "$#" -ne 1 ] && echo "USAGE $0 <PARAMETER>" && exit

-1

পরীক্ষার শর্তের মধ্যে আপনার ফাঁকা স্থান যুক্ত করা উচিত:

if [ $# -ne 1 ]; 
    then echo "illegal number of parameters"
fi

আশা করি এটা কাজে লাগবে.

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