PowerShell
PowerShell copied to clipboard
Need a way to detect output goes to a file instead of the console
If a custom format wants to use ANSI escape sequences, it should be possible to skip the escape sequences when the target is a file instead of a tty.
For example, my custom format for MatchInfo
(the output of Select-String
) uses ANSI escape sequences, but if I redirect output, e.g. dir *.txt | Select-String foo > out.txt
, I probably don't want the escape sequences.
We should have a simple way (api, variable, whatever) that makes it easy to control this behavior.
Do you really mean a file or just redirected (not a tty/console). IIRC, there is logic in the native command processor that computes whether the output is redirected or not.
I think it depends,
If tmux
or screen
is using redirection, then you'd still like your escape sequences.
But if I run powershell -file script.ps1 > out.txt
, then that's also simple redirection where you don't want escape sequences.
The bottom line here is that PowerShell should make it easy (if it isn't already) to support these scenarios in custom formatting, or alternatively strip (some limited) ANSI escape sequences automatically.
I've been struggling with this for a little while - I rewrote my ls
alias to output similar to Linux's ls -F --color
, but if I forget to write gci
instead in a pipeline, all sorts of weird things happen.
At first I tried calling GetFileType(GetStdHandle(STD_OUTPUT_HANDLE))
from an Add-Type
block, but this doesn't work. It seems that PowerShell code in a pipeline doesn't change the actual stdout handle and I can't see anything that exposes the redirection to the script.
When calling native code though, it does replace the handles as you'd expect, so I wrote a small C++ program, which seems to be the only way to tell if a stream is redirected or it's part of a pipeline.
Since calling a native program does what you'd expect, I can't imagine it'd be too hard to add something like $MyInvocation.Is<Input|Output|Error>Redirected
.
I actually had an issue with Richard Turner of Windows Terminal team about this. The general idea is request-based mediated execution. I made the point that tools like troff are legacy and pre-date REST approach to API development where a client and server handshake on the medium the messages use.
For those coming here looking for a workaround, I found this Stack Overflow answer helpful: https://superuser.com/a/1706459/560725
$FormatEnumerationLimit=-1
Your Command | Format-Table | Out-File -width 999999 -Encoding utf8 "C:\Temp\result.txt"
e.g., you can even simplify this in some cases:
Get-Content "SomeLogFile.txt" | Select-String "LogPattern" | Out-File -width 999999 -Encoding utf8 "C:\Temp\result.txt"
As someone who doesn't use PowerShell on a daily basis, I really dislike this behavior as compared to how I would use grep and redirection via cat "SomeLogFile.txt" | select-string "LogPattern" > "c:\Temp\result.txt"
. Unix is way more intuitive. If PowerShell is going to take all the time in the world to parse a text file, it might as well be intuitive in how it prints the output when redirecting it.
The general idea here is that this example is a play on the same theme of request-based mediated execution. The format applied should depend on the context.
Super UserI'm trying to get a list of all the directories and files on an external hard drive, with one fully-qualified directory/file path per line. I'm using PowerShell on Windows 10 to achieve this. This ...
See also: https://github.com/dotnet/msbuild/issues/4299#issuecomment-639753092
Still desired.
while i know the issue predates $PSStyle
, doesn't $PSStyle.OutputRendering
solve this?
OutputRendering - Control when output rendering is used
Get-ChildItem | Out-String
Get-ChildItem | Out-File
Both are created without ansi for me with Host
mode.
Your solution does not solve the format length issue. It does solve the problem as initially motivated, but not all use cases for knowing the output target is a file.
Your solution does not solve the format length issue.
I'm not sure i entirely understand the problem, do you have an example?
Out-File, Out-String and redirected >
works and it strips the ansi out.
cat "SomeLogFile.txt" | select-string "LogPattern" > "c:\Temp\result.txt
this works.
example
'A' * 100kb + 'b' | select-string b > foo.tmp
^ does not get truncated..
https://github.com/PowerShell/PowerShell/issues/3452#issuecomment-1640310102
I already gave examples.
This issue has not had any activity in 6 months, if there is no further activity in 7 days, the issue will be closed automatically.
Activity in this case refers only to comments on the issue. If the issue is closed and you are the author, you can re-open the issue using the button below. Please add more information to be considered during retriage. If you are not the author but the issue is impacting you after it has been closed, please submit a new issue with updated details and a link to this issue and the original.