আমি চাই যে আমার চালিত কোনও কমান্ড ব্যর্থ হলে (পাওয়ার মতো set -e
) আমার পাওয়ারশেল স্ক্রিপ্টটি বন্ধ হয়ে যায় । আমি পাওয়ারশেল কমান্ড ( New-Object System.Net.WebClient
) এবং প্রোগ্রাম ( .\setup.exe
) উভয়ই ব্যবহার করছি ।
আমি চাই যে আমার চালিত কোনও কমান্ড ব্যর্থ হলে (পাওয়ার মতো set -e
) আমার পাওয়ারশেল স্ক্রিপ্টটি বন্ধ হয়ে যায় । আমি পাওয়ারশেল কমান্ড ( New-Object System.Net.WebClient
) এবং প্রোগ্রাম ( .\setup.exe
) উভয়ই ব্যবহার করছি ।
উত্তর:
$ErrorActionPreference = "Stop"
আপনাকে সেখানে যাওয়ার অংশটি পেয়ে যাবে (অর্থাত এটি সেমিডলেটগুলির জন্য দুর্দান্ত কাজ করে)।
তবে এক্সইএসগুলির জন্য আপনার প্রতিটি প্রতিবেদনের অনুরোধের $LastExitCode
পরে নিজেকে যাচাই করতে হবে এবং তা ব্যর্থ হয়েছে কিনা তা নির্ধারণ করতে হবে। দুর্ভাগ্যক্রমে আমি ভাবি না যে পাওয়ারশেল এখানে সহায়তা করতে পারে কারণ উইন্ডোজে, এক্সইএসগুলি "সাফল্য" বা "ব্যর্থতা" প্রস্থান কোডটি কীসের উপর নির্ভর করে তা মারাত্মকভাবে সামঞ্জস্য নয়। বেশিরভাগ ইউনিক্স মান অনুসরণ করে 0 সাফল্যের ইঙ্গিত দেয় কিন্তু সব হয় না। পরীক্ষা করে দেখুন এই ব্লগ পোস্টে CheckLastExitCode ফাংশন । আপনি এটি দরকারী মনে হতে পারে।
throw "$exe failed with exit code $LastExitCode"
$ এক্সপি কেবলমাত্র পথ EXE।
$ErrorActionPreference = "Stop"
আপনার স্ক্রিপ্টগুলির শুরুতে আপনার বিবৃতিটি ব্যবহার করে এটি সম্পাদন করতে সক্ষম হওয়া উচিত ।
ডিফল্ট সেটিং $ErrorActionPreference
হল Continue
ত্রুটি ঘটতে পরে, যার কারণে আপনাকে আপনার স্ক্রিপ্টের দেখতে পান বর্তা।
দুঃখের বিষয়, নিউ-রেজি এবং ক্লিয়ার-ডিস্কের মতো বগি সেমিডলেটগুলির কারণে এই উত্তরগুলির কোনওোটাই যথেষ্ট নয়। আমার বোধগম্যতা বজায় রাখতে আমি বর্তমানে কোনও পাওয়ারশেল স্ক্রিপ্টের শীর্ষে নিম্নোক্ত লাইনে স্থির হয়েছি।
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
$PSDefaultParameterValues['*:ErrorAction']='Stop'
এবং তারপরে যে কোনও দেশীয় কল এই চিকিত্সা পায়:
native_call.exe
$native_call_success = $?
if (-not $native_call_success)
{
throw 'error making native call'
}
নেটিভ কল প্যাটার্নটি ধীরে ধীরে আমার পক্ষে যথেষ্ট সাধারণ হয়ে উঠছে যে সম্ভবত এটি আরও সংক্ষিপ্ত করার জন্য আমার বিকল্পগুলির দিকে নজর দেওয়া উচিত। আমি এখনও পাওয়ারশেল নবাগত, তাই পরামর্শগুলি স্বাগত।
পাওয়ারশেল ফাংশনগুলির জন্য এবং এক্সের কলিংয়ের জন্য আপনার কিছুটা ভিন্ন ত্রুটি দরকার এবং আপনার স্ক্রিপ্টের কলারকে অবশ্যই এটি নিশ্চিত হওয়া উচিত যে এটি ব্যর্থ হয়েছে। Exec
Psake লাইব্রেরি থেকে শীর্ষে বিল্ডিং , নীচের কাঠামোযুক্ত একটি স্ক্রিপ্ট সমস্ত ত্রুটিগুলি থামবে, এবং বেশিরভাগ স্ক্রিপ্টগুলির জন্য বেস টেমপ্লেট হিসাবে ব্যবহারযোগ্য।
Set-StrictMode -Version latest
$ErrorActionPreference = "Stop"
# Taken from psake https://github.com/psake/psake
<#
.SYNOPSIS
This is a helper function that runs a scriptblock and checks the PS variable $lastexitcode
to see if an error occcured. If an error is detected then an exception is thrown.
This function allows you to run command-line programs without having to
explicitly check the $lastexitcode variable.
.EXAMPLE
exec { svn info $repository_trunk } "Error executing SVN. Please verify SVN command-line client is installed"
#>
function Exec
{
[CmdletBinding()]
param(
[Parameter(Position=0,Mandatory=1)][scriptblock]$cmd,
[Parameter(Position=1,Mandatory=0)][string]$errorMessage = ("Error executing command {0}" -f $cmd)
)
& $cmd
if ($lastexitcode -ne 0) {
throw ("Exec: " + $errorMessage)
}
}
Try {
# Put all your stuff inside here!
# powershell functions called as normal and try..catch reports errors
New-Object System.Net.WebClient
# call exe's and check their exit code using Exec
Exec { setup.exe }
} Catch {
# tell the caller it has all gone wrong
$host.SetShouldExit(-1)
throw
}
Exec { sqlite3.exe -bail some.db "$SQL" }
, -bail
একটি ত্রুটি যেহেতু এটি একটি Cmdlet প্যারামিটার হিসাবে এটা ব্যাখ্যা চাচ্ছে কারণ? উদ্ধৃতিতে জিনিস মোড়ানো কাজ করে বলে মনে হচ্ছে না। কোন ধারনা?
@ অ্যালেস্টায়ার্ট্রি থেকে উত্তরে সামান্য পরিবর্তন :
function Invoke-Call {
param (
[scriptblock]$ScriptBlock,
[string]$ErrorAction = $ErrorActionPreference
)
& @ScriptBlock
if (($lastexitcode -ne 0) -and $ErrorAction -eq "Stop") {
exit $lastexitcode
}
}
Invoke-Call -ScriptBlock { dotnet build . } -ErrorAction Stop
এখানে মূল পার্থক্যগুলি হ'ল:
Invoke-Command
)-ErrorAction
সেমিডলেটগুলিতে অন্তর্নির্মিত আচরণ থেকে নকল আচরণInvoke-Call { dotnet build $something }
& @ScriptBlock
এবং & $ScriptBlock
একই জিনিস প্রদর্শিত হবে। এই ক্ষেত্রে পার্থক্যটি কী তা গুগল করতে সক্ষম হয়নি
আমি একই জিনিস খুঁজছেন এখানে এসেছেন। $ ত্রুটিঅ্যাকশনপ্রিফারেন্স = "থামান" ততক্ষনে আমার শেলটি মেরে ফেলবে যখন আমি বরং ত্রুটি বার্তাটি দেখি (বিরতি দিন) এটি শেষ হওয়ার আগেই। আমার ব্যাচের সংবেদনশীলতার পিছনে পড়ে:
IF %ERRORLEVEL% NEQ 0 pause & GOTO EOF
আমি দেখতে পেয়েছি যে এটি আমার বিশেষ পিএস 1 লিপির জন্য বেশ একই রকম কাজ করে:
Import-PSSession $Session
If ($? -ne "True") {Pause; Exit}
পুনর্নির্দেশ stderr
করা stdout
অন্য কমান্ড / স্ক্রিপ্টব্লক মোড়ক ছাড়াই কৌতুকটি করতে পারে বলে মনে হচ্ছে যদিও এটি কেন সেভাবে কাজ করে তার কোনও ব্যাখ্যা আমি পাই না ..
# test.ps1
$ErrorActionPreference = "Stop"
aws s3 ls s3://xxx
echo "==> pass"
aws s3 ls s3://xxx 2>&1
echo "shouldn't be here"
এটি প্রত্যাশিত হিসাবে নিম্নলিখিতটি আউটপুট দেবে (কমান্ডটি aws s3 ...
রিটার্ন করবে $LASTEXITCODE = 255
)
PS> .\test.ps1
An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied
==> pass
$ErrorActionPreference = "Stop"
ভালভাবে ভদ্র প্রোগ্রামের জন্য কাজ (যে ফিরতি সাফল্য 0)?