বাশ শেল স্ক্রিপ্টে ইনপুট আর্গুমেন্টের অস্তিত্ব পরীক্ষা করুন


1335

আমার একটি ইনপুট আর্গুমেন্টের অস্তিত্ব পরীক্ষা করতে হবে। আমি নিম্নলিখিত স্ক্রিপ্ট আছে

if [ "$1" -gt "-1" ]
  then echo hi
fi

আমি পাই

[: : integer expression expected

ইনপুট আর্গুমেন্ট 1 উপস্থিত আছে কিনা তা দেখার জন্য আমি কীভাবে চেক করব?

উত্তর:


2328

এটাই:

if [ $# -eq 0 ]
  then
    echo "No arguments supplied"
fi

$#পরিবর্তনশীল আপনি ইনপুট আর্গুমেন্ট স্ক্রিপ্ট পাস হয় সংখ্যা বলতে হবে।

অথবা আপনি এটি পরীক্ষা করতে পারেন যে কোনও যুক্তিটি খালি স্ট্রিং কিনা বা পছন্দ নয়:

if [ -z "$1" ]
  then
    echo "No argument supplied"
fi

-zযদি "$ 1" সম্প্রসারণ একটি নাল স্ট্রিং বা না সুইচ পরীক্ষা হবে। এটি যদি নাল স্ট্রিং হয় তবে শরীরটি কার্যকর করা হয়।


62
আমি এটি করতে চান, সংক্ষিপ্ত বাক্য গঠন এবং এখনও পসিক্স গ্রহণযোগ্য। [ -z "$1" ] && echo "No argument supplied" আমি ওয়ান-লাইনার পছন্দ করি, কারণ এগুলি আমার পক্ষে সহজ; ব্যবহারের সাথে তুলনা করে প্রস্থান মূল্য পরীক্ষা করাও দ্রুতif
জেএম বেকার

168
exit 1স্ক্রিপ্টটির কাজ করার জন্য যখন আর্গুমেন্টটির প্রয়োজন হয় আপনি সম্ভবত ইফ ব্লকের ভিতরে আপনার ইকোসের শেষে একটি যুক্ত করতে চান । স্পষ্টতই, তবে সম্পূর্ণতার জন্য লক্ষণীয়।
মিসানফোর্ড

16
প্রথম যুক্তিটি আরম্ভ করার জন্য খালি হলেও এটি খুব কমই কার্যকর হলেও এটি সম্ভব; programname "" secondarg third$#চেক unambiguously আর্গুমেন্টের সংখ্যা পরীক্ষা করে।
ট্রিপলি

39
কোনও নুব-র জন্য, বিশেষত যে কেউ স্ক্রিপ্টিংহীন পটভূমি থেকে আসে, এই বিষয়গুলি সম্পর্কে কিছু অদ্ভুততা উল্লেখ করাও গুরুত্বপূর্ণ। আপনি আরও উল্লেখ করতে পারেন যে খোলার পরে এবং বন্ধ বন্ধনীটির পরে আমাদের একটি স্থান প্রয়োজন। অন্যথায় জিনিসগুলি কাজ করে না। আমি নিজেই একটি স্ক্রিপ্টিং নুব (আমি সি ব্যাকগ্রাউন্ড থেকে এসেছি) এবং এটি হার্ড উপায় খুঁজে পেয়েছি। আমি কেবল তখনই পুরো জিনিসটি "যেমন" কপি করার সিদ্ধান্ত নিয়েছিলাম যে জিনিসগুলি আমার পক্ষে কাজ করেছিল। এটি তখনই বুঝতে পেরেছিলাম যে খোলার ধনুর্বন্ধনী পরে এবং বন্ধের আগে আমাকে একটি স্থান ছেড়ে যেতে হবে।
হাইউনমিট

72

346

এইভাবে প্রদর্শন করা আরও ভাল

if [[ $# -eq 0 ]] ; then
    echo 'some message'
    exit 1
fi

আপনার খুব কম যুক্তি থাকলে আপনার সাধারণত প্রস্থান করতে হবে।


72
না এটি নয়: এটি exit 1যা আপনি সাধারণত চান, এটি ব্যবহার করে এবং [[ ]]যা (iirc) সাধারণত আরও যুক্তিসঙ্গত হয় সেই পরীক্ষাটি ব্যবহার করে । সুতরাং লোকেরা অন্ধভাবে অনুলিপি কোড-পেস্টিং কোড এটি ভাল উত্তর।
শেফার্ড

42
[] এবং [[]] এর মধ্যে পার্থক্য সম্পর্কে আরও জানতে
স্ট্যাকওভারফ্লো.com/ প্রশ্নগুলি

103

কিছু ক্ষেত্রে আপনাকে পরীক্ষা করে নেওয়া দরকার যে ব্যবহারকারী স্ক্রিপ্টে কোনও যুক্তি পাস করেছে কিনা এবং যদি না হয় তবে ডিফল্ট মানটিতে ফিরে যান fall নীচের স্ক্রিপ্টে পছন্দ করুন:

scale=${2:-1}
emulator @$1 -scale $scale

এখানে যদি ব্যবহারকারী scale2 য় প্যারামিটার হিসাবে পাস না করে থাকে তবে আমি ডিফল্টর সাথে অ্যান্ড্রয়েড এমুলেটর চালু করি -scale 1${varname:-word}একটি সম্প্রসারণ অপারেটর। এছাড়াও অন্যান্য সম্প্রসারণ অপারেটর রয়েছে:

  • ${varname:=word}যা মান ফিরিয়ে দেওয়ার পরিবর্তে অপরিজ্ঞাত সেট করে ;varnameword
  • ${varname:?message}যা হয় varnameযদি এটি সংজ্ঞায়িত হয় এবং শূন্য না হয় বা মুদ্রণ না করে messageএবং স্ক্রিপ্টটি বন্ধ করে দেয় (প্রথম উদাহরণের মতো);
  • ${varname:+word}যা wordকেবলমাত্র varnameসংজ্ঞায়িত এবং শূন্য না হলে ফিরে আসে ; অন্যথায় নাল ফেরায়।

1
উপরের উদাহরণটি ব্যবহার বলে মনে হচ্ছে ${varname?message}। অতিরিক্ত কি :একটি টাইপো, বা এটি আচরণ পরিবর্তন করে?
একি

6
একি, ":" একটি বিল্টিন কমান্ড এবং এই উদাহরণটিতে / বিন / সত্যের জন্য শর্টহ্যান্ড। এটি একটি করণীয় কমান্ড উপস্থাপন করে যা মূলত এটি সরবরাহ করা যুক্তিগুলি উপেক্ষা করে। "$ বর্ণ" এর বিষয়বস্তু (যা আপনি অবশ্যই হতে চান না) এর অর্থবোধককে কার্যকর করার চেষ্টা থেকে দোভাষীকে আটকাতে এই পরীক্ষায় এটি প্রয়োজনীয়। এছাড়াও লক্ষণীয় মূল্য; আপনি নিজের ইচ্ছে মত এই পদ্ধতিতে যতগুলি ভেরিয়েবল পরীক্ষা করতে পারেন। এবং সমস্ত নির্দিষ্ট ত্রুটি বার্তা সহ। অর্থাত্: ${1?"First argument is null"} ${2?"Please provide more than 1 argument"}
ব্যবহারকারীর সাথে বন্ধুত্বপূর্ণভাবে

48

চেষ্টা করুন:

 #!/bin/bash
 if [ "$#" -eq  "0" ]
   then
     echo "No arguments supplied"
 else
     echo "Hello world"
 fi

4
কেন আপনার জন্য ডাবল কোট প্রয়োজন $#এবং 0?
ব্যবহারকারী 13107

1
যদি আমরা double # এবং 0 এর মতো ডাবল-কোট ব্যতীত ব্যবহার না করি তবে কোনও সমস্যা নেই
রঞ্জিতকুমার টি

উইন্ডোজগুলিতে, মিংডউ এটিই একমাত্র উপায়।
লাজোস মেসারোস

2
এই উত্তরটি আমি সবে তৈরি একটি স্ক্রিপ্টের দুর্দান্ত সূচনা প্রদান করে। দেখানোর জন্য ধন্যবাদ else
ক্রিস কে

2
@ ইউজার 13107 বাশ-এ ডাবল উদ্ধৃত ভেরিয়েবলগুলি গ্লোববিং (যেমন ফাইলের নামগুলি প্রসারিত করা foo*) এবং শব্দ বিভাজন (অর্থাত্ যদি সাদা বাক্সে থাকে তবে বিষয়বস্তুগুলিকে বিভক্ত করা) প্রতিরোধ করে। এই ক্ষেত্রে উদ্ধৃতি দেওয়ার প্রয়োজন নেই $#কারণ এই দুটি ক্ষেত্রেই প্রযোজ্য নয়। বরাত দিয়ে 0আরো প্রয়োজন হয় না, কিন্তু কিছু মানুষ মান উদ্ধৃত করা যেহেতু তারা সত্যিই স্ট্রিং হয় পছন্দ করা এবং যে এটি আরো স্পষ্ট করে তোলে।
ডেনিস

39

স্ক্রিপ্টে যুক্তিগুলি পাস করা হয়েছে কিনা তা সনাক্ত করার আরেকটি উপায়:

((!$#)) && echo No arguments supplied!

লক্ষ্য করুন (( expr ))অভিব্যক্তি ঘটায় নিয়ম অনুযায়ী মূল্যায়ন করা শেল পাটিগণিত

কোনও যুক্তির অভাবে প্রস্থান করার জন্য, কেউ বলতে পারেন:

((!$#)) && echo No arguments supplied! && exit 1

উপরের বলার আর একটি (অ্যানালগাস) উপায় হ'ল :

let $# || echo No arguments supplied

let $# || { echo No arguments supplied; exit 1; }  # Exit if no arguments!

help let বলেছেন:

let: let arg [arg ...]

  Evaluate arithmetic expressions.

  ...

  Exit Status:
  If the last ARG evaluates to 0, let returns 1; let returns 0 otherwise.

2
-1 কোনও যুক্তির অস্তিত্ব বৈধকরণের ক্ষেত্রে এটি সবচেয়ে খারাপ পদ্ধতি হতে পারে .. এবং এটি ইতিহাসের বিকল্পটিকে ট্রিগার করতে এবং সম্ভাব্যভাবে খারাপ কাজগুলি করতে পারে।
user.friendly

2
এর পরিবর্তে exitআমার zsh প্রক্রিয়াটিকে হত্যা করে, আমি ব্যবহার করি returnযা এটি হত্যা করে না
টিমো

কেন ((!$#))ইতিহাস প্রতিস্থাপন ট্রিগার হবে ?
Zhro

25

আমি প্রায়শই সরল স্ক্রিপ্টগুলির জন্য এই স্নিপেট ব্যবহার করি:

#!/bin/bash

if [ -z "$1" ]; then
    echo -e "\nPlease call '$0 <argument>' to run this command!\n"
    exit 1
fi

1
সুতরাং, এটি আপনার ব্যবহার করতে হবে কেবল একটি যুক্তি?
দানিজেল

21

কেবলমাত্র উল্লেখ করার জন্য আরও বেস পয়েন্ট রয়েছে বলেই আমি যুক্ত করব যে আপনি কেবল নিজের স্ট্রিংটি শূন্য পরীক্ষা করতে পারবেন:

if [ "$1" ]; then
  echo yes
else
  echo no
fi

তেমনি আপনি যদি আর্গ গণনাটি আশা করেন তবে কেবল আপনার শেষ পরীক্ষা করুন:

if [ "$3" ]; then
  echo has args correct or not
else
  echo fixme
fi

এবং তাই কোনও আরগ বা var সঙ্গে


4

আপনি যদি আর্গুমেন্টটি উপস্থিত রয়েছে কিনা তা পরীক্ষা করতে চান, আপনি আর্গুমেন্টের # টি আপনার টার্গেট আর্গুমেন্ট সংখ্যার চেয়ে বড় বা সমান কিনা তা পরীক্ষা করতে পারেন।

নিম্নলিখিত স্ক্রিপ্টটি দেখায় যে এটি কীভাবে কাজ করে

test.sh

#!/usr/bin/env bash

if [ $# -ge 3 ]
then
  echo script has at least 3 arguments
fi

নিম্নলিখিত আউটপুট উত্পাদন করে

$ ./test.sh
~
$ ./test.sh 1
~
$ ./test.sh 1 2
~
$ ./test.sh 1 2 3
script has at least 3 arguments
$ ./test.sh 1 2 3 4
script has at least 3 arguments

3

একটি ছোট অনুস্মারক হিসেবে, ব্যাশ সাংখ্যিক পরীক্ষা অপারেটার শুধুমাত্র পূর্ণসংখ্যার কাজ ( -eq, -lt, -ge, ইত্যাদি)

আমি নিশ্চিত করতে চাই যে আমার ars ভার্সগুলি অন্তর্নিহিত

var=$(( var + 0 ))

আমি তাদের পরীক্ষা করার আগে, কেবল "[:: পূর্ণসংখ্যার আর্গ প্রয়োজনীয়" ত্রুটির বিরুদ্ধে রক্ষা করতে।


1
ঝরঝরে কৌশল, তবে দয়া করে নোট করুন: পাটিগণিতগুলিতে ভাসমানদের পরিচালনা করতে বাশের অক্ষমতার কারণে এই পদ্ধতিটি একটি সিনট্যাক্স ত্রুটি সৃষ্টি করতে পারে এবং শূন্য-শূন্যকে ফিরিয়ে দিতে পারে যা যেখানে ইরাক্সিট সক্ষম করা হয়েছে তাতে বাধা হয়ে দাঁড়াবে। var=$(printf "%.0f" "$var")ভাসা পরিচালনা করতে পারে তবে স্ট্রিং দেওয়ার সময় অ-শূন্য প্রস্থান থেকে ভুগতে পারে। আপনি একটি awk কিছু মনে না করেন, তাহলে এই পদ্ধতি আমি ব্যবহারের একটি পূর্ণসংখ্যা প্রয়োগ সবচেয়ে জোরালো হবে বলে মনে হয়: var=$(<<<"$var" awk '{printf "%.0f", $0}')। যদি ভারটি সেট না করা থাকে তবে এটি "0" এ ডিফল্ট হয়। যদি ভাসা ভাসমান হয় তবে এটি নিকটতম পূর্ণসংখ্যার সাথে বৃত্তাকার হয়। নেতিবাচক মানগুলি ব্যবহার করাও ঠিক।
user.friendly

0

একটি লাইনার বাশ ফাংশন বৈধতা

myFunction() {

    : ${1?"forgot to supply an argument"}
    if [ "$1" -gt "-1" ]; then
        echo hi
    fi

}

ফাংশন নাম এবং ব্যবহার যোগ করুন

myFunction() {

    : ${1?"forgot to supply an argument ${FUNCNAME[0]}() Usage:  ${FUNCNAME[0]} some_integer"}
    if [ "$1" -gt "-1" ]; then
        echo hi
    fi

}

পূর্ণসংখ্যা কিনা তা যাচাই করার জন্য বৈধতা যুক্ত করুন

অতিরিক্ত বৈধতা যুক্ত করতে, উদাহরণ স্বরূপ যুক্তিটি একটি পূর্ণসংখ্যা কিনা তা পরীক্ষা করে দেখুন, বৈধতা ফাংশনটি কল করার জন্য বৈধকরণের একটি লাইনার সংশোধন করুন:

: ${1?"forgot to supply an argument ${FUNCNAME[0]}() Usage:  ${FUNCNAME[0]} some_integer"} && validateIntegers $1 || die "Must supply an integer!"

তারপরে, একটি বৈধতা ফাংশন নির্মাণ করুন যা আর্গুমেন্টকে বৈধ করে, 0 সাফল্যে ফিরে আসে, 1 ব্যর্থতায় এবং ডাই ফাংশন যা ব্যর্থতার উপরে স্ক্রিপ্ট বাতিল করে

validateIntegers() {

    if ! [[ "$1" =~ ^[0-9]+$ ]]; then
        return 1 # failure
    fi
    return 0 #success

}

die() { echo "$*" 1>&2 ; exit 1; }

এমনকি সহজ - কেবল ব্যবহার করুন set -u

set -u প্রতিটি রেফারেন্সড ভেরিয়েবল ব্যবহারের সময় সেট করা আছে তা নিশ্চিত করে, তাই কেবল এটি সেট করে তা ভুলে যান

myFunction() {
    set -u
    if [ "$1" -gt "-1" ]; then
        echo hi
    fi

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