PowerShell icon indicating copy to clipboard operation
PowerShell copied to clipboard

Need a way to detect output goes to a file instead of the console

Open lzybkr opened this issue 7 years ago • 11 comments

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.

lzybkr avatar Mar 29 '17 19:03 lzybkr

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.

BrucePay avatar Mar 29 '17 20:03 BrucePay

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.

lzybkr avatar Mar 29 '17 21:03 lzybkr

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.

parkovski avatar Sep 24 '21 04:09 parkovski

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.

jzabroski avatar Jul 18 '23 01:07 jzabroski

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 User
I'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 ...

jzabroski avatar Jul 18 '23 14:07 jzabroski

See also: https://github.com/dotnet/msbuild/issues/4299#issuecomment-639753092

jzabroski avatar Jul 18 '23 14:07 jzabroski

Still desired.

jzabroski avatar Jan 15 '24 13:01 jzabroski

while i know the issue predates $PSStyle, doesn't $PSStyle.OutputRendering solve this?

OutputRendering - Control when output rendering is used

PSStyle

Host mode

Get-ChildItem | Out-String
Get-ChildItem | Out-File

Both are created without ansi for me with Host mode.

image

trackd avatar Jan 17 '24 02:01 trackd

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.

jzabroski avatar Jan 17 '24 02:01 jzabroski

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.

image

example

'A' * 100kb + 'b' | select-string b > foo.tmp

^ does not get truncated..

trackd avatar Jan 17 '24 02:01 trackd

https://github.com/PowerShell/PowerShell/issues/3452#issuecomment-1640310102

I already gave examples.

jzabroski avatar Jan 17 '24 03:01 jzabroski

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.