This works when I pipe ImageMagick output straight to chafa, but not when I wrap chafa in a PowerShell function. What changes at the function boundary, and is there a reliable way to keep the data as raw bytes?
Why does piping raw bytes work directly but fail through a function?
Answers
The direct pipe between two native executables can pass standard output to standard input as bytes. Once a PowerShell function sits in the middle, the pipeline is PowerShellโs object pipeline, not a transparent native-process byte pipe. The function does not automatically forward its incoming pipeline data to chafaโs stdin.
So this is not just a matter of adding a parameter to the function. Even if it accepts pipeline input, that does not guarantee the original raw byte stream reaches the native program unchanged. For this use, keep the native commands adjacent, or use another mechanism that explicitly preserves the bytes.
Reply to this answer
There are two separate issues here. The function needs to be written to accept pipeline input, and PowerShellโs function pipeline is not the same thing as native stdin. A parameter block can solve the first part, but it does not turn the function into a raw-byte conduit.
If you only want a reusable wrapper, have it invoke chafa with its arguments, as you already do, but call it without expecting bytes piped into the function to flow through untouched. If the input must remain binary, keep the pipe directly between the executables.
Reply to this answer
For this exact case, the simplest fix is to skip the function in the middle:
magick _.png -negate png:- | chafa.exe --size=70x -f sixel -
The trailing dash tells chafa to read from standard input. In the direct version, the shell connects the two native processes. Calling a PowerShell function instead changes the route, so it is no longer equivalent.
Reply to this answer
If the wrapper is mainly for convenience, consider making it construct or run the whole native command rather than trying to accept binary pipeline input. PowerShell functions are useful for passing and transforming PowerShell objects, but they are not a drop-in replacement for a native pipe when the payload is arbitrary bytes.
Also, @args only deals with the arguments passed to the function. It does not capture the previous commandโs stdout and forward that as stdin.
Reply to this answer
Add your answer
Answers are reviewed before publication.
m0onreceipt:
So adding a parameter marked for pipeline input would not be enough to preserve these bytes?