কেন || বা && শর্তাধীন কাজ?


12

এটি শেল (ব্যাশ, ড্যাশ) প্রম্পটে কাজ করে:

[ -z "" ] && echo A || echo B
A

যাইহোক, আমি একটি পসিক্স শেল স্ক্রিপ্ট লেখার চেষ্টা করছি , এটি এর শুরু হয়:

#!/bin/sh

[ "${#}" -eq 1 ] || echo "Invalid number of arguments, expected one."; exit 1

readonly raw_input_string=${1}

[ -z "${raw_input_string}" ] && echo "The given argument is empty."; exit 1

এবং আমি জানি না কেন, কিন্তু আমি বার্তা পাবেন না :

প্রদত্ত যুক্তিটি খালি।

আমি যদি স্ক্রিপ্টটিকে এভাবে কল করি:

./test_empty_argument ""

কেন এমন?


5
দেখুন যদি কোনও ভেরিয়েবল খালি থাকে বা কেবলমাত্র ফাঁকা স্থান থাকে তবে আমি কীভাবে পরীক্ষা করতে পারি? পরীক্ষার উপায়গুলির জন্য যদি কোনও ভেরিয়েবলটি খালি, আনসেট না করা থাকে বা কেবল ফাঁকা থাকে। এই প্রশ্নের ইস্যুটির সাথে কিছু করার নেই।
ইলক্কাচু

1
কেবল ব্যবহার করুনif [ X”” = X”$var” ] ; then echo isempty ; fi
ব্যবহারকারীর 2497

3
@ user2497 গত 20 বছরে প্রকাশিত কোনও শেলের মধ্যে এটি ব্যবহার করার কোনও কারণ নেই। এটি পুরানো, বগি শাঁসের জন্য কার্যকর ar
চিপনার

@ চেপনার সুতরাং এটি কোন বৈধ সমাধান নয়? অন্য কিছু ব্যবহার করা আবশ্যক?
ব্যবহারকারী 2497

6
[ "" = "$var" ]ভাল কাজ করবে; একটি উদ্ধৃত খালি স্ট্রিংয়ের যুক্তির তালিকা থেকে সরানো হবে না [। তবে [ -z "$var" ] এটিও প্রয়োজনীয় নয়, কারণ এটি ঠিক কাজ করে।
চিপনার

উত্তর:


37

আপনার লাইন নোট করুন

[ "${#}" -eq 1 ] || echo "Invalid number of arguments, expected one."; exit 1

এই হিসাবে একই

[ "${#}" -eq 1 ] || echo "Invalid number of arguments, expected one."
exit 1

(একটি অব্যক্ত ;, বেশিরভাগ ক্ষেত্রেই, একটি নতুন লাইনের চরিত্র দ্বারা প্রতিস্থাপন করা যেতে পারে)

এর অর্থ exit 1হ'ল স্ক্রিপ্টে কতটি যুক্তি দেওয়া হয়েছিল তা নির্বিশেষে বয়ানটি সর্বদা কার্যকর করা হয়। এর পরিবর্তে এর অর্থ হ'ল বার্তাটি The given argument is empty.কখনই মুদ্রণের সুযোগ পাবে না।

একটি পরীক্ষা "শর্ট সার্কিট সিনট্যাক্স", দলের বিবৃতি ব্যবহার করে পরে একটি একক বিবৃতি চেয়ে বেশি চালানো { ...; }। বিকল্পটি হ'ল সঠিক ifবিবৃতি (যা আইএমএইচও, কোনও স্ক্রিপ্টে পরিষ্কার দেখায়) ব্যবহার করা হয়:

if [ "$#" -ne 1 ]; then
    echo 'Invalid number of arguments, expected one.' >&2
    exit 1
fi

আপনার দ্বিতীয় পরীক্ষাতেও একই সমস্যা রয়েছে।


সংক্রান্ত

[ -z "" ] && echo A || echo B

এটি প্রদত্ত উদাহরণের জন্য কাজ করবে তবে জেনেরিক

some-test && command1 || command2

হিসাবে একই হবে না

if some-test; then
    command1
else
    command2
fi

পরিবর্তে, এটি আরও পছন্দ

if ! { some-test && command1; }; then
    command2
fi

অথবা

if some-test && command1; then
    :
else
    command2
fi

অর্থাৎ, যদি পরীক্ষা বা প্রথম কমান্ড ব্যর্থ হয়, দ্বিতীয় কমান্ড কার্যকর করে, যার অর্থ এটি তিনটি জড়িত বিবৃতি কার্যকর করার সম্ভাবনা রাখে ।


18

এই:

[ "${#}" -eq 1 ] || echo "Invalid number of arguments, expected one."; exit 1

এটি না:

[ "${#}" -eq 1 ] || { echo "Invalid number of arguments, expected one."; exit 1; }

তবে পরিবর্তে হ'ল:

{ [ "${#}" -eq 1 ] || echo "Invalid number of arguments, expected one."; } 
exit 1

আপনার স্ক্রিপ্টটি কতটা আর্গুমেন্ট এতে করে তা নির্বিশেষে উপস্থিত রয়েছে is


8

এটিকে আরও পঠনযোগ্য করার একটি উপায় হ'ল dieফাংশন (à লা perl) এর মতো সংজ্ঞা দেওয়া:

die() {
  printf >&2 '%s\n' "$@"
  exit 1
}

# then:

[ "$#" -eq 1 ] || die "Expected one argument, got $#"

[ -n "$1" ] || die "Empty argument not supported"

রঙ, উপসর্গ, লাইন নম্বর এর মতো আপনি আরও বেশি ঘণ্টা এবং হুইসেল যুক্ত করতে পারেন ... প্রয়োজনে।


অনুশীলনে, আপনি কি কখনও dieএকাধিক যুক্তি দিয়ে আপনার ফাংশনটি কল করেন ? (যদি তাই হয়, আপনি একটি উদাহরণ দিতে পারেন?) আমি প্রায় একটি অভিন্ন dieফাংশন ব্যবহার করি , তবে "$*"পরিবর্তে ব্যবহার করি , যা আপনি চান তা আরও বেশি হতে পারে?
jrw32982

3
এর মান "$@"হ'ল এটি আক্ষরিক নিউলাইনগুলি যুক্ত করার প্রয়োজন ছাড়াই বহু-লাইন বার্তাগুলিকে মঞ্জুরি দেয়।
চার্লস ডাফি

1
@ jrw32982, "$*"ফাঁকা জায়গাগুলিতে আরগগুলিতে যোগদানের অর্থ এটিও পরিবর্তিত হয়েছে $IFSএমনগুলি সহ সমস্ত প্রসঙ্গে কাজ করার জন্য আপনাকে এসপিসিতে সেট করতে হবে $IFS। বিকল্পভাবে ksh/ এর সাথে zsh, আপনি ব্যবহার করতে print -r -- "$@"বা echo -E - "$@"ইন করতে পারেন zsh
স্টাফেন চেজেলাস

@ চার্লসডুফি হ্যাঁ, তবে আমি এটি কখনও-die টাইপ ফাংশনের প্রসঙ্গে দেখিনি । আমি যা জিজ্ঞাসা করছি তা হল: বাস্তবে, আপনি কি কখনও কাউকে die "unable to blah:" "some error"2-লাইনের ত্রুটি বার্তা পাওয়ার উদ্দেশ্যে লিখতে দেখেছেন ?
jrw32982 13: 24 তে মনিকা

@ স্টাফেনচাজেলাস ভাল পয়েন্ট। সুতরাং (আমার গঠনে) এটি হওয়া উচিত die() { IFS=" "; printf >&2 "%s\n" "$*"; exit 1; }। আপনি কি কখনও ব্যক্তিগতভাবে এই জাতীয় dieফাংশনটি printfএকাধিক তর্ক যুক্ত করে একটি বহু-লাইন ত্রুটি বার্তা উত্পন্ন করতে ব্যবহার করেছেন? অথবা আপনি কেবল কখনও dieকোনও একক তর্ককে পাস করেন যাতে এটি কেবলমাত্র তার আউটপুটে একটি নতুন লাইন যুক্ত করে?
jrw32982

-1

আমি প্রায়শই এটি খালি স্ট্রিংয়ের পরীক্ষারূপে দেখেছি:

if [ "x$foo" = "x" ]; then ...

"=" - হওয়া উচিত ছিল।
wef

3
সেই অনুশীলনটি আক্ষরিক অর্থে 1970 এর দশকের। কোন কারণ সবটা উদ্ধৃত ব্যবহার করা হয় এবং এখন লুপ্তপ্রায় কার্যকারিতা যেমন সঠিক, তাই যতদিন কোন শেল যে 1992 POSIX SH মান সঙ্গে সঙ্গতিশীল (সঙ্গে এটি ব্যবহার করতে হয় -a, -o, (এবং )derectives বলতে যেমন testএকটি একক আবাহন একাধিক অপারেশন একত্রিত এড়ানো হয়; pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html এ ওবি চিহ্নিতকারীগুলি দেখুন )।
চার্লস ডাফি

নন-লিনাক্স ইউনিটগুলি মূল 'শ' দিয়ে ভালভাবে 90 এর দশকে প্রেরণ করা হয়েছে - সম্ভবত এখনও আছে। আমার কাজের সময়ে, আমাকে পোর্টেবল ইনস্টল স্ক্রিপ্ট লিখতে হয়েছিল এবং আমি এই নির্মাণটি ব্যবহার করেছি। আমি কেবল ইনস্টল স্ক্রিপ্টগুলি দেখেছি যা এনভিডিয়া লিনাক্সের জন্য পাঠায় এবং তারা এখনও এই নির্মাণ ব্যবহার করে।
ডব্লিউইএফ

এনভিডিয়া এটি ব্যবহার করতে পারে, তবে এটি বলার অপেক্ষা রাখে না যে এটি করার কোনও প্রযুক্তিগত ন্যায়সঙ্গততা তাদের রয়েছে; বাণিজ্যিকভাবে ইউনিক্সে কার্গো-কাল্ট বিকাশ দুঃখজনকভাবে প্রচলিত। এমনকি হেরলুম বোর্নেরও বাগের প্রশ্ন নেই - সুতরাং সানোস কোডবেস (এটি নন-পসিক্স বহন করার সর্বশেষ বাণিজ্যিক /bin/shইউএনআইএক্স এবং হেরলুম বোর্নের তাত্ক্ষণিক পূর্বসূরীর) ছিল না।
চার্লস ডাফি

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