Finding out where Powershell stdout is redirected to (as opposed to cmd.exe)

Viewed 202

I am trying to detect read / write cycles like the Linux program cat does:

$ cat a b c > b
cat: b: input file is output file

On Linux, I can identify files with the stat family of functions to find such a loop. Similarly on Windows, I can compare fields of the result of GetFileInformationByHandle - I need a HANDLE to a file for that though (handles to a pipe do not work).

This is where I am stuck. Neither of the answers in Check if Windows file is redirected to itself and How to check if stdout has been redirected to NUL on Windows (a.k.a. /dev/null on Linux)? are working for me in Powershell.

I found that in cmd.exe (with the variable stdout being a handle obtained from GetStdHandle), GetFileType(stdout) is 1 (FILE_TYPE_DISK, as explained in this answer from the second thread) when redirecting to a file. Here, I can do everything I could do with a file handle and there are no problems.

However in Powershell GetFileType(stdout) is 3 (FILE_TYPE_PIPE). Similarly, APIs like GetFinalPathNameByHandleW return a path when running under cmd.exe but not in PS.

I read that Powershell has cmdlets like Out-File for that, so I thought for a moment that ">" is maybe aliased to "| Out-File ...", but in the documenation it is called an operator, which to me seems like too strong a word for just an alias.

Can anyone explain, why the ">" operator behaves so differently on cmd.exe and Powershell? What can I do to work around that? Is there any way to find out where stdout (aka the success stream) is redirected to in Powershell?


The full (Rust) code (1 function, starting at line 44) can be found here, there is some Rust safety noise around the calls into the Windows APIs though.

0 Answers
Related