প্রারম্ভিক প্রক্রিয়াটির সাথে স্ট্যান্ডার্ড আউট এবং ত্রুটি ক্যাপচার করা হচ্ছে


112

পাওয়ারশেলের Start-Processকমান্ডে সম্পত্তি StandardErrorএবং StandardOutputবৈশিষ্ট্য অ্যাক্সেস করার সময় কি কোনও ত্রুটি রয়েছে ?

আমি যদি নিম্নলিখিতটি চালিত করি তবে আমি কোনও আউটপুট পাই না:

$process = Start-Process -FilePath ping -ArgumentList localhost -NoNewWindow -PassThru -Wait
$process.StandardOutput
$process.StandardError

তবে যদি আমি কোনও ফাইলে আউটপুট পুনর্নির্দেশ করি তবে আমি প্রত্যাশিত ফলাফল পেয়ে যাব:

$process = Start-Process -FilePath ping -ArgumentList localhost -NoNewWindow -PassThru -Wait -RedirectStandardOutput stdout.txt -RedirectStandardError stderr.txt

5
এই নির্দিষ্ট ক্ষেত্রে আপনার কি সত্যিই প্রারম্ভিক প্রক্রিয়া দরকার? ... $process= ping localhost # প্রক্রিয়া ভেরিয়েবলের আউটপুট সংরক্ষণ করে।
mjsr

1
সত্য। আমি রিটার্ন এবং তর্কগুলি পরিচালনা করার জন্য একটি ক্লিনার উপায় খুঁজছিলাম। আপনার দেখানো স্ক্রিপ্টটি লিখে শেষ করেছি।
জিজব্রুনো

উত্তর:


128

Start-Processকোনও কারণে ডিজাইন করা হয়েছিল এভাবে । ফাইল না পাঠিয়ে এটি পাওয়ার জন্য এখানে একটি উপায়:

$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = "ping.exe"
$pinfo.RedirectStandardError = $true
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$pinfo.Arguments = "localhost"
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$p.WaitForExit()
$stdout = $p.StandardOutput.ReadToEnd()
$stderr = $p.StandardError.ReadToEnd()
Write-Host "stdout: $stdout"
Write-Host "stderr: $stderr"
Write-Host "exit code: " + $p.ExitCode

7
আমি আপনার উত্তর গ্রহণ করছি। আমি আশা করি তারা এমন বৈশিষ্ট্য তৈরি না করত যা ব্যবহার করা হয় না, এটি খুব বিভ্রান্তিকর।
jzbruno

6
আপনার যদি এইভাবে কোনও প্রক্রিয়া চালাতে সমস্যা হয় তবে এখানে গৃহীত উত্তর দেখুন stackoverflow.com/questions/11531068/… , যা ওয়েটফরেক্সট এবং স্ট্যান্ডার্ডআউটপুট-এ সামান্য পরিবর্তন করেছে
রিডটওএন্ড

3
আপনি যখন -verb রানআউট ব্যবহার করেন তখন এটি -NoNewWindow বা পুনঃনির্দেশ বিকল্পগুলির অনুমতি দেয় না
ম্যাভারিক

15
StdErr এবং StdOut উভয়টি সমকালীনভাবে শেষ পর্যন্ত পড়ার কারণে এই কোডটি কিছু শর্তে অচল হয়ে যাবে। msdn.microsoft.com/en-us/library/…
কোডপোক

8
@ কোডপোক - এটি এর চেয়ে খানিকটা খারাপ - যেহেতু এটি ওয়েটফরএক্সিট প্রথমে কল করে, যদিও এটি কেবল তাদের মধ্যে একটিকে পুনঃনির্দেশিত করে, স্ট্রিম বাফারটি পূরণ হয়ে গেলে এটি অচল হয়ে যেতে পারে (যেহেতু প্রক্রিয়া না হওয়া পর্যন্ত এটি থেকে এটি পড়ার চেষ্টা করে না) বেরিয়ে এসেছেন)
জেমস ম্যানিং

20

প্রশ্নের প্রদত্ত কোডে, আমি মনে করি যে দীক্ষা ভেরিয়েবলের এক্সিটকোড সম্পত্তিটি পড়া কাজ করা উচিত।

$process = Start-Process -FilePath ping -ArgumentList localhost -NoNewWindow -PassThru -Wait
$process.ExitCode

মনে রাখবেন (যেমন আপনার উদাহরণ হিসাবে) আপনাকে -PassThruএবং -Waitপরামিতিগুলি যুক্ত করতে হবে (এটি আমাকে কিছুক্ষণের জন্য ধরা দিয়েছে)।


যুক্তি তালিকায় যদি কোনও ভেরিয়েবল থাকে তবে কী হবে? এটি প্রসারিত বলে মনে হয় না।
ওও

1
আপনি যুক্তিতে তালিকার তালিকাটি রাখবেন। কাজ করবে? ... $ প্রক্রিয়া = শুরু-প্রক্রিয়া -ফিলিপথ পিং -আর্গগমেন্টলিস্ট "-t লোকালহোস্ট -n 1" -ননিউ উইন্ডো -পাসথ্রু -উইট
জে জোনেস

পাওয়ারশেল উইন্ডোতে আউটপুটটি প্রদর্শন করার পাশাপাশি একটি লগ ফাইলে লগ ইন করবেন কীভাবে? এটা কি সম্ভব?
মুরালি ধর দর্শন

এর -NoNewWindowসাথে ব্যবহার করতে পারবেন না-Verb runAs
ড্রাগাস

11

আমারও এই সমস্যাটি ছিল এবং একাধিক কমান্ড চালানোর প্রয়োজন হলে জিনিসগুলি পরিষ্কার করার জন্য একটি ফাংশন তৈরি করতে অ্যান্ডির কোড ব্যবহার করে শেষ করেছি ended

এটি স্ট্যাডার, স্টডআউট এবং প্রস্থান কোডগুলি অবজেক্ট হিসাবে ফিরে আসবে। একটি বিষয় লক্ষণীয়: ফাংশনটি .\পথে গ্রহণ করবে না ; সম্পূর্ণ পাথ ব্যবহার করা আবশ্যক।

Function Execute-Command ($commandTitle, $commandPath, $commandArguments)
{
    $pinfo = New-Object System.Diagnostics.ProcessStartInfo
    $pinfo.FileName = $commandPath
    $pinfo.RedirectStandardError = $true
    $pinfo.RedirectStandardOutput = $true
    $pinfo.UseShellExecute = $false
    $pinfo.Arguments = $commandArguments
    $p = New-Object System.Diagnostics.Process
    $p.StartInfo = $pinfo
    $p.Start() | Out-Null
    $p.WaitForExit()
    [pscustomobject]@{
        commandTitle = $commandTitle
        stdout = $p.StandardOutput.ReadToEnd()
        stderr = $p.StandardError.ReadToEnd()
        ExitCode = $p.ExitCode
    }
}

এটি কীভাবে ব্যবহার করবেন তা এখানে:

$DisableACMonitorTimeOut = Execute-Command -commandTitle "Disable Monitor Timeout" -commandPath "C:\Windows\System32\powercfg.exe" -commandArguments " -x monitor-timeout-ac 0"

ভাল ধারণা, তবে মনে হচ্ছে সিনট্যাক্সটি আমার পক্ষে কাজ করছে না। প্যারামিটার তালিকায় প্যারাম ([টাইপ] gu আর্গুমেন্টনাম) সিনট্যাক্স ব্যবহার করা উচিত নয়? আপনি এই ফাংশন একটি উদাহরণ কল যোগ করতে পারেন?
লকস্মিথ

"একটি বিষয় লক্ষণীয়: সম্পর্কিত: ফাংশনটি গ্রহণ করবে না Regarding সম্পর্কিত; পুরো পথগুলি অবশ্যই ব্যবহার করা উচিত Regarding" সম্পর্কিত: আপনি ব্যবহার করতে পারেন:> $ pinfo.FileName = সমাধান - পথ $ কমান্ডপথ
লুপুজ

9

গুরুত্বপূর্ণ:

এলপিজি দ্বারা প্রদত্ত ফাংশনটি আমরা ব্যবহার করছি ।

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

Function Execute-Command ($commandTitle, $commandPath, $commandArguments)
{
  Try {
    $pinfo = New-Object System.Diagnostics.ProcessStartInfo
    $pinfo.FileName = $commandPath
    $pinfo.RedirectStandardError = $true
    $pinfo.RedirectStandardOutput = $true
    $pinfo.UseShellExecute = $false
    $pinfo.Arguments = $commandArguments
    $p = New-Object System.Diagnostics.Process
    $p.StartInfo = $pinfo
    $p.Start() | Out-Null
    [pscustomobject]@{
        commandTitle = $commandTitle
        stdout = $p.StandardOutput.ReadToEnd()
        stderr = $p.StandardError.ReadToEnd()
        ExitCode = $p.ExitCode
    }
    $p.WaitForExit()
  }
  Catch {
     exit
  }
}

এই বিষয়ে আরও তথ্য এমএসডিএন- তে পাওয়া যাবে :

যদি পিতামহী প্রসেস পি। স্ট্যান্ডার্ডএররের আগে p.WaitforExit কল করে তবে একটি অচলাবস্থার পরিণতি ঘটতে পারে e রিডটওএন্ড এবং শিশু প্রক্রিয়া পুনঃনির্দেশিত স্ট্রিমটি পূরণ করার জন্য পর্যাপ্ত পাঠ্য লেখায়। সন্তানের প্রক্রিয়াটি প্রস্থান করার জন্য পিতামাতার প্রক্রিয়া অনির্দিষ্টকালের জন্য অপেক্ষা করবে। সন্তানের প্রক্রিয়াটি পুরো স্ট্যান্ডার্ডএরর স্ট্রিম থেকে পিতামাতার জন্য অনির্দিষ্টকালের জন্য অপেক্ষা করবে would


3
এই কোডটি এখনও রিডটোএন্ড () তে সমকালীন কলের কারণে অচল অবস্থায় রয়েছে, যা আপনার এমএসডিএন-এর লিঙ্কটিও বর্ণনা করেছে।
বার্গমিস্টার

1
এটি এখন আমার সমস্যার সমাধান করেছে বলে মনে হচ্ছে। আমাকে অবশ্যই স্বীকার করতে হবে যে এটি কেন স্থির হয়েছিল তা আমি পুরোপুরি বুঝতে পারি না তবে মনে হয় যে খালি স্টাডার প্রক্রিয়াটি শেষ করতে অবরুদ্ধ করেছে। আশ্চর্যের বিষয়, যেহেতু এটি দীর্ঘ সময়ের জন্য কাজ করেছিল তবে হঠাৎ ক্রিসমাসের আগে এটি ব্যর্থ হতে শুরু করে, যার ফলে প্রচুর জাভা-প্রক্রিয়া স্তব্ধ হয়ে যায়।
রেললেম

8

অ্যান্ডি আরিস্মেন্দি এবং এলপিজির কাছ থেকে পাওয়া উদাহরণগুলির সাথে আমার সত্যিই সমস্যা হয়েছিল । আপনার সর্বদা ব্যবহার করা উচিত:

$stdout = $p.StandardOutput.ReadToEnd()

ফোন করার আগে

$p.WaitForExit()

একটি সম্পূর্ণ উদাহরণ হ'ল:

$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = "ping.exe"
$pinfo.RedirectStandardError = $true
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$pinfo.Arguments = "localhost"
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$stdout = $p.StandardOutput.ReadToEnd()
$stderr = $p.StandardError.ReadToEnd()
$p.WaitForExit()
Write-Host "stdout: $stdout"
Write-Host "stderr: $stderr"
Write-Host "exit code: " + $p.ExitCode

আপনি কোথায় পড়েছেন যে "আপনার সর্বদা ব্যবহার করা উচিত:। পি.স্যান্ডার্ডআউটপুট e পি.ওয়েটফরেক্সট () এর আগে পড়ুন?" অবসন্ন হওয়া বাফারে যদি আউটপুট থাকে তবে পরবর্তী সময়ে আরও আউটপুট অনুসরণ করা হয়, যদি মৃত্যুদন্ড কার্যকর করার রেখাটি ওয়েটফরেক্সেটে থাকে এবং প্রক্রিয়াটি শেষ না হয় তবে এটি মিস হবে (এবং পরবর্তীকালে আরও স্ট্যাডার বা স্টাডআউট আউটপুট দেয়) ....
সিজেবিএস

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

@ সিজেবিএস: "কেবল বাফারটি শেষ পর্যন্ত পড়া হয়েছে বলে এর অর্থ এই নয় যে প্রক্রিয়াটি শেষ হয়েছে" - এর অর্থ এই নয়। আসলে, এ কারণেই এটি অচল হয়ে যেতে পারে। "শেষ পর্যন্ত" পড়ার অর্থ এই নয় যে " এখন যা আছে তা পড়ুন "। এর অর্থ পড়া শুরু করা এবং প্রবাহ বন্ধ না হওয়া পর্যন্ত থামবে না, যা প্রক্রিয়াটি সমাপ্ত হওয়ার সমান ating
পিটার ডুনিহো

0

এখানে আমার ফাংশনটির সংস্করণটি মানক সিস্টেম ফিরে আসছে D ডায়াগনস্টিক্স 3 নতুন 3 টি বৈশিষ্ট্য সহ প্রসেস করুন

Function Execute-Command ($commandTitle, $commandPath, $commandArguments)
{
    Try {
        $pinfo = New-Object System.Diagnostics.ProcessStartInfo
        $pinfo.FileName = $commandPath
        $pinfo.RedirectStandardError = $true
        $pinfo.RedirectStandardOutput = $true
        $pinfo.UseShellExecute = $false
        $pinfo.WindowStyle = 'Hidden'
        $pinfo.CreateNoWindow = $True
        $pinfo.Arguments = $commandArguments
        $p = New-Object System.Diagnostics.Process
        $p.StartInfo = $pinfo
        $p.Start() | Out-Null
        $stdout = $p.StandardOutput.ReadToEnd()
        $stderr = $p.StandardError.ReadToEnd()
        $p.WaitForExit()
        $p | Add-Member "commandTitle" $commandTitle
        $p | Add-Member "stdout" $stdout
        $p | Add-Member "stderr" $stderr
    }
    Catch {
    }
    $p
}

0

অন্য পাওয়ারশেল প্রক্রিয়া থেকে আউটপুট পাওয়ার জন্য এখানে ক্লডগি উপায় রয়েছে:

start-process -wait -nonewwindow powershell 'ps | Export-Clixml out.xml'; import-clixml out.xml
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.