이 대답은 당신을 위해 NOT 다음과 같은 경우,
거의 어느 경우 필요 외부 경기 선행 지수를 사용하지 않으려면 (대한 가치 분투가 일반적이다 - - PowerShell을 네이티브 명령은 훨씬 더 함께 플레이와 같은 기능에 대한 필요가 없습니다).
-Bash의 프로세스 대체에 익숙하지 않습니다.
이 답변 은 다음 과 같은 경우에 도움이됩니다.-
특히 스크립트를 작성하는 동안 외부 CLI를 사용합니다 (습관이 없는지 또는 PowerShell 고유의 대안이 없는지에 따라).
-Bash의 프로세스 대체가 할 수있는 일을 이해하고 이해하는 데 사용됩니다.
- 업데이트 : 이제 Unix 플랫폼에서도 PowerShell이 지원 되므로이 기능 에 대한 관심이 높아지고 있습니다. GitHub에서이 기능 요청을 참조하십시오.이는 PowerShell이 대체를 처리하는 것과 유사한 기능을 구현할 것을 제안합니다.
유닉스 세계에서 Bash / Ksh / Zsh에서 프로세스 대체 는 명령 출력을 마치 자체적으로 정리 되는 임시 파일 인 것처럼 처리 합니다. 예를 들어 cat <(echo 'hello')
, 여기서 명령의 출력을 명령 출력을 포함 하는 임시 파일 의 경로 로 cat
봅니다 .echo
PowerShell 기본 명령에는 이러한 기능이 실제로 필요하지 않지만 외부 CLI를 처리 할 때 유용 할 수 있습니다 .
PowerShell에서 기능을 에뮬레이트하는 것은 번거롭지 만 자주 필요한 경우 유용 할 수 있습니다.
cf
스크립트 블록을 받아들이고 블록을 실행하고 출력을 temp에 기록하는 명명 된 함수를 그림으로 만듭니다. 파일은 요청시 생성되며 임시를 반환합니다. 파일의 경로 ; 예 :
findstr.exe "Windows" (cf { Get-ChildItem c:\ }) # findstr sees the temp. file's path.
이것은 그러한 기능 의 필요성 을 잘 설명하지 않는 간단한 예입니다 . 아마도보다 설득력있는 시나리오는 psftp.exe
SFTP 전송을 사용하는 것입니다 . 배치 (자동화)를 사용하려면 원하는 명령이 포함 된 입력 파일 을 제공해야 하지만 이러한 명령은 즉시 문자열로 쉽게 만들 수 있습니다.
가능한 한 외부 유틸리티와 광범위하게 호환되도록 임시. 필요한 경우 파일을 사용 하여 UTF-8 BOM을 요청할 수 있지만 파일은 기본적으로 BOM (바이트 순서 표시) 없이 UTF-8 인코딩 을-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
}
}
}
출력 [file] 경로 및 / 또는 파일 이름 확장자를 선택적으로 지정할 수 있습니다.