如何解决管道流到其他进程
我想下载一个 20GB 的转储,替换字符串并将其通过管道传输到 MysqL.exe,同时它仍在 Powershell 中下载。但是我在传输信息流时遇到了问题。
如果我的文件已经下载,我可以在将文件中的字符串替换为 StdOut 的同时进行流式传输:
Get-Content 'dump.sql' | %{ $_.replace("production_db","staging_db") }
或者,如果我在流式传输并将字符串替换为 StdOut 时也下载文件,我可以这样做:
$url = 'http://MyServer.ext/dump.sql'
& {
$myHttpWebRequest = [System.Net.WebRequest]::Create($url)
$myHttpWebRequest.Headers.Add("Authorization","Basic " + [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("MyUsername:MyPassword")))
try {
$res = $myHttpWebRequest.GetResponse()
}
catch [System.Net.WebException] {
$res = $_.Exception.Response
}
if ([int] $res.StatusCode -ne 200) {
'Error: ' + [int]$res.StatusCode + " " + $res.StatusCode
} else {
$receiveStream = $res.GetResponseStream()
$encode = [System.Text.Encoding]::GetEncoding("utf-8")
$readStream = [System.IO.StreamReader]::new($receiveStream,$encode)
while (-not $readStream.EndOfStream) {
$readStream.ReadLine().replace("production_db","staging_db")
}
$res.Close()
$readStream.Close()
}
}
但在这两种情况下,我都无法将其作为流传输到 MysqL.exe。它接缝整个流首先加载到内存中,然后传递给 MysqL.exe 进程,当我追加时:
| & 'C:\Program Files\MysqL\MysqL Server 5.7\bin\MysqL.exe' -u MyUsername -pMyPassword -h 127.0.0.1
如何通过管道将流传输到 Powershell 中的另一个进程?
解决方法
我们知道 mysql.exe 将接受标准输入,因为我们可以运行 mysql.exe < myfile.sql
并且它运行良好。我找到了 this 关于将文本行发送到流程的标准输入的绝妙答案,它似乎对我有用。我正在使用 CMD shell 进行测试,因为我手头没有 mysql:
# Setup: example commands to feed via stream to process
'echo "hello"
echo "world"
echo "bye"
exit' > 'C:\temp\file.bat'
# create streamreader from file
$readStream = [System.IO.Streamreader]::new('C:\temp\file.bat')
$encode = [System.Text.Encoding]::GetEncoding("utf-8")
对于您,只需更新您的替代品和 exe 名称:
# Create a process for the job
$psi = New-Object System.Diagnostics.ProcessStartInfo;
$psi.FileName = "cmd.exe"; #process file
$psi.UseShellExecute = $false; #start the process from it's own executable file
$psi.RedirectStandardInput = $true; #enable the process to read from standard input
$psi.RedirectStandardOutput = $true #send standard output to object
$p = [System.Diagnostics.Process]::Start($psi);
# Send each line of the file to the process as standard input:
while (-not $readStream.EndOfStream) {
$p.StandardInput.WriteLine(
($readStream.ReadLine().replace("l","L"))
)
}
$readStream.Close()
# Make sure you don't accidentally close mysql before it's done processing.
# For example,add WriteLine('exit') after the While{},then use Wait-Process.
# get the output of the process,should also wait for the process to finish
$p.StandardOutput.ReadToEnd()
$p.Close()
在我的测试中,它正在工作,在读取命令时替换它们,并将它们发送到进程,并显示输出:
Microsoft Windows [Version 10.0.19043.1110]
(c) Microsoft Corporation. All rights reserved.
C:\>echo "heLLo"
"heLLo"
C:\>echo "worLd"
"worLd"
C:\>echo "bye"
"bye"
C:\>exit
我认为您应该能够挂钩 $p.StandardOutput 并随时阅读它,但是当我尝试时它会导致进程挂起?也许只是使用 mysql 日志记录代替。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。