New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Don’t parse the pipeline as text when it is directed from an EXE to another EXE or file. Keep the bytes as-is. #1908
Comments
Maybe add a cmdlet/operator to call native command and get its raw output (as a byte array / stream?), something like this: # Consider ^& operator is an alias for Get-CommandRawOutputStream; this is just an example syntax
$output = ^& curl.exe http://whatever/a.png # $output now is a byte array or stream
$output > C:\Temp\file.png # file.png now is a valid image file
# This should be valid, too:
^& curl.exe http://whatever/a.png > C:\Temp\file.png This opens an opportunity for some additional usage patterns (you can put this raw content into variables, and pipe raw content from native commands to managed cmdlets). |
But maybe we could add a special kind of redirection operator (like $output = curl.exe http://whatever/a.png %>&1
$output > C:\Temp\file.png
# Or even this:
curl.exe http://whatever/a.png %> C:\Temp\file.png # which is just awesome Overall: I don't think that this kind of redirection should be tied to only native commands or some limited list of usage patterns (e.g. |
@ForNeVeR My proposal is that:
|
@be5invis okay, it seems like this proposal also supports all the relevant use cases I can imagine. |
Shouldn't this open up an RFC since this is a breaking change (changes the observed behaviour)? A workaround for this is to provide a cmdlet that stores the content in a temporary file. A working example is |
Great discussion! Thank you all for the feedback. I'd like to share my plans about this work:
function foo
{
param([byte[]]$rawBytes)
} they may archive it with a temp file or some other technique as @GeeLaw pointed out.
We can revisit the last two parts later, but I'd like to set expectations about scope of this issue. |
@vors However the current “>” is identical to |
If PowerShell is ever to introduce a way to get the binary output stream of a binary command (or pipe it into a Cmdlet), through, say, a |
@Shayan-To, you left out the rest of my paragraph, which I believe encapsulates my counter-argument:
Let's elevate this to user experience, and put aside the implementation challenges for the moment... My crude analogy: most GUI systems have a clipboard mechanism for transferring data from one application to another. One approach would be to say only UTF-16 text is supported, and would be captured via a Ctrl+C keystroke. If the source data wasn't really text, then the data would be "transformed" into that format, even if it resulted in a loss/change of information. The end user would get something, but it might not be what they expect. The burden of dealing with that could be put on the user, and (for example) we could expect them to learn that if they want to copy HTML and paste it to an HTML-aware application and preserve the mark-up, they should know to instead know to use Alt+Ctrl+C to do the copy, and so on for each possible data format. That would be roughly equivalent to creating an assortment of new pipe operators in PowerShell. However, another approach would be something similar to what Windows has done with its clipboard: if the sender has a preferred/native non-text format, and the receiver has indicated that it can accept that format, then a direct transfer is done in that format. And, the user can just use Ctrl+C (or the | operator) in all cases, and in most cases will get the expected result. (I'm intentionally leaving out the implementation detail of how the clipboard accomplishes this - it's a user experience example, not an implementation example, and a different implementation would likely be more appropriate for PowerShell.) So, my understanding of this baby-step proposal is:
To be clear: I'm NOT proposing that a full general anything-to-anything system needs to be designed to take this first tiny step (a general solution might not be needed in the end). That could be deferred until if/when something came up in the future, such as the use case you describe. This baby step is just to fix an existing bug, which is that data output from traditional executables is being modified in certain well-defined cases where it doesn't need to be, and that is an unfortunate impediment to PowerShell adoption. Let's make PowerShell less of an annoyance so it can be unstoppable. (Poor kitten! 😉) |
There's some great discussion happening here about |
so i came by this issue, and wondered how it is not possible to send bytes to the input stream of another command.
function Send-Bytes {
param(
[string] $To,
[string] $Arguments
)
begin {
$startInfo = [System.Diagnostics.ProcessStartInfo]::new()
$startInfo.RedirectStandardInput = $true
$startInfo.FileName = $To
$startInfo.Arguments = $Arguments
$process = [System.Diagnostics.Process]::Start($startInfo)
$inputStream = $process.StandardInput.BaseStream
}
process {
$inputStream.WriteByte([byte]$_)
}
end {
$inputStream.Flush()
$inputStream.Close()
$process.WaitForExit()
}
} enables you to do this: unfortunately i wasn't really able to capture the standard output properly, to pipe it back into powershell ( If this would pipe the output back into powershell, you could even chain multiple native commands
|
Hey @SeidChr, workarounds like this do exist, see for example Use-RawPipeline. Unfortunately, I believe that many of the people supporting this issue are not looking for a workaround. Speaking for myself, I can assure you that no workaround would be sufficient for me to consider using PowerShell as my daily driver. Literally the only way it can work for me is if I can pipe byte streams from one application to another with a single pipe operator like, honestly, in any other shell. |
Fixing pwsh piping/redirecting is crucially needed... I cannot use pwsh professionally if i can't rely on basic redirection or piping of data... |
Indeed, it's the one thing stopping many Linux users from pwsh adoption as a primary shell. Has there been any progress on this front, pwsh team? |
@potatoqualitee yeah, my PR is ready for review now (#17857). It is a large change in a sensitive area of the code base, so don't expect a speedy review, but it's comin'. |
Powershell regard output as string.But windows-1252 maps every byte to character,you can try use this encoding. [console]::outputencoding=[console]::inputencoding=[System.Text.Encoding]::GetEncoding(1252)
$result=python zipbomb --mode=quoted_overlap --num-files=250 --compressed-size=21179
[IO.File]::WriteAllText("$pwd\result.zip",$result,[System.Text.Encoding]::GetEncoding(1252)) |
Great news, @SeeminglyScience !! Thank you, looking very forward to it. |
Forgot to mark the PR as resolving this issue! The PR was merged on 04/27, should be in the next preview 🎉 Closing Oh also when it does make it to preview, remember to run |
HECK YES! 🚀 Such great news for the non-Windows communities. Thanks so much |
to anyone interested, this is the commit: personally I will be waiting until the next proper release (not preview) but regardless this is great news - thanks (I guess 7 years late is better than never 😀) |
wooooooooooo this works:
For me though, with this feature enabled, you can't actually redirect stdout to a file, it always seems to go to the console with native commands followup bug filed though #19836 |
Currently PowerShell parses STDOUT as string when piping from an EXE, while in some cases it should be preserved as a byte stream, like this scenario:
or
Affected patterns include:
native | native
,native > file
and (maybe)cat file | native
.The text was updated successfully, but these errors were encountered: