একটি 'যদি' বিবৃতিতে কোনও ভেরিয়েবল বিদ্যমান কিনা তা আমি কীভাবে চেক করব?


69

আমাকে একটি ifবিবৃতিতে একটি ভেরিয়েবলের অস্তিত্ব পরীক্ষা করতে হবে । এর প্রভাব কিছু:

if [ -v $somevar ]
then
    echo "Variable somevar exists!"
else
    echo "Variable somevar does not exist!"

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


আপনি সেট করতে চান তাহলে $somevarযদি পরিবর্তনশীল বিদ্যমান নেই মান / স্ট্রিং: ${somevar:=42}
সাইরাস

ব্যক্তিগতভাবে, আমি কেবল শূন্যতার জন্য ( [ -n "$var" ]বা [ ! -z "$var" ]) পরীক্ষা করার প্রবণতা রাখি । আমি মনে করি অস্তিত্ব / অস্তিত্বের চেকগুলি খুব সূক্ষ্ম এবং আমি আমার কোডটি মোটা এবং সহজ পছন্দ করি।
পিএসকোকিক

আপনি কেন যে বনাম প্রয়োজন [ -n "$var" ]? সম্পর্কিত: স্ট্যাকওভারফ্লো.com
সিরো সান্তিলি 新疆 改造 中心 法轮功 六四 事件

উত্তর:


97

আধুনিক বাশে (সংস্করণ ৪.২ এবং তার বেশি):

[[ -v name_of_var ]]

থেকে help test:

-v VAR, শেল ভেরিয়েবল VAR সেট করা থাকলে সত্য


3
এছাড়াও একক বন্ধনী সঙ্গে কাজ করে: [ -v name_of_var ]
meuh

7
হ্যাশ এবং অ্যারেগুলির জন্য, ভেরিয়েবলের কী / ইনডিস "0" এর উপাদান না থাকলে এটি মিথ্যা প্রত্যাবর্তন করবে। নেম্রেফগুলির জন্য, এটি লক্ষ্য নির্ধারিত কিনা তা পরীক্ষা করে। মনে হচ্ছে বিশেষ পরামিতি জন্য কাজ করে না $1, $-, $#...
Stéphane Chazelas

4
এই বৈশিষ্ট্যটি কেবল ব্যাশ বিল্টিনে testবা [; এটি পাওয়া যায় না /usr/bin/testman testসঙ্গে তুলনা করুন help test
লাকাতা

@ মার্কলাকাতা ডান, কারণ বাহ্যিক কমান্ডগুলি শেলের অভ্যন্তরীণ অবস্থা জানতে পারে না।
ক্রিস ডাউন

উম্মে কি সর্বদা এটি [[-v "$ নাম_ওফ_ভার"] হওয়া উচিত নয়?
আলেকজান্ডার মিলস

24

আপনার বিদ্যমান বলতে কী বোঝায় তা নির্ভর করে ।

ঘোষিত হলেও নির্ধারিত নয় এমন একটি ভেরিয়েবল কি বিদ্যমান ?

খালি তালিকা নির্ধারিত একটি অ্যারে (বা হ্যাশ) ভেরিয়েবলের কি উপস্থিত রয়েছে ?

যা বর্তমানে নির্ধারিত করা হয় না একটি পরিবর্তনশীল করার জন্য একটি nameref পরিবর্তনশীল ইশারা দেয় অস্তিত্ব ?

আপনি বিবেচনা না $-, $#, $1ভেরিয়েবল? (পসিক্স দেয় না)।

বোর্নের মতো শেলগুলিতে, ক্যানোনিকাল উপায়টি হ'ল:

if [ -n "${var+set}" ]; then
  echo '$var was set'
fi

এটি স্কেলার ভেরিয়েবল এবং অন্যান্য পরামিতিগুলির জন্য কাজ করে যে কোনও ভেরিয়েবলকে একটি মূল্য নির্ধারণ করা হয়েছে কিনা তা খালি করার জন্য (খালি বা না, স্বয়ংক্রিয়ভাবে, পরিবেশ, অ্যাসিগমেন্টস read, forবা অন্যান্য) থেকে কাজ করে tell

শাঁস একটি আছে জন্য typesetঅথবা declareকমান্ড যে হিসাবে প্রতিবেদন না সেট ভেরিয়েবল যে হয়েছে ঘোষিত কিন্তু নির্ধারিত ছাড়া zsh

শেলগুলির জন্য যা অ্যারে সমর্থন করে, ব্যতীত yashএবং সেট অ্যারে ভেরিয়েবল zshহিসাবে রিপোর্ট করবে না যদি না ইনডিস 0 এর উপাদান সেট করা থাকে।

জন্য bash(কিন্তু ksh93না zsh), টাইপ ভেরিয়েবলের জন্য এসসিয়েতিভ আরে , যে তাদের প্রতিবেদন না সেট চাবি "0" সেট করা হয়েছে তাদের উপাদান যদি না।

নেমরেফ টাইপের ভেরিয়েবলের জন্য ksh93এবং কেবল যদি সেই নামটিফ দ্বারা বর্ণিত ভেরিয়েবলটি সেট হিসাবে বিবেচিত হয় তবেই এটি সত্য হয় ।bash

জন্য ksh, zshএবং bash, একটি সম্ভাব্য ভালো পদ্ধতির হতে পারে:

if ((${#var[@]})); then
  echo '$var (or the variable it references for namerefs) or any of its elements for array/hashes has been set'
fi

জন্য ksh93, zshএবং bash4.4 বা তার উপরে রয়েছে রয়েছে:

if typeset -p var 2> /dev/null | grep -q '^'; then
  echo '$var exists'
fi

যা সেট করা বা ঘোষিত ভেরিয়েবলের প্রতিবেদন করবে।


1
declare -p/ এখন typeset -pকাজ bashকরে।
ক্যাস

1
@সি এ এস নং. ঘোষিত নয় তবে ভেরিয়েবল সেট করে নেই। ব্যবহার করে দেখুন bash -c 'typeset -i a; typeset -p a'এবং সঙ্গে তুলনা ksh93বা zsh
স্টাফেন চেজেলাস 21

আমাকে এখানে পয়েন্ট দেওয়ার জন্য ধন্যবাদ। এছাড়াও আমার প্রশ্নটি দেখুন unix.stackexchange.com/q/280893/674
টিম

@ ক্যাস, যা বাশ -৪.৪ (সেপ্টেম্বর ২০১ in এ প্রকাশিত) দিয়ে পরিবর্তিত হয়েছে, আমি এটি সম্পাদনা করেছি
স্টাফেন চ্যাজেলাস

9

এসও- তে উত্তরে বর্ণিত হিসাবে , এখানে যাচাই করার একটি উপায়:

if [ -z ${somevar+x} ]; then echo "somevar is unset"; else echo "somevar is set to '$somevar'"; fi

যেখানে $ {সোমবার + এক্স হ'ল একটি প্যারামিটার বিস্তৃতি যা ভেরটি সেট না করা থাকলে শূন্যের জন্য মূল্যায়ন করে এবং অন্যথায় স্ট্রিং "x" কে প্রতিস্থাপন করে।

-nঅন্যান্য উত্তরের পরামর্শ অনুসারে ব্যবহার করা কেবল ভেরিয়েবলের খালি স্ট্রিং রয়েছে কিনা তা পরীক্ষা করবে। এটি তার অস্তিত্ব পরীক্ষা করবে না।


2
$somevarহ্যান্ডেল করার জন্য আপনাকে উদ্ধৃতি দিতে হবে IFS=x। হয় বা উদ্ধৃতি x
মাইকজার্ভ

1
@ মাইকজার্ভস ধন্যবাদ, আমি প্রান্তের মামলাগুলি শিখতে পছন্দ করি :) আপনার অর্থ কি if [ -z "${somevar+x}" ]? কোটিং এখনও ভিতরে প্রয়োজন হবে [[এবং ]]?
টম হেল

@ টমহেল - হ্যাঁ, বিরল ক্ষেত্রে। [ testযেমন স্বাভাবিক ভাবেই উপর ওপরেই নির্ভরশীল হতে উচিত আদেশ পরীক্ষা নামোচ্চারণের এ রেন্ডার করতে যা যদি আপনি কোন প্রোগ্রাম কমান্ড লাইন দ্বারা যার ফলে পড়তে হবে কারণ উচিত প্রয়োগ রুটিন কমান্ড লাইন প্যারামিটার, এবং তাই স্বাভাবিক সম্প্রসারণ ও ব্যাখ্যা গ্রহণ। পরীক্ষা {! + "!"}
মাইকসার্ভ

@ মিকসার্ভ আমি অনুমান করি যে হ্যাঁ আমার দ্বিতীয় প্রশ্নটি হ'ল ... প্রথমটি কি হ্যাঁ?
টম হেল

1
+1 টি; এটি কার্যকর হওয়ার সময় এটি করার সবচেয়ে সহজ উপায় বলে মনে হয় set -uএবং বাশ সংস্করণটি প্রাক-৪.২ রয়েছে।
কাইল স্ট্র্যান্ড

4

POSIXly:

! (: "${somevar?}") 2>/dev/null && echo somevar unset

অথবা আপনি আপনার শেলটি আপনার জন্য বার্তাটি প্রদর্শন করতে পারেন:

(: "${somevar?}")
zsh: somevar: parameter not set

@ মিমকিজার: হ্যাঁ, অবশ্যই এটি করার অনেক উপায় রয়েছে। প্রথমত, আমি সঙ্গে এটি সদৃশ হবে এই । তবে এই প্রশ্নে ওপি কেবলমাত্র চেক করতে চায়, তিনি দাবি করেননি যে তিনি ভেরিয়েবল আনসেট না হলে প্রস্থান করতে বা রিপোর্ট করতে চান, তাই আমি সাব-শেলতে একটি চেক নিয়ে এসেছি।
cuonglm

2
ঠিক আছে, আমি জানি, তবে এটি অবশ্যই কারণ আপনি এটি পরীক্ষা করার মতো সেরা উপায় হতে পারে না এমন ইঙ্গিত দেয় failure এটি ব্যর্থতার বিরুদ্ধে থামানো পদক্ষেপ, এটি কোনও সহজ উপায় পরিচালনা করার অনুমতি দেয় না doesn't একটি ব্যর্থতা. বহনযোগ্য এমনকি একটি trapশুধুমাত্র প্রস্থান কাজ করতে পারেন। এগুলিই আমি বলছি - এটি কেবল পাস হিসাবে প্রয়োগ হয় না / খুব ভালভাবে ব্যর্থ হয়। এবং এটি আমিও কথা বলছি না - আমি ঠিক এই আগেই করেছি এবং আমাকে বোঝানোর জন্য এটি এই জাতীয় মন্তব্যের সাথে কিছুটা মন্তব্য করেছে। সুতরাং, আমি কেবল ভেবেছিলাম আমি এটি অগ্রিম প্রদান করব।
মাইকজার্ভ

1
@ মিমকিজার: আচ্ছা, ভাল, এটি একটি ভাল বিষয়। আমি কেবল
আশ্চর্যই

2
if set|grep '^somevar=' >/dev/null;then
    echo "somevar exists"
else
    echo "does not exist"
fi

আমি এটিকে কিছুটা অদক্ষ বলে ধারণা করব, তবে এটি খুব সহজ এবং shসামঞ্জস্যপূর্ণ, যা আমার প্রয়োজন ঠিক তাই।
হোইজুই

2
printf ${var+'$var exists!\n'}

... কখনই প্রিন্ট করবে না যখন তা হয় না। অথবা ...

printf $"var does%${var+.}s exist%c\n" \ not !

... আপনাকে যেভাবেই বলবে।

আপনি আপনার অবস্থার জন্য যথাযথ বিন্যাসের স্ট্রিংয়ে গতিশীলভাবে প্রসারিত করতে একটি পরীক্ষার রিটার্ন মানটি ব্যবহার করতে পারেন:

[ "${var+1}" ]
printf $"var does%.$?0s exist%c\n" \ not !

আপনি printfপ্রতিস্থাপনের ভিত্তিতে ব্যর্থও করতে পারেন ...

printf $"var does%${var+.}s exist%c\n%.${var+b}d" \
        \ not ! \\c >&"$((2${var+-1}))" 2>/dev/null

... যা $var does not exist!স্টার্ডারকে প্রিন্ট করে এবং $varআনসেট না করা অবস্থায় 0 ব্যতীত অন্যকে ফেরত দেয় তবে প্রিন্ট $var does exist!করে স্টাডাউট এবং $varসেট হয়ে গেলে 0 ফেরত দেয় ।


1

এই সাধারণ লাইনটি কাজ করে (এবং বেশিরভাগ পসিক্স শেলের উপর কাজ করে):

${var+"false"} && echo "var is unset"

বা, একটি দীর্ঘ আকারে লিখিত:

unset var

if ${var+"false"}
then
   echo "var is unset"
fi

সম্প্রসারণটি হ'ল:

  • যদি ভেরটির মান থাকে (এমনকি নালও) তবে মিথ্যা প্রতিস্থাপন করা হয়
  • যদি ভেরটির "কোন মান নেই", তবে "কোন মান" (নাল) প্রতিস্থাপন করা হয়।

${var+"false"}সম্প্রসারণ হয় "মিথ্যা" এর "নাল" করার বিস্তৃতি ঘটে।
তারপরে, "কিছুই না" বা "মিথ্যা" কার্যকর হয় এবং প্রস্থান কোড সেট হয়।

প্রস্থানটি নিজেই এক্সটেনশান (এক্সিকিউট) দ্বারা নির্ধারিত হওয়ায় কমান্ডটি test( [বা [[) কল করার দরকার নেই ।


হ্যাঁ, sh অনুকরণে zsh এর কিছু পুরানো সংস্করণ বাদে যখন $IFSf, a, l, s বা e থাকে। অন্যান্য উত্তরের মতো, অ্যারে, হ্যাশ বা অন্যান্য ধরণের ভেরিয়েবলের কেস রয়েছে যা উল্লেখ করতে পারে।
স্টাফেন চেজেলাস

@ স্টাফেনচেজেলাস আমি লিখেছি most POSIX shellsmost মানেIn the greatest number of instances , না সব। ... ... সুতরাং, হ্যাঁ, একটি অস্পষ্ট অবস্থায় when $IFS contains f, a, l, s or eএবং কিছু অস্পষ্ট শেলের জন্য some old versions of zshএটি ব্যর্থ হয়: কী ধাক্কা !. আমার ধারণা করা উচিত যে এই ধরনের বাগটি অনেক আগেই সমাধান হয়ে গেছে। ... ... আপনি কি প্রস্তাব দিচ্ছেন যে অনেক আগে থেকেই ভাঙা শাঁসের জন্য আমাদের কোড লিখতে হবে ?.

@ স্টাফেনচাজেলাস এছাড়াও: প্রশ্নের শিরোনামটি খুব নির্দিষ্ট: বাশ।

বাইনারি জেব্রা ???
মাইকসার্ভ

0

খাঁটি শেল উপায়:

[ "${var+1}" ] || echo "The variable has not been set"

পরীক্ষার স্ক্রিপ্ট:

#!/bin/sh
echo "Test 1, var has not yet been created"
[ "${var+1}" ] || echo "The variable has not been set"

echo "Test 2, var=1"
var=1
[ "${var+1}" ] || echo "The variable has not been set"

echo "Test 3, var="
var=
[ "${var+1}" ] || echo "The variable has not been set"

echo "Test 4, unset var"
unset var
[ "${var+1}" ] || echo "The variable has not been set"
echo "Done"

ফলাফল:

Test 1, var has not yet been created
The variable has not been set
Test 2, var=1
Test 3, var=
Test 4, unset var
The variable has not been set
Done

1
ভেরিয়েবল নাল স্ট্রিংয়ে সেট হয়ে গেলে ব্যর্থ হয়।
টম হেল

0

4.4.19 বাশ সহ নিম্নলিখিতটি আমার জন্য কাজ করেছে। এখানে একটি সম্পূর্ণ উদাহরণ

$export MAGENTO_DB_HOST="anyvalue"

#!/bin/bash

if [ -z "$MAGENTO_DB_HOST" ]; then
    echo "Magento variable not set"
else
    echo $MAGENTO_DB_HOST
fi

-1

আপনি ifব্যাশে ঘোষিত ভেরিয়েবলের অস্তিত্ব পরীক্ষা করতে কমান্ডটি ব্যবহার করতে পারবেন না তবে -vবিকল্পটি নতুন ব্যাশে উপস্থিত রয়েছে তবে এটি বহনযোগ্য নয় এবং আপনি এটি পুরানো bashসংস্করণগুলিতে ব্যবহার করতে পারবেন না । কারণ আপনি যখন ভেরিয়েবলটি ব্যবহার করেন এটি উপস্থিত না থাকলে এটি একই সাথে জন্মগ্রহণ করবে।

উদাহরণস্বরূপ কল্পনা করুন যে আমি MYTESTভেরিয়েবলের জন্য কোনও মান ব্যবহার করি নি বা নির্ধারণ করি নি , তবে আপনি যখন ইকো কমান্ড ব্যবহার করছেন তখন এটি আপনাকে কিছুই দেখায় না! অথবা আপনি যদি if [ -z $MYTEST ]এটি ব্যবহার করেন তবে শূন্যের মান ফিরে আসবে! এটি আর একটি প্রস্থান স্থিতি ফিরিয়ে দেয়নি, যা আপনাকে বলে যে এই পরিবর্তনশীলটির অস্তিত্ব নেই!

এখন আপনার দুটি সমাধান রয়েছে ( -vবিকল্প ছাড়াই ):

  1. declareকমান্ড ব্যবহার করে ।
  2. setকমান্ড ব্যবহার করে ।

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

MYTEST=2
set | grep MYTEST
declare | grep MYTEST

কিন্তু দুর্ভাগ্যক্রমে এই কমান্ডগুলি মেমরিতে আপনাকে ভার্য ভারগুলিও দেখায়! আপনি declare -p | grep -q MYTEST ; echo $?ক্লিনার ফলাফলের জন্য কমান্ড ব্যবহার করতে পারেন ।


-1

ভেরিয়েবল ঘোষণা / আনসেট করা হয়েছে কিনা তা পরীক্ষা করার কাজ to

খালি সহ $array=()


@ গিলসের উত্তর ছাড়াও

case " ${!foobar*} " in
  *" foobar "*) echo "foobar is declared";;
  *) echo "foobar is not declared";;
esac

- যা আমি একটি ফাংশন মধ্যে এটি encapsulate জন্য একটি উপায় খুঁজে পাইনি - আমি একটি সহজ সংস্করণে দেখানো হয় আংশিকভাবে উপর ভিত্তি করে তৈরি যোগ করতে চান রিচার্ড হ্যানসেন এর উত্তর কিন্তু ঠিকানাটি ফাঁদ যে একটি খালি ক্ষেত্রেও একই ঘটনা ঘটে না array=():

# The first parameter needs to be the name of the variable to be checked.
# (See example below)

var_is_declared() {
    { [[ -n ${!1+anything} ]] || declare -p $1 &>/dev/null;}
}

var_is_unset() {
    { [[ -z ${!1+anything} ]] && ! declare -p $1 &>/dev/null;} 
}
  • ভেরিয়েবলটি (আন) সেট করা থাকলে প্রথমে পরীক্ষার মাধ্যমে, প্রয়োজন না হলে ঘোষণা করার কলটি এড়ানো যায়,
  • তবে যদি খালিটির $1নাম থাকে তবে $array=()ঘোষণা করার জন্য কলটি নিশ্চিত করেছে যে আমরা সঠিক ফলাফল পেয়েছি
  • ঘোষিত হিসাবে / ডেভেল / নালকে খুব বেশি ডেটা পাঠানো হয় নি কেবল তখনই বলা হয় যদি হয় ভেরিয়েবলটি সেট না করে থাকে বা খালি অ্যারে হয়।


নিম্নলিখিত কোডের সাথে ফাংশনগুলি পরীক্ষা করা যেতে পারে:

( # start a subshell to encapsulate functions/vars for easy copy-paste into the terminal
  # do not use this extra parenthesis () in a script!

var_is_declared() {
    { [[ -n ${!1+anything} ]] || declare -p $1 &>/dev/null;}
}

var_is_unset() {
    { [[ -z ${!1+anything} ]] && ! declare -p $1 &>/dev/null;} 
}

:;       echo -n 'a;       '; var_is_declared a && echo "# is declared" || echo "# is not declared"
a=;      echo -n 'a=;      '; var_is_declared a && echo "# is declared" || echo "# is not declared"
a="sd";  echo -n 'a="sd";  '; var_is_declared a && echo "# is declared" || echo "# is not declared"
a=();    echo -n 'a=();    '; var_is_declared a && echo "# is declared" || echo "# is not declared"
a=("");  echo -n 'a=("");  '; var_is_declared a && echo "# is declared" || echo "# is not declared"
unset a; echo -n 'unset a; '; var_is_declared a && echo "# is declared" || echo "# is not declared"
echo ;
:;       echo -n 'a;       '; var_is_unset a && echo "# is unset" || echo "# is not unset"
a=;      echo -n 'a=;      '; var_is_unset a && echo "# is unset" || echo "# is not unset"
a="foo"; echo -n 'a="foo"; '; var_is_unset a && echo "# is unset" || echo "# is not unset"
a=();    echo -n 'a=();    '; var_is_unset a && echo "# is unset" || echo "# is not unset"
a=("");  echo -n 'a=("");  '; var_is_unset a && echo "# is unset" || echo "# is not unset"
unset a; echo -n 'unset a; '; var_is_unset a && echo "# is unset" || echo "# is not unset"
)

স্ক্রিপ্ট ফিরে আসা উচিত

a;       # is not declared
a=;      # is declared
a="foo"; # is declared
a=();    # is declared
a=("");  # is declared
unset a; # is not declared

a;       # is unset
a=;      # is not unset
a="foo"; # is not unset
a=();    # is not unset
a=("");  # is not unset
unset a; # is unset

-1

বাশ ফাংশন যা স্কেলার এবং অ্যারের উভয় প্রকারের জন্য কাজ করে :

সংজ্ঞা

has_declare() { # check if variable is set at all
    local "$@" # inject 'name' argument in local scope
    &>/dev/null declare -p "$name" # return 0 when var is present
}

আবাহন

if has_declare name="vars_name" ; then
   echo "variable present: vars_name=$vars_name"
fi
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.