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


10

আমি স্ক্রিপ্টগুলিতে এরকম নির্মাণগুলি দেখেছি:

if somevar="$(somecommand 2>/dev/null)"; then
...
fi

এটি কোথাও নথিভুক্ত করা হয়? কোনও পরিবর্তনশীলটির রিটার্নের স্থিতি কীভাবে নির্ধারিত হয় এবং এটি কমান্ড প্রতিস্থাপনের সাথে কীভাবে সম্পর্কিত? (উদাহরণস্বরূপ, আমি কি একই ফলাফল পাব if echo "$(somecommand 2>/dev/null)"; then?)

উত্তর:


13

এটি ওপেন গ্রুপ বেস স্পেসিফিকেশনের সাধারণ কমান্ডগুলি বিভাগে 2.9.1 বিভাগে ( পসিক্সের জন্য) নথিযুক্ত । সেখানে পাঠ্যের একটি প্রাচীর রয়েছে; আমি আপনার মনোযোগ শেষ অনুচ্ছেদে নির্দেশ করি:

কোনও কমান্ডের নাম থাকলে, কমান্ড অনুসন্ধান এবং সম্পাদনকে বর্ণিত অনুসারে কার্যকর করা চলতে থাকবে । যদি কোনও কমান্ডের নাম না থাকে তবে কমান্ডটিতে একটি কমান্ড প্রতিস্থাপন থাকে, শেষ কমান্ড প্রতিস্থাপনের প্রস্থান স্থিতি দিয়ে কমান্ডটি সম্পূর্ণ হবে। অন্যথায়, কমান্ডটি শূন্য প্রস্থান স্থিতির সাথে সম্পূর্ণ হবে।

সুতরাং, উদাহরণস্বরূপ,

   Command                                         Exit Status
$ FOO=BAR                                   0 (but see also the note from icarus, below)
$ FOO=$(bar)                                Exit status from "bar"
$ FOO=$(bar) baz                            Exit status from "baz"
$ foo $(bar)                                Exit status from "foo"

বাশও এইভাবে কাজ করে। তবে শেষে "এত সহজ নয়" বিভাগটিও দেখুন।

পিএইচকে , তাঁর প্রশ্নের মধ্যে অ্যাসাইনমেন্টগুলি হ'ল একটি প্রস্থান স্থিতি সহ কমান্ডের মতো হ'ল কমান্ড প্রতিস্থাপনের বিকল্পটি ছাড়া? , পরামর্শ দেয়

... এটি প্রদর্শিত হবে যেন একটি অ্যাসাইনমেন্ট নিজেই একটি কমান্ড হিসাবে গণনা করে ... একটি শূন্য প্রস্থান মূল্য সহ, তবে যা অ্যাসাইনমেন্টের ডান পাশের আগে প্রযোজ্য (যেমন, একটি কমান্ড প্রতিস্থাপন কল ...)

এটি দেখার মতো ভয়ঙ্কর উপায় নয়। একটি সহজ কমান্ড ফেরত অবস্থা নির্ধারণের জন্য একটি অশোধিত স্কীম (এক ধারণকারী না ;, &, |, &&বা ||) হল:

  • আপনার প্রান্তে পৌঁছানো বা কমান্ড শব্দ (সাধারণত কোনও প্রোগ্রামের নাম) না হওয়া পর্যন্ত বাম থেকে ডানদিকে লাইনটি স্ক্যান করুন।
  • আপনি যদি কোনও পরিবর্তনশীল অ্যাসাইনমেন্ট দেখেন তবে লাইনের জন্য ফেরতের স্ট্যাটাসটি 0 হতে পারে।
  • আপনি যদি কোনও কমান্ডের বিকল্প দেখেন - যেমন $(…)- command আদেশ থেকে প্রস্থান স্থিতি নিন।
  • আপনি যদি সত্যিকারের কমান্ডে পৌঁছান (কমান্ডের বিকল্পে নয়), সেই আদেশ থেকে প্রস্থান স্থিতি নিন।
  • লাইনের জন্য ফেরতের স্থিতি হ'ল আপনি শেষ নম্বর number
    কমান্ড বদল আর্গুমেন্ট হিসাবে কমান্ড, যেমন, foo $(bar), গণনা করা হয় না; আপনি থেকে প্রস্থান স্থিতি পেতে foo। ভাষান্তর করার phk এর স্বরলিপি , ব্যবহার এখানে

    temporary_variable  = EXECUTE( "bar" )
    overall_exit_status = EXECUTE( "foo", temporary_variable )

তবে এটি সামান্য ওভারসিম্প্লিফিকেশন। থেকে সামগ্রিক ফেরতের স্থিতি

এ = $ ( সেন্টিমিটার 1 ) বি = $ ( সেমিডি 2 ) সি = $ ( সেমিডি 3 ) ডি = $ ( সেন্টিমিটার 4 ) ই = এমসি 2
থেকে প্রস্থান স্থিতি । নিয়োগ পর যেটা নিয়োগ 0 সামগ্রিক প্রস্থান অবস্থা সেট করেনি।cmd4E=D=

আইক্রাস , পিএইচকে-র প্রশ্নের উত্তরে একটি গুরুত্বপূর্ণ বিষয় উত্থাপন করে: ভেরিয়েবলগুলি কেবল পঠনযোগ্য হিসাবে সেট করা যায়। পসিক্স স্ট্যান্ডার্ডের ২.৯.১ বিভাগের তৃতীয় থেকে শেষ অনুচ্ছেদে বলা হয়েছে,

চলক অ্যাসাইনমেন্টগুলির মধ্যে যদি কোনও চলকটিতে একটি মান নির্ধারণের চেষ্টা করে যার জন্য বর্তমান শেল পরিবেশে পঠনযোগ্য বৈশিষ্ট্য নির্ধারিত হয় (নির্ধারিত ক্ষেত্রে সেই পরিবেশটি নির্ধারিত হয় কিনা), একটি চলক অ্যাসাইনমেন্ট ত্রুটি ঘটবে। দেখুন শেল ত্রুটি ফল এই ত্রুটিগুলি পরিণতি জন্য।

সুতরাং যদি আপনি বলেন

readonly A
C=Garfield A=Felix T=Tigger

রিটার্ন অবস্থা 1. বাংলাদেশে তো ব্যাপার যদি স্ট্রিং Garfield, Felixএবং / অথবা Tigger কমান্ড প্রতিকল্পন (গুলি) দিয়ে প্রতিস্থাপিত হয় - কিন্তু নিচের নোট দেখুন।

বিভাগ 2.8.1 শেল ত্রুটির ফলাফলগুলির মধ্যে আরও একটি গুচ্ছ পাঠ্য এবং একটি সারণী রয়েছে এবং এর সাথে শেষ হয়

সারণীতে প্রদর্শিত সমস্ত ক্ষেত্রে যেখানে একটি ইন্টারেক্টিভ শেলটি প্রস্থান করার প্রয়োজন হয় না, শেলটি ত্রুটি ঘটেছে এমন কমান্ডটির আর কোনও প্রক্রিয়া সম্পাদন করবে না।

বিশদটি কিছু বোঝায়; কিছু না:

  • A=নিয়োগ কখনও কখনও aborts যেমন যে শেষ বাক্য উল্লেখ করতে হয়, কমান্ড লাইন। উপরের উদাহরণে, Cসেট করা আছে Garfield, তবে Tসেট করা নেই (এবং, অবশ্যই, উভয়ই নয়  A)।
  • একইভাবে, executes কিন্তু । কিন্তু, ব্যাশ আমার সংস্করণ (যা 4.1.X এবং 4.3.X অন্তর্ভুক্ত করুন), এটা নেই চালানো । (প্রসঙ্গক্রমে, এটি পিএইচকে এর ব্যাখ্যাটিকে আরও বিভ্রান্ত করে যে অ্যাসাইনমেন্টের প্রস্থান মূল্য নির্ধারনের ডান দিকের আগে প্রযোজ্য))C=$(cmd1) A=$(cmd2) T=$(cmd3)cmd1cmd3
    cmd2

তবে এখানে অবাক করা বিষয়:

আমার বাশ সংস্করণে,

পঠনযোগ্য A
সি = কিছু এ = কিছু টি = কিছু  সেমিডি 0

নেই চালানো। নির্দিষ্টভাবে,cmd0

সি $ = ( cmd কমান্ড 1 ) একটি = $ ( cmd কমান্ড 2 ) টি = $ ( cmd 3 )    cmd 0
কার্যকর এবং না, কিন্তু । (মনে রাখবেন যে কোনও আদেশ না থাকলে এটি তার আচরণের বিপরীত )) এবং এটি পরিবেশের ক্ষেত্রে সেট করে (পাশাপাশি পাশাপাশি ) । আমি ভাবছি এটি ব্যাশ-এ বাগ কিনা whethercmd1cmd3cmd2TCcmd0


এত সহজ নয়:

এই উত্তরের প্রথম অনুচ্ছেদটি "সাধারণ আদেশগুলি" বোঝায়।  স্পেসিফিকেশন বলে,

একটি "সিম্পল কমান্ড" হ'ল alচ্ছিক পরিবর্তনশীল অ্যাসাইনমেন্ট এবং পুনঃনির্দেশগুলির ক্রম, কোনও ক্রম, বিকল্পভাবে শব্দ এবং পুনঃনির্দেশগুলির পরে, একটি নিয়ন্ত্রণ অপারেটর দ্বারা সমাপ্ত।

এগুলি আমার প্রথম উদাহরণ ব্লকের মত বিবৃতিগুলি:

$ FOO=BAR
$ FOO=$(bar)
$ FOO=$(bar) baz
$ foo $(bar)

যার মধ্যে প্রথম তিনটিতে ভেরিয়েবল অ্যাসাইনমেন্ট অন্তর্ভুক্ত রয়েছে এবং এর মধ্যে শেষ তিনটিতে কমান্ডের বিকল্প অন্তর্ভুক্ত রয়েছে।

তবে কিছু পরিবর্তনশীল অ্যাসাইনমেন্ট এত সহজ নয় so  বাশ (1) বলেছেন,

অ্যাসাইনমেন্ট বিবৃতি এছাড়াও আর্গুমেন্ট হিসাবে প্রদর্শিত হতে পারে alias, declare, typeset, export, readonly, এবং localbuiltin কমান্ড ( ঘোষণা কমান্ড)।

এর জন্য export, পসিক্স স্পেসিফিকেশন বলেছে,

স্ট্যাটাস থেকে প্রস্থান করুন

    0
      সমস্ত নাম অপারেশন সফলভাবে রফতানি করা হয়েছিল।
    > 0
      কমপক্ষে একটি নাম রফতানি করা যায়নি, বা -pবিকল্পটি নির্দিষ্ট করা হয়েছে এবং একটি ত্রুটি ঘটেছে।

এবং পসিক্স সমর্থন করে না local, তবে বাশ (1) বলে,

localকোনও ফাংশনের মধ্যে না থাকলে এটি ব্যবহার করা ত্রুটি । localফাংশনটির বাইরে ব্যবহার না করা, একটি অবৈধ নাম সরবরাহ করা হয় না বা নামটি কেবল পঠনযোগ্য ভেরিয়েবলের ক্ষেত্রে প্রত্যাবর্তন স্থিতি 0 থাকে ।

লাইনের মধ্যে পড়া, আমরা দেখতে পাচ্ছি যে ডিক্লেয়ারেশন কমান্ডগুলি পছন্দ করে

export FOO=$(bar)

এবং

local FOO=$(bar)

আরও পছন্দ হয়

foo $(bar)

যতটুকু তারা থেকে প্রস্থান অবস্থা উপেক্ষা bar এবং আপনি মূল কমান্ড উপর ভিত্তি করে একটি প্রস্থান মর্যাদা দিতে ( export, local, অথবা foo)। সুতরাং আমাদের মত অদ্ভুততা আছে

   Command                                           Exit Status
$ FOO=$(bar)                                    Exit status from "bar"
                                                  (unless FOO is readonly)
$ export FOO=$(bar)                             0 (unless FOO is readonly,
                                                  or other error from “export”)
$ local FOO=$(bar)                              0 (unless FOO is readonly,
                                                  statement is not in a function,
                                                  or other error from “local”)

যা আমরা এর সাথে প্রদর্শন করতে পারি

$ export FRIDAY=$(date -d tomorrow)
$ echo "FRIDAY   = $FRIDAY, status = $?"
FRIDAY   = Fri, May 04, 2018  8:58:30 PM, status = 0
$ export SATURDAY=$(date -d "day after tomorrow")
date: invalid date ‘day after tomorrow’
$ echo "SATURDAY = $SATURDAY, status = $?"
SATURDAY = , status = 0

এবং

myfunc() {
    local x=$(echo "Foo"; true);  echo "x = $x -> $?"
    local y=$(echo "Bar"; false); echo "y = $y -> $?"
    echo -n "BUT! "
    local z; z=$(echo "Baz"; false); echo "z = $z -> $?"
}

$ myfunc
x = Foo -> 0
y = Bar -> 0
BUT! z = Baz -> 1

ভাগ্যক্রমে শেলচেক ত্রুটিটি ধরা পড়ে এবং এসসি 2155 উত্থাপন করে , যা এটির পরামর্শ দেয়

export foo="$(mycmd)"

পরিবর্তন করা উচিত

foo=$(mycmd)
export foo

এবং

local foo="$(mycmd)"

পরিবর্তন করা উচিত

local foo
foo=$(mycmd)

1
দুর্দান্ত, আপনাকে ধন্যবাদ! বোনাস পয়েন্টগুলির জন্য, আপনি কি জানেন যে এর localমধ্যে কীভাবে সম্পর্ক রয়েছে? যেমন local foo=$(bar)?
ওয়াইল্ডকার্ড

1
দ্বিতীয় উদাহরণের জন্য (কেবল FOO=$(bar)) এটি লক্ষণীয় যে তাত্ত্বিকভাবে প্রস্থান স্থিতি এবং অ্যাসাইনমেন্ট উভয়ই একটি ভূমিকা পালন করতে পারে, unix.stackexchange.com/a/341013/117599 দেখুন
phk

1
@ উইল্ডকার্ড: আপনি পছন্দ করেছেন বলে আমি আনন্দিত। আমি আবার এটি আপডেট করেছি; আপনি যে সংস্করণটি পড়েছিলেন তার একটি বড় অংশটি ভুল ছিল। যতক্ষণ আপনি এখানে আছেন, আপনি কী ভাবেন? এটি কি ব্যাশের কোনও বাগ, এটি কেবল পঠনযোগ্য হয়ে গেলেও A=foo cmdচলে ? cmdA
জি-ম্যান

1
@ পিএফকে: (১) আকর্ষণীয় তত্ত্ব, তবে আমি নিশ্চিত নই যে এটি কীভাবে অর্থবোধ করে। আমার "আশ্চর্য" শিরোনামের ঠিক আগে উদাহরণটি দেখুন। যদি Aকেবলমাত্র পঠনযোগ্য হয়, কমান্ডটি C=value₁ A=value₂ T=value₃সেট করে Cতবে না T(এবং অবশ্যই Aসেট করা থাকে না) - শেলটি কমান্ড লাইনটি প্রসেস করে, উপেক্ষা করে T=value₃, কারণ A=value₂এটি একটি ত্রুটি। (২) স্ট্যাক ওভারফ্লো প্রশ্নটির লিঙ্কের জন্য ধন্যবাদ - আমি এটিতে মন্তব্য পোস্ট করেছি।
জি-ম্যান বলছেন 'ফিরতি মনিকা'

1
@ উইল্ডকার্ড "বোনাস পয়েন্টগুলির জন্য, আপনি কি জানেন যে এটির মধ্যে স্থানীয় সম্পর্ক কীভাবে?" হ্যাঁ ... local=$(false)প্রস্থান মূল্য আছে 0কারণ (মানুষ পাতা থেকে): It is an error to use local when not within a function. The return status is 0 unless local is used outside a function, an invalid name is supplied, or name is a readonly variable.। প্রতিভাধর যারা এইভাবে ডিজাইন করেছিলেন তাদের পক্ষে এটি বিশ্বের পক্ষে যথেষ্ট ট্রলফেস নয়।
ডেভিড টনহোফার

2

এটি ব্যাশে নথিভুক্ত করা হয়েছে ( LESS=+/'^SIMPLE COMMAND EXPANSION' bash):

প্রসারণের পরে যদি কোনও কমান্ডের নাম থাকে ...। অন্যথায়, কমান্ডটি প্রস্থান করে। ... যদি কমান্ডের বিকল্প না থাকে, কমান্ডটি শূন্যের স্থিতি সহ প্রস্থান করে।

অন্য কথায় (আমার কথা):

প্রসারণের পরে যদি কোনও কমান্ডের নাম না থাকে এবং কোনও কমান্ড বিকল্প প্রয়োগ না করা হয়, কমান্ড লাইনটি শূন্যের স্থিতি সহ প্রস্থান করে।

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