পাওয়ারশেলে ফাংশন রিটার্ন মান


188

আমি একটি পাওয়ারশেল ফাংশন বিকাশ করেছি যা শেয়ারপয়েন্ট টিম সাইটগুলির বিধান যুক্ত অনেকগুলি ক্রিয়া সম্পাদন করে । শেষ পর্যন্ত, আমি চাই ফাংশনটি স্ট্রিং হিসাবে বিভক্ত সাইটের ইউআরএল ফিরিয়ে দেয় যাতে আমার ফাংশন শেষে আমার কাছে নিম্নলিখিত কোডটি রয়েছে:

$rs = $url.ToString();
return $rs;

এই ফাংশনটি কল করে এমন কোডটি দেখে মনে হচ্ছে:

$returnURL = MyFunction -param 1 ...

সুতরাং আমি একটি স্ট্রিং আশা করছি, তবে তা নয় it's পরিবর্তে, এটি System.Management.A Automation.PSMethod টাইপের একটি অবজেক্ট। স্ট্রিং টাইপের পরিবর্তে কেন এটি টাইপটি ফিরছে?


2
আমরা ফাংশন ঘোষণা দেখতে পারেন?
জেডান

1
না, ফাংশন অনুরোধ নয়, আপনি কীভাবে / কোথায় "মাই ফাংশন" ঘোষণা করেছিলেন তা আমাদের জানান। আপনি যখন করবেন: গেট-আইটেম ফাংশন: \ মাই ফাংশন
জেডান


আমি মনে করি এটি ফাংশন / পদ্ধতিগুলির সাথে সম্পর্কিত স্ট্যাক ওভারফ্লো সম্পর্কিত একটি অত্যন্ত পাওয়ারশেল প্রশ্ন। আপনি যদি পাওয়ারশেল স্ক্রিপ্টিং শেখার পরিকল্পনা করছেন তবে আপনার এই পুরো পৃষ্ঠাটি পড়তে হবে এবং এটি ভালভাবে বুঝতে হবে। আপনি যদি না করেন তবে পরে নিজেকে ঘৃণা করবেন।
বার্ডম্যান

উত্তর:


271

পাওয়ারশেলের সত্যিই বেহাল রিটার্ন সিনটিক্স রয়েছে - কমপক্ষে যখন আরও প্রচলিত প্রোগ্রামিং দৃষ্টিকোণ থেকে দেখা হয়। আপনার মাথাটি চারদিকে মুড়িয়ে দেওয়ার জন্য দুটি মূল ধারণা রয়েছে:

  • সমস্ত আউটপুট ক্যাপচার, এবং ফিরে
  • প্রত্যাবর্তন কীওয়ার্ডটি কেবলমাত্র একটি যৌক্তিক প্রস্থান বিন্দু নির্দেশ করে

সুতরাং, নিম্নলিখিত দুটি স্ক্রিপ্ট ব্লক কার্যকরভাবে একই জিনিস কার্যকর করবে:

$a = "Hello, World"
return $a

 

$a = "Hello, World"
$a
return

দ্বিতীয় উদাহরণে একটি ভেরিয়েবল পাইপলাইনে আউটপুট হিসাবে রেখে যায় এবং উল্লিখিত হিসাবে, সমস্ত আউটপুট ফিরে আসে। প্রকৃতপক্ষে, দ্বিতীয় উদাহরণে আপনি পুরোপুরি রিটার্ন বাদ দিতে পারেন এবং আপনি একই আচরণ পাবেন (ফাংশনটি প্রাকৃতিকভাবে সম্পূর্ণ হয়ে ওঠার সাথে সাথে প্রত্যাবর্তনটি বোঝানো হবে)।

আপনার ফাংশন সংজ্ঞা ছাড়া আরও বলতে পারি না আপনি কেন পিএসমেথড অবজেক্ট পাচ্ছেন। আমার ধারণা হ'ল আপনার কাছে সম্ভবত কয়েকটি লাইন রয়েছে যা ধরা পড়ে না এবং আউটপুট পাইপলাইনে স্থাপন করা হচ্ছে।

এটি লক্ষণীয় যে আপনার সম্ভবত সেই সেমিকোলনগুলির প্রয়োজন নেই - যদি না আপনি একটি লাইনে একাধিক অভিব্যক্তি বাসা বাঁধেন।

আপনি টেকনেট সম্পর্কে_আর্টনার পৃষ্ঠায় রিটার্ন শব্দার্থ সম্পর্কে আরও পড়তে পারেন , বা help returnপাওয়ারশেল থেকে নিজেই কমান্ডটি আহ্বান করে।


13
সুতরাং কোন ফাংশন থেকে কোনও স্কেলারের মান ফেরত দেওয়ার কোনও উপায় আছে কি?
চিলেইয়াগো

10
যদি আপনার ফাংশন কোনও হ্যাশটেবল ফেরত দেয়, তবে এটি ফলাফলটিকে এরূপ হিসাবে বিবেচনা করে তবে আপনি যদি অন্য কমান্ডের আউটপুট সহ ফাংশন বডির মধ্যে কিছু "প্রতিধ্বনি" করেন এবং হঠাৎ ফলাফলটি মিশ্রিত হয়।
লুক পুপলেট

5
আপনি যদি ফাংশন ফলাফলের অংশ হিসাবে সেই পাঠ্যটি না write-debug$DebugPreference = "Continue""SilentlyContinue"
ফেরৎ

6
এটি সহায়তা করেছে, তবে এই স্ট্যাকওভারফ্লো . com/ প্রশ্নগুলি / 22663848/… আরও বেশি সহায়তা করেছে। "... | আউট-নাল" এর মাধ্যমে ডাকা ফাংশনে কমান্ড / ফাংশন কলগুলির অনাকাঙ্ক্ষিত ফলাফলগুলি পাইপ করুন এবং তারপরে আপনার পছন্দসই জিনিসটি ফিরিয়ে দিন।
স্ট্রাফ

1
@ লুক্কুপ্লেট echoআমার জন্য বিষয়টি ছিল! ছোট্ট সাইড পয়েন্টটি খুব গুরুত্বপূর্ণ। আমি সমস্ত কিছু অনুসরণ করে একটি হ্যাশটেবল ফিরিয়েছিলাম, কিন্তু তারপরেও প্রত্যাবর্তনের মানটি আমার প্রত্যাশা মতো ছিল না। মুছে ফেলা হয়েছে echoএবং কবজির মতো কাজ করেছে।
অায়ো আমি

53

পাওয়ারশেলের এই অংশটি সম্ভবত সবচেয়ে বোকা দিক। কোনও ফাংশন চলাকালীন যে কোনও বহিরাগত আউটপুট ফলাফলটিকে দূষিত করবে। কখনও কখনও কোনও আউটপুট থাকে না এবং তারপরে কিছু পরিস্থিতিতে আপনার পরিকল্পিত রিটার্ন মান ছাড়াও কিছু অপরিকল্পিত আউটপুট থাকে।

সুতরাং, আমি আসল ফাংশন কল থেকে অ্যাসাইনমেন্টটি সরিয়ে ফেলছি, সুতরাং আউটপুটটি স্ক্রিনে শেষ হবে এবং তারপরে পাছা না দেওয়া পর্যন্ত আমি ডিবাগার উইন্ডোতে ( পাওয়ারশেল আইএসই ব্যবহার করে ) পপ আউট করার পরিকল্পনা করিনি until

এমনকি বাইরের স্কোপে ভেরিয়েবল সংরক্ষণের মতো জিনিসগুলির ফলে আউটপুট হয়, [boolean]$isEnabledযা আপনি বিরক্তিকরভাবে একটি ফলসকে ছড়িয়ে দেবেন যদি আপনি এটি না তৈরি করেন [boolean]$isEnabled = $false

আর একটি ভাল $someCollection.Add("thing")এটি নতুন সংগ্রহের গণনা ছড়িয়ে দেয়।


2
স্পষ্টভাবে সংজ্ঞায়িত একটি মান দিয়ে ভেরিয়েবলটি সঠিকভাবে আরম্ভ করার সর্বোত্তম অনুশীলন না করে কেন আপনি কেবল একটি নাম সংরক্ষণ করবেন?
বিউওলফনোড 42

2
আমি এটি গ্রহণ করেছি আপনার অর্থ এই যে যে স্কোপে ব্যবহৃত প্রতিটি ভেরিয়েবলের জন্য প্রতিটি সুযোগের শুরুতে আপনার পরিবর্তনশীল ঘোষণার একটি ব্লক রয়েছে। আপনার এখনও সি বা অন্য কোনও ভাষায় ব্যবহার করার আগে সমস্ত ভেরিয়েবলগুলি আরম্ভ করা উচিত। এছাড়াও গুরুত্বপূর্ণভাবে [boolean]$aপাওয়ারশেলে করা আসলে ভেরিয়েবল declare এ ঘোষণা করে না। আপনি লাইনটির সাথে সেই লাইনটি অনুসরণ করে এটি নিশ্চিত করতে পারেন $a.gettype()এবং স্ট্রিংয়ের সাথে ডিক্লেয়ার এবং আরম্ভ করার সময় সেই আউটপুটটির সাথে তুলনা করতে পারেন $a = [boolean]$false
বেওলোফনড 42

3
আপনি সম্ভবত সঠিক, দুর্ঘটনাক্রমে লেখা রোধ করতে আমি আরও স্পষ্ট নকশাকে পছন্দ করব।
লুক পুপলেট 21 '45

4
প্রোগ্রামারের দৃষ্টিকোণ থেকে আসা, যদিও আমি পিএস-এন00 বি, আমি পিএস সিনট্যাক্সের অনেক বিরক্তিকর দিকগুলির মধ্যে সবচেয়ে খারাপ এটি খুঁজে পেয়েছি বলে আমি নিশ্চিত নই। পৃথিবীতে কেউ কীভাবে "x> y" এর চেয়ে "x -gt y" লিখতে পছন্দনীয় বলে মনে করেন?!? অবশ্যই অন্তত অন্তর্নির্মিত অপারেটররা আরও বেশি মানব-বান্ধব বাক্য গঠন ব্যবহার করতে পারত?
দাগ

5
@TheDag কারণ এটি প্রথম শেল, প্রোগ্রামিং ভাষার দ্বিতীয়; >এবং <ইতিমধ্যে ফাইলগুলিতে / থেকে I / O স্ট্রিম পুনঃনির্দেশের জন্য ব্যবহৃত হয়। >=বলা একটি ফাইল stdout লিখুন =
টেসেল্ল্যাটিংহেকলার

38

পাওয়ারশেল 5 দিয়ে আমাদের এখন ক্লাস তৈরি করার দক্ষতা রয়েছে। আপনার ফাংশনটিকে একটি শ্রেণিতে রূপান্তর করুন, এবং প্রত্যাবর্তনটি কেবল তার পূর্ববর্তী জিনিসটিকে কেবল ফিরে আসবে। এখানে একটি বাস্তব সহজ উদাহরণ।

class test_class {
    [int]return_what() {
        Write-Output "Hello, World!"
        return 808979
    }
}
$tc = New-Object -TypeName test_class
$tc.return_what()

এটি যদি কোনও ফাংশন হয় তবে প্রত্যাশিত আউটপুট হবে

Hello World
808979

তবে শ্রেণি হিসাবে একমাত্র জিনিসটি প্রত্যাবর্তিত হয় 808979 A


6
বিঃদ্রঃ. এটি staticপদ্ধতিগুলিও সমর্থন করে। বাক্য [test_class]::return_what()
গঠনতে

1
"এটি যদি কোনও ফাংশন হয় তবে প্রত্যাশিত আউটপুটটি হ্যালো ওয়ার্ল্ড \ n808979" হত - আমি মনে করি এটি সঠিক নয়? আউটপুট মান সর্বদা কেবল সর্বশেষ বিবৃতিটির মান, আপনার ক্ষেত্রে return 808979, কার্যকরী বা না।
amn

1
আপনাকে ধন্যবাদ! আপনি খুব সঠিক উদাহরণটি কেবল তখনই ফিরে আসবে যদি এটি ফাংশনের মধ্যে আউটপুট তৈরি করে। যা আমাকে বিরক্ত করে। কখনও কখনও আপনার ফাংশন আউটপুট উত্পন্ন করতে পারে এবং সেই আউটপুট প্লাস আপনি রিটার্ন স্টেটমেন্টে যোগ করেন এমন কোনও মান ফিরে আসে। আপনার জানা ক্লাসগুলি কেবল ঘোষিত বা অকার্যকর টাইপটিই ফিরিয়ে দেবে। যদি আপনি তার পরিবর্তে ফাংশন ব্যবহার করেন তবে একটি সহজ পদ্ধতি হ'ল ফাংশনটিকে একটি ভেরিয়েবলের জন্য বরাদ্দ করা এবং যদি ফেরতের মানের চেয়ে বেশি ফেরত দেওয়া হয় তবে একটি অ্যারে হয় এবং ফেরতের মান অ্যারের শেষ আইটেম হবে।
ডস্মোমাকডোগ

1
আচ্ছা, কমান্ড থেকে আপনি কী আশা করবেন Write-Output? এটি "কনসোল" আউটপুট নয় যা এখানে উল্লেখ করা হয়েছে, এটি ফাংশন / সেমিডলেট এর আউটপুট। আপনি কনসোলে কাপড় ডাম্প করতে চান আছে Write-Verbose, Write-Hostএবং Write-Errorফাংশন, প্রমুখ। মূলত, কনসোল আউটপুট পদ্ধতির চেয়ে শব্দার্থকগুলির Write-Outputকাছাকাছি return। এটি অপব্যবহার করবেন না, Write-Verboseভার্বোসটির জন্য ব্যবহার করুন , এটাই তার জন্য।
amn

1
@ এমএন আমি খুব সচেতন এটি কনসোল নয়। কোনও ক্লাস বনাম কোনও ক্রিয়াকলাপের মধ্যে অপ্রত্যাশিত আউটপুট নিয়ে যেভাবে রিটার্ন আসে তার উপায়টি দেখানোর এটি ছিল এক দ্রুত উপায়। কোনও ফাংশনে সমস্ত আউটপুট + আপনি যে মানটি ফিরিয়ে দেন তা সমস্তই ফিরে যায়। কেবলমাত্র কোনও শ্রেণীর ফেরতের ক্ষেত্রে নির্দিষ্ট মানটি প্যাকটি পাস হয়। এগুলি নিজের জন্য চালানোর চেষ্টা করুন।
দাসমোকডোগ

30

একটি কর্মক্ষেত্র হিসাবে আমি অ্যারেতে শেষ অবজেক্টটি ফিরে আসছি যা আপনি ফাংশন থেকে ফিরে পেয়েছেন ... এটি দুর্দান্ত সমাধান নয়, তবে এটি কিছুই না থেকে ভাল:

someFunction {
   $a = "hello"
   "Function is running"
   return $a
}

$b = someFunction
$b = $b[($b.count - 1)]  # Or
$b = $b[-1]              # Simpler

সব মিলিয়ে একই জিনিস লেখার আরও একতরঙ্গিক উপায় হতে পারে:

$b = (someFunction $someParameter $andAnotherOne)[-1]

7
$b = $b[-1]সর্বশেষ উপাদান বা অ্যারে পাওয়ার সহজ উপায় হতে পারে, তবে এমনকি সহজটি হ'ল আউটপুট মানগুলি যা আপনি চান না তা নয়।
ডানকান

@ ডানকান এবং যদি আমি ফাংশনটিতে স্টাফ আউটপুট করতে চাই, তবে একই সাথে আমিও একটি ফেরতের মান চাই?
উতকান গেজার

@ থো অ্যাপেলসিন আপনি যদি বোঝাতে চান যে আপনি টার্মিনালে স্টাফ লিখতে চান তবে write-hostসরাসরি এটির আউটপুট ব্যবহার করুন ।
ডানকান

7

আমি ফিরে আসার উন্মাদনা এড়াতে একক রেজাল্ট সদস্যের সাথে একটি সাধারণ হ্যাশটেবল অবজেক্টের চারপাশে পাস করি কারণ আমি কনসোলে আউটপুটও করতে চাই। এটি রেফারেন্স দ্বারা পাস মাধ্যমে কাজ করে।

function sample-loop($returnObj) {
  for($i = 0; $i -lt 10; $i++) {
    Write-Host "loop counter: $i"
    $returnObj.result++
  }
}

function main-sample() {
  $countObj = @{ result = 0 }
  sample-loop -returnObj $countObj
  Write-Host "_____________"
  Write-Host "Total = " ($countObj.result)
}

main-sample

আপনি আমার গিটহাব প্রকল্পের আনপ্যাকটিউনসগুলিতে বাস্তব উদাহরণ ব্যবহার দেখতে পাচ্ছেন


4

কোডটি না দেখে বলা শক্ত। নিশ্চিত হয়ে নিন যে আপনার ফাংশনটি একের বেশি বস্তুতে ফিরে না এসেছে এবং আপনি অন্য কলগুলি থেকে তৈরি কোনও ফলাফল ক্যাপচার করেছেন। আপনি কি জন্য পাবেন:

@($returnURL).count

যাইহোক, দুটি পরামর্শ:

স্ট্রিং এ অবজেক্টটি কাস্ট করুন:

...
return [string]$rs

বা কেবল এটি ডাবল উদ্ধৃতিতে উপরের মতো সমান তবে টাইপ করার জন্য সংক্ষিপ্ত:

...
return "$rs"

1
অথবা এমনকি ন্যায়সঙ্গত "$rs"- returnকেবলমাত্র ফাংশন থেকে প্রারম্ভিক সময়ে ফিরে আসার প্রয়োজন। রিটার্নটি ছাড়াই আরও ভাল পাওয়ারশেল আইডিয়াম।
ডেভিড ক্লার্ক

4

এই পরিস্থিতিতে এই ফাংশন ফলাফলের লুকের বিবরণ ঠিক মনে হয়। আমি কেবল মূল কারণটি বুঝতে চাই এবং পাওয়ারশেল পণ্য দলটি আচরণ সম্পর্কে কিছু করবে। এটি বেশ সাধারণ বলে মনে হচ্ছে এবং এটি আমার খুব বেশি ডিবাগিংয়ের জন্য ব্যয় করেছে।

এই সমস্যাটি সন্ধান করতে আমি ফাংশন কল থেকে মানটি ফিরে আসার পরিবর্তে বৈশ্বিক চলকগুলি ব্যবহার করছি using

গ্লোবাল ভেরিয়েবলের ব্যবহার সম্পর্কে এখানে আরও একটি প্রশ্ন রয়েছে: গ্লোবাল ভেরিয়েবলের নামটি একটি ফাংশনটিতে কার্যকর একটি চলক যেখানে একটি ফাংশন থেকে বৈশ্বিক পাওয়ারশেল ভেরিয়েবল সেট করা


3

নিম্নলিখিত হিসাবে সহজ হিসাবে 4 হিসাবে উত্তর। আপনি যখন স্ট্রিংয়ের জন্য অ্যাড এক্সপ্রেশনগুলি প্রতিস্থাপন করেন এটি প্রথম স্ট্রিংটি দেয়।

Function StartingMain {
  $a = 1 + 3
  $b = 2 + 5
  $c = 3 + 7
  Return $a
}

Function StartingEnd($b) {
  Write-Host $b
}

StartingEnd(StartingMain)

এটি একটি অ্যারের জন্যও করা যেতে পারে। নীচের উদাহরণটি "পাঠ্য 2" ফিরিয়ে দেবে

Function StartingMain {
  $a = ,@("Text 1","Text 2","Text 3")
  Return $a
}

Function StartingEnd($b) {
  Write-Host $b[1]
}

StartingEnd(StartingMain)

নোট করুন যে আপনাকে নিজেই ফাংশনের নীচে ফাংশনটি কল করতে হবে। অন্যথায়, এটি প্রথমবার চালিত হলে এটি একটি ত্রুটি ফিরিয়ে দেবে যা এটি "স্টার্টিংমাইন" কী তা জানে না।


2

বিদ্যমান উত্তরগুলি সঠিক, তবে কখনও কখনও আপনি প্রকৃতপক্ষে কোনও Write-Outputবা একটি দিয়ে স্পষ্টভাবে কিছু ফিরিয়ে দিচ্ছেন না return, তবুও ফাংশন ফলাফলের মধ্যে কিছু রহস্যের মান রয়েছে। এটি কোনও বিল্টিন ফাংশনের মতো আউটপুট হতে পারেNew-Item

PS C:\temp> function ContrivedFolderMakerFunction {
>>    $folderName = [DateTime]::Now.ToFileTime()
>>    $folderPath = Join-Path -Path . -ChildPath $folderName
>>    New-Item -Path $folderPath -ItemType Directory
>>    return $true
>> }
PS C:\temp> $result = ContrivedFolderMakerFunction
PS C:\temp> $result


    Directory: C:\temp


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----         2/9/2020   4:32 PM                132257575335253136
True

ডিরেক্টরি তৈরির সমস্ত অতিরিক্ত শব্দটি আউটপুটে সংগ্রহ এবং নির্গত হচ্ছে। এটিকে প্রশমিত করার সহজ উপায়টি হল স্টেটমেন্টের | Out-Nullশেষে যুক্ত করা New-Item, অথবা আপনি ফলাফলটি একটি ভেরিয়েবলের কাছে বরাদ্দ করতে পারেন এবং কেবল সেই ভেরিয়েবলটি ব্যবহার না করেই করতে পারেন। এটি দেখতে এই রকম ...

PS C:\temp> function ContrivedFolderMakerFunction {
>>    $folderName = [DateTime]::Now.ToFileTime()
>>    $folderPath = Join-Path -Path . -ChildPath $folderName
>>    New-Item -Path $folderPath -ItemType Directory | Out-Null
>>    # -or-
>>    $throwaway = New-Item -Path $folderPath -ItemType Directory 
>>    return $true
>> }
PS C:\temp> $result = ContrivedFolderMakerFunction
PS C:\temp> $result
True

New-Itemসম্ভবত এর মধ্যে আরও বিখ্যাত, তবে অন্যদের মধ্যে পদ্ধতিটির StringBuilder.Append*()পাশাপাশি সমস্ত পদ্ধতি অন্তর্ভুক্ত রয়েছে SqlDataAdapter.Fill()


0

বিকল্প হিসাবে returnআমি পরামর্শ দিতে হবে Write-Output

Write-Output পাইপলাইন থেকে ইনপুট নিতে এবং এটি পাইপলাইনটি নীচে ফরোয়ার্ড করতে পারে বা এটি শেষ কমান্ড হলে কনসোলে মুদ্রণ করতে পারে।

তবে Write-Outputস্ক্রিপ্টটি যেমন হয় তেমনভাবে শেষ করে returnনা, যা লুপে আউটপুট ব্যবহার করা, ফরোয়ার্ড করা উচিত an

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