यह उत्तर आपके लिए नहीं है , यदि आप:
- शायद ही कभी, अगर कभी, बाहरी सीएलआई का उपयोग करने की आवश्यकता होती है (जो आम तौर पर इसके लिए प्रयास करने योग्य है - पावरशेल-देशी कमांड एक साथ बहुत बेहतर खेलते हैं और ऐसी सुविधा की कोई आवश्यकता नहीं है)।
- बश की प्रक्रिया प्रतिस्थापन से परिचित नहीं हैं।
यह उत्तर आपके लिए है , यदि आप:
- अक्सर बाहरी सीएलआई का उपयोग करें (चाहे वह आदत से बाहर हो या (अच्छे) पावरस्ले-देशी विकल्पों की कमी के कारण), विशेषकर स्क्रिप्ट लिखते समय।
- का उपयोग किया जाता है और बश की प्रक्रिया प्रतिस्थापन क्या कर सकता है इसकी सराहना करते हैं।
- अद्यतन : अब जब PowerShell यूनिक्स प्लेटफार्मों पर भी समर्थित है, तो यह सुविधा बढ़ती रुचि की है - GitHub पर यह सुविधा अनुरोध देखें, जो सुझाव देता है कि पावरशेल प्रतिस्थापन की प्रक्रिया के लिए एक विशेषता एंकिन को लागू करता है।
यूनिक्स दुनिया में, बैश / क्ष / ज़श में, एक प्रक्रिया प्रतिस्थापन कमांड आउटपुट का इलाज करता है जैसे कि यह एक अस्थायी फ़ाइल थी जो स्वयं के बाद साफ हो जाती है; जैसे cat <(echo 'hello')
, जहां cat
से उत्पादन में देखता है echo
के रूप में आदेश एक अस्थायी फ़ाइल का रास्ता युक्त आदेश उत्पादन ।
जबकि PowerShell- देशी कमांड्स को इस तरह की सुविधा की कोई वास्तविक आवश्यकता नहीं है, बाहरी सीएलआई के साथ काम करते समय यह आसान हो सकता है ।
पावरशेल में फीचर का अनुकरण करना बोझिल है , लेकिन यह इसके लायक हो सकता है, यदि आप खुद को अक्सर इसकी आवश्यकता पाते हैं।
चित्र एक फ़ंक्शन को नामित cf
करता है जो एक स्क्रिप्ट ब्लॉक को स्वीकार करता है, ब्लॉक को निष्पादित करता है और इसके आउटपुट को एक अस्थायी लिखता है। मांग पर बनाई गई फ़ाइल, और अस्थायी रिटर्न। फ़ाइल का रास्ता ; उदाहरण के लिए:
findstr.exe "Windows" (cf { Get-ChildItem c:\ }) # findstr sees the temp. file's path.
यह एक सरल उदाहरण है जो इस तरह की सुविधा की आवश्यकता को अच्छी तरह से नहीं बताता है । शायद एक अधिक ठोस परिदृश्य psftp.exe
एसएफटीपी ट्रांसफर के लिए उपयोग होता है : इसके बैच (स्वचालित) उपयोग के लिए वांछित कमांड वाले इनपुट फ़ाइल प्रदान करने की आवश्यकता होती है , जबकि इस तरह के कमांड को आसानी से मक्खी पर एक स्ट्रिंग के रूप में बनाया जा सकता है।
ताकि जितना संभव हो सके बाहरी उपयोगिताओं के साथ व्यापक रूप से संगत हो, अस्थायी। फ़ाइल को डिफ़ॉल्ट रूप से किसी BOM (बाइट-ऑर्डर मार्क) के बिना UTF-8 एन्कोडिंग का उपयोग करना चाहिए , हालाँकि आप जरूरत पड़ने पर UTF-8 BOM के साथ अनुरोध कर सकते हैं ।-BOM
दुर्भाग्य से, प्रक्रिया प्रतिस्थापन के स्वचालित सफाई पहलू को सीधे अनुकरण नहीं किया जा सकता है , इसलिए एक स्पष्ट सफाई कॉल की आवश्यकता है ; cf
तर्कों के बिना कॉल करके क्लीनअप किया जाता है :
के लिए इंटरैक्टिव उपयोग करते हैं, आप कर सकते हैं अपने को सफाई कॉल जोड़कर सफाई को स्वचालित prompt
रूप में निम्नानुसार (समारोह prompt
समारोह शीघ्र रिटर्न स्ट्रिंग , लेकिन यह भी परदे के पीछे के प्रदर्शन करने के लिए इस्तेमाल किया जा सकता है हर बार संकेत दिखाई देने पर बैश के लिए इसी तरह की आज्ञा देता है $PROMPT_COMMAND
चर); किसी भी संवादात्मक सत्र में उपलब्धता के लिए, cf
अपने PowerShell प्रोफ़ाइल में निम्न और साथ ही नीचे की परिभाषा जोड़ें :
"function prompt { cf 4>`$null; $((get-item function:prompt).definition) }" |
Invoke-Expression
स्क्रिप्ट में उपयोग के लिए , यह सुनिश्चित करने के लिए कि क्लीनअप किया जाता है, जिस ब्लॉक का उपयोग किया जाता है cf
- संभवतः पूरी स्क्रिप्ट - को try
/ finally
ब्लॉक में लपेटने की आवश्यकता होती है , जिसमें cf
बिना तर्क के सफाई के लिए कहा जाता है:
# Example
try {
# Pass the output from `Get-ChildItem` via a temporary file.
findstr.exe "Windows" (cf { Get-ChildItem c:\ })
# cf() will reuse the existing temp. file for additional invocations.
# Invoking it without parameters will delete the temp. file.
} finally {
cf # Clean up the temp. file.
}
यहां लागू किया गया है : उन्नत कार्य ConvertTo-TempFile
और इसकी रसीला उपनाम cf
:
नोट : New-Module
एक गतिशील मॉड्यूल के माध्यम से फ़ंक्शन को परिभाषित करने के लिए PSv3 + के उपयोग की आवश्यकता होती है, यह सुनिश्चित करता है कि पास किए गए स्क्रिप्ट ब्लॉक के अंदर संदर्भित पैरामीटर और चर के बीच कोई चर संघर्ष नहीं हो सकता है।
$null = New-Module { # Load as dynamic module
# Define a succinct alias.
set-alias cf ConvertTo-TempFile
function ConvertTo-TempFile {
[CmdletBinding(DefaultParameterSetName='Cleanup')]
param(
[Parameter(ParameterSetName='Standard', Mandatory=$true, Position=0)]
[ScriptBlock] $ScriptBlock
, [Parameter(ParameterSetName='Standard', Position=1)]
[string] $LiteralPath
, [Parameter(ParameterSetName='Standard')]
[string] $Extension
, [Parameter(ParameterSetName='Standard')]
[switch] $BOM
)
$prevFilePath = Test-Path variable:__cttfFilePath
if ($PSCmdlet.ParameterSetName -eq 'Cleanup') {
if ($prevFilePath) {
Write-Verbose "Removing temp. file: $__cttfFilePath"
Remove-Item -ErrorAction SilentlyContinue $__cttfFilePath
Remove-Variable -Scope Script __cttfFilePath
} else {
Write-Verbose "Nothing to clean up."
}
} else { # script block specified
if ($Extension -and $Extension -notlike '.*') { $Extension = ".$Extension" }
if ($LiteralPath) {
# Since we'll be using a .NET framework classes directly,
# we must sync .NET's notion of the current dir. with PowerShell's.
[Environment]::CurrentDirectory = $pwd
if ([System.IO.Directory]::Exists($LiteralPath)) {
$script:__cttfFilePath = [IO.Path]::Combine($LiteralPath, [IO.Path]::GetRandomFileName() + $Extension)
Write-Verbose "Creating file with random name in specified folder: '$__cttfFilePath'."
} else { # presumptive path to a *file* specified
if (-not [System.IO.Directory]::Exists((Split-Path $LiteralPath))) {
Throw "Output folder '$(Split-Path $LiteralPath)' must exist."
}
$script:__cttfFilePath = $LiteralPath
Write-Verbose "Using explicitly specified file path: '$__cttfFilePath'."
}
} else { # Create temp. file in the user's temporary folder.
if (-not $prevFilePath) {
if ($Extension) {
$script:__cttfFilePath = [IO.Path]::Combine([IO.Path]::GetTempPath(), [IO.Path]::GetRandomFileName() + $Extension)
} else {
$script:__cttfFilePath = [IO.Path]::GetTempFilename()
}
Write-Verbose "Creating temp. file: $__cttfFilePath"
} else {
Write-Verbose "Reusing temp. file: $__cttfFilePath"
}
}
if (-not $BOM) { # UTF8 file *without* BOM
# Note: Out-File, sadly, doesn't support creating UTF8-encoded files
# *without a BOM*, so we must use the .NET framework.
# [IO.StreamWriter] by default writes UTF-8 files without a BOM.
$sw = New-Object IO.StreamWriter $__cttfFilePath
try {
. $ScriptBlock | Out-String -Stream | % { $sw.WriteLine($_) }
} finally { $sw.Close() }
} else { # UTF8 file *with* BOM
. $ScriptBlock | Out-File -Encoding utf8 $__cttfFilePath
}
return $__cttfFilePath
}
}
}
वैकल्पिक रूप से आउटपुट [फ़ाइल] पथ और / या फ़ाइल नाम एक्सटेंशन निर्दिष्ट करने की क्षमता पर ध्यान दें।