শেল লোকাল ভেরিয়েবলের প্রস্থান কোড নির্ধারণ করা


42
#!/bin/bash
function0()
{
 local t1=$(exit 1)
 echo $t1
}

function0

echoখালি মান মুদ্রণ। আমি আশা করেছিলাম:

1

t1ভেরিয়েবল কেন প্রস্থান কমান্ডের ফেরতের মান নির্ধারিত হয় না 1?

উত্তর:


58

local t1=$(exit 1) শেলটিকে বলে:

  • exit 1একটি subhell চালানো ;
  • এর আউটপুট (যেমন পাঠ্যটি এটি স্ট্যান্ডার্ড আউটপুটে আউটপুট করে) কোনও ভেরিয়েবলে t1, স্থানীয়ভাবে ফাংশনে সংরক্ষণ করুন।

এটি t1খালি থাকার মতো এটি স্বাভাবিক ।

( কমান্ড প্রতিস্থাপন$() হিসাবে পরিচিত ।)

প্রস্থান কোডটি সর্বদা নির্ধারিত হয় $?, তাই আপনি এটি করতে পারেন

function0()
{
  (exit 1)
  echo "$?"
}

আপনি খুঁজছেন প্রভাব পেতে। আপনি অবশ্যই $?অন্য পরিবর্তনশীল নির্ধারণ করতে পারেন :

function0()
{
  (exit 1)
  local t1=$?
  echo "$t1"
}

1
আপনি জানেন, আপনি সর্বদা পাইপে ফিরতে পারেন। $ $ (trap 'printf ":: ERRNO: $?"' 0; # যাই হোক যাই হোক না কেন - সেই ফাঁদটি নিশ্চিত করবে লিখিত শেষ স্ট্রিংটি পুরো প্রতিস্থাপনের প্রেক্ষাপটের শেষ প্রত্যাবর্তন
মাইকজারভ

1
@ মাইক্রজার আপনি কি একটি ব্যাকটিক মিস করেছেন? $(trap 'printf "::ERRNO:$?"' 0; # now do whatever however
ডক্টর জে

12

প্রস্থান কোডটি stored এ সংরক্ষণ করা হয়েছিল ? পরিবর্তনশীল। কমান্ড সাবস্টিটিউশন ব্যবহার করে কেবল আউটপুট ক্যাপচার করে, আপনার সাব-শেল তৈরি করতে (...) ব্যবহার করা উচিত :

#!/bin/bash

func() {
  (exit 1)
  local t1=$?
  printf '%d\n' "$t1"
}

func

অ্যাসাইনমেন্টের পয়েন্টটি t1=$?এটি ব্যবহার করা হয়, না? এবং $?অ্যাসাইনমেন্ট বিকল্প দ্বারা আঁটসাঁট পেতে হবে না ? আমার ধারণা আমি এটি জিজ্ঞাসা করছি এটি হওয়া উচিত নয়printf '%d\n' "${t1}"
ড্যানি_ল

@ দানি_ল: ধন্যবাদ, এটি একটি ভুল টাইপ। আপডেট করা হয়েছে।
cuonglm

নোট করুন যে কমান্ড সাবস্টিটিউশনটি ভিন্নভাবে পুনঃনির্দেশ না করা হলে কেবল স্ট্যান্ডার্ড আউট ক্যাপচার করে।
ফায়াত

7

ইন bashএই কাজ:

loc(){  local   "x=$(exit "$1"):$?"
        printf  '$%s:\t%d\n' \
                 x "${x##*:}" \? "$?"
}

এটি কমান্ড মূল্যায়নের ক্রম এবং পরিবর্তনশীল অ্যাসাইনমেন্টের সাথে কাজ করে। localতার নিজস্ব একটি রিটার্ন মান রয়েছে - এবং এটি বর্তমানে নির্বাহকারী কমান্ড, কমান্ড প্রতিস্থাপন নয়। কারণগুলির কারণগুলি ...

x=$(exit 1); echo "$?"

... 1 ফিরে আসতে পারে কারণ সেই কমান্ডে কখনই $xএর মান নির্ধারণের জন্য সাব-শেল রান ব্যতীত আর কোনও রিটার্ন $?আসে না - সুতরাং কমান্ডের বিকল্পগুলি ব্যবহৃত হয় এমন প্রতিটি ক্ষেত্রে যেমন ব্যবহারিকভাবে এটি আঁটসাঁট হয়ে যায় না।

যাই হোক, সঙ্গে localএটা নেই clobbered করুন - যখন প্রসারণও এখনও মূল্যায়িত করা হচ্ছে এবং যা - কিন্তু আপনাকে একেবারে সঠিক সময়ে এটা ধরা যদি আগে local আপনি এখনও এটা ধার্য করতে পারেন - এর রুটিন এটা পরাস্ত করার জন্য একটি সুযোগ আছে।

unset x; loc 130; echo "${x-\$x is unset}"

... কপি করে প্রিন্ট ...

$x: 130
$?: 0
$x is unset

আপনার জানা উচিত যদিও অনেক শেলের মধ্যে আপনি সেইভাবে $?মধ্য-মূল্যায়ন সেট করার উপর নির্ভর করতে পারবেন না । আসলে, এটি সম্ভবত কারণ এই শেলগুলি প্রতিটি সম্ভাব্য মোড়কে পুনরায় মূল্যায়ন করতে পারে না যেমনটি bashহয় - যা আমি যুক্তি দিয়ে বলব যে সম্ভবত bashএর চেয়ে ভাল আচরণ behavior আপনি কি সত্যিই আপনার দোভাষীকে পুনরাবৃত্তভাবে লুপ-মূল্যায়নকারী মানগুলি ব্যবহার করতে চান যেগুলি ব্যবহার করার সুযোগ পাওয়ার আগেই ওভাররাইট করা হবে?

যাইহোক, আপনি এটি করতে পারেন যে কিভাবে।


-1

আপনি কেন কেবল প্রস্থান কোড পাওয়ার চেষ্টা করছেন তার উপর নির্ভর করে আপনি কেবল চালাতে পারেন if some-command; then echo "Success $?"; else echo "Failure $?"; fiযা কমান্ডের আউটপুট দিয়ে কিছুই করে না, এটি কমান্ড রানের প্রস্থান কোডটি মূল্যায়ন করে। আপনি যোগ করতে পারেন or( gre or( around the command and you'll still get the same results. A better example might beযদি গ্রেপ-কিউ 'সামস্ট্রিং' সামুফিল; তবে প্রতিধ্বনিত "" সুমস্ট্রিং প্রস্থান কোডটি পাওয়া গেল $? "; অন্যথায়" কিছু স্রস্টিং প্রস্থান কোডটি find? "; ফাই) খুঁজে পাওয়া যায় নি?

আপনি কোনও ফাংশনের রিটার্ন কোডও পরীক্ষা করতে পারেন যা সুস্পষ্ট return 3বা অন্তর্নিহিত রিটার্ন কোড হতে পারে যা শেষ কমান্ডের ফলস্বরূপ, এক্ষেত্রে আপনার সতর্কতা অবলম্বন করা উচিত যে আপনার echoশেষে নেই ফাংশন, অন্যথায় এটি পূর্ববর্তী প্রস্থান কোডটি মাস্ক করে / পুনরায় সেট করে।

command_last () {
  echo "True is `true`"
  echo "False is `false`"
  false
}
command_last; echo $?
# Outputs:
# True is 0
# False is 1
# 1

echo_last () {
  echo "True is `true`"
  echo "False is `false`"
  false
  # echo'ing literally anything (or nothing) returns true aka exit 0
  echo
}
echo_last; echo $?
# Outputs:
# True is 0
# False is 1
#            # Blank line due to empty echo
# 0

অবশেষে একটি নোংরা কৌশল কারণ আপনি এটি করতে পারবেন না VAR=(SOME_COMMAND)কারণ VAR=()একটি অ্যারে সংজ্ঞা তাই আপনার প্রয়োজন VAR=( $(echo 'Some value') )


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