Powershell: Out-Host -Paging does not pause on long strings or clean up after itself

Created on 23 Sep 2018  ·  10Comments  ·  Source: PowerShell/PowerShell

Per the comment on #4962, paging was at some point intended to be fixed by 6.1.0 -- this is not the case, as such.

Checking the contents of $function:help indicates that some effort was made for the help system specifically (it utilises less on Linux, and more.com on Windows), but Out-Host -Paging does... nothing, in those cases (long strings of text aren't interrupted to page, etc.)

It does work with lengthy sequences of objects, but even there the paging is... not at all pretty. Unlike how more or less function, it leaves... useless prompt strings in the host display after they've been skipped past, duplicates the prompt after the first full page, and overall doesn't make enough of an effort to distinguish itself from the rest of the output, in my opinion. Image is below; partial host output from a call to gci c:\ -recurse -depth 2 | out-host -paging

image

Out-Host -Paging should mimic the behaviour of more and less. As this unfortunate soul discovered more.com does have cases where it completely breaks non-Latin character encodings (though it is perfectly capable of reading them from a file).

And, arguably, the more function should return as a function that simply maps to Out-Host -Paging

Steps to reproduce

# windows
gci c:\ -recurse -depth 2 | out-host -Paging

Expected behavior

similar behaviour to more.com or less

Actual behavior

    Directory: C:\


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----         7/1/2018  12:33 AM                8336500659725115574
da----        8/16/2016   4:57 PM                adb
d-----        9/16/2018   6:40 PM                AMD
da----         9/9/2016  11:27 AM                Android
d-----        9/24/2015   5:38 PM                EFI
d-----         4/7/2018   6:39 PM                ESD
d-----        3/16/2015   1:35 AM                Intel
d-----         5/3/2018   6:48 PM                Logs
d-----        9/27/2015  11:57 PM                My Backups
d-----         9/8/2018   5:23 AM                PerfLogs
d-r---        9/16/2018   6:39 PM                Program Files
d-r---        9/16/2018   6:39 PM                Program Files (x86)
d-----        3/17/2015   9:12 PM                Python34
d-----         9/4/2017   8:34 PM                Ruby24-x64
d-----         7/6/2018   1:23 PM                test
d-r---        9/16/2018   6:39 PM                Users
d-----       11/29/2016  12:32 AM                VIA_XHCI
d-----        9/16/2018   6:46 PM                Windows
d-----        9/16/2018   6:48 PM                Windows.old
d-----         6/1/2018  12:28 AM                Windows.old(1)
-a----        3/17/2015   5:49 AM        4194304 BIOS.17.03.15.bak
-a----         4/6/2018   6:05 PM          17005 PS5.1help.csv
-a----         4/6/2018   6:04 PM           5535 PSCoreHelp.csv
-a----         4/6/2018   6:22 PM            328 WinPSTopics.txt


    Directory: C:\adb


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        10/9/2015   5:58 PM         944128 adb.exe
-a----        10/9/2015   5:58 PM          96256 AdbWinApi.dll
-a----        10/9/2015   5:58 PM          60928 AdbWinUsbApi.dll
-a----        10/9/2015   5:58 PM         318464 fastboot.exe


    Directory: C:\AMD


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
<SPACE> next page; <CR> next line; Q quit
d-----         2/4/2018  11:12 AM                Packages
<SPACE> next page; <CR> next line; Q quit
d-----       12/12/2017   8:43 PM                PPC
<SPACE> next page; <CR> next line; Q quit
d-----         2/4/2018  11:12 AM                radeon-software-adrenalin-18.2.1-minimalsetup-180201_64bit
<SPACE> next page; <CR> next line; Q quit
d-----       12/12/2017   8:36 PM                Win10-64Bit-Radeon-Software-Adrenalin-Edition-17.12.1-Dec11
<SPACE> next page; <CR> next line; Q quit
d-----        9/16/2018   6:40 PM                WU-CCC2
<SPACE> next page; <CR> next line; Q quit
-a----         2/4/2018   9:20 AM           2647 atikmdag_dce.log
<SPACE> next page; <CR> next line; Q quit

<SPACE> next page; <CR> next line; Q quit

<SPACE> next page; <CR> next line; Q quit
    Directory: C:\AMD\Packages
<SPACE> next page; <CR> next line; Q quit

<SPACE> next page; <CR> next line; Q quit

<SPACE> next page; <CR> next line; Q quit

Lots of added clutter that does not clean up after itself.

Environment data

> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      6.1.0
PSEdition                      Core
GitCommitId                    6.1.0
OS                             Microsoft Windows 10.0.17758
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0
Area-Cmdlets Issue-Discussion

Most helpful comment

Out-Host -paging is really bare bones.. and not always functional. While I realize that the different platforms have different paging tools, to me, this is not an acceptable experience. My PS experience should be as identical as possible between the platforms, and should not depend on using separate OS executables to provide some relatively basic functionality. More on Windows is different than More on Linux is _probably_ different than More on Mac. And of course Less is different and not present on Windows. This means my experience is either very stripped down with Out-host -paging or I have learn/memorize all these different syntaxes and account for them in what I do - _if_ it even works.

All 10 comments

@vexx32 I don't think we're planning to do much if anything with Out-Host -Paging. Why invest in it when the existing pagers already do so much more. On the other hand we should definitely make sure the pagers work well with PowerShell.

The existing pagers don't... really do much more, unless I've missed quite a bit. To my knowledge, most commonly used pagers like this date back decades if not more and have not been updated since.

It would seem far more astute, from my perspective, to expand the (presently laughable) capabilities of Out-Host -Paging to enable both a consistent experience across supported OSes as well as a code base PowerShell actually has control over and can build upon.

@vexx32 Try less --help to see what you can do with it.

Speaking of less, I have my $env:PAGER env var (on Windows) pointing to less (less 394) and somehow the wrapping of man/help is getting messed up:

image

If I execute this Get-Help Get-Process -Full | Out-String -Width 120 | less the output wraps much better (but still off a tiny bit). Do we need an extra Out-String stage in the pipeline of the help when $env:PAGER is set?

And it doesn't come by default on Windows, either, of course.

PS C:\Users\Joel> less --help
less : The term 'less' is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ less --help
+ ~~~~
+ CategoryInfo          : ObjectNotFound: (less:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException

Rather than waste time interfacing and dealing with the nuances of third party programs of god knows how many different ages, versions, and authors that are currently in use, imo, it would be better spent utilising the console from PS itself, as we already can. 🤷‍♂️

@BrucePay

I don't think we're planning to do much if anything with Out-Host -Paging. Why invest in it when the existing pagers already do so much more. On the other hand we should definitely make sure the pagers work well with PowerShell.

~I mainly use Out-Host -Paging when I know I'm sending a lot of output, since it doesn't wait until all output is received. Any chance you know of a way to force less to act like that?~

Also useful for remoting as no other pagers work.

@SeeminglyScience Yeah, that's a good point -- in a remoting situation, all we can really work with there is what PS has to offer. 🙁

@SeeminglyScience

I mainly use Out-Host -Paging when I know I'm sending a lot of output, since it doesn't wait until all output is received.

That was a limitation in how we handled piping to external executables. It should be fixed in PSCore. Are you still seeing it?

less in PowerShell does not create backpressure like Out-Host -Paging. Imagine you have a cmdlet that reads and outputs huge amount of data. Piping it into Out-Host -Paging will make sure the cmdlet will only read as much data as is actually visible on the page, and create backpressure until the user scrolls down. Also, when quitting, the cmdlet's execution will be aborted. This is extremely useful for commands that stream large amounts of expensive-to-compute data (basically, all commands where you would want to use a pager).

Both do not happen with less. Pipe the cmdlet into less, and it will keep reading and outputting more and more data (potentially from an infinite data source!) that gets sent to less and buffered in memory by less. When quitting less nothing actually happens if the cmdlet didn't terminate yet, you need to Ctrl+C it manually.

Proof:
Define this function:

$i = 0
function test() {
  while ($true) {
    $global:i++
    $global:i
  }
}

Now run test | Out-Host -Paging, wait a bit without scrolling, and quit.
Check $i in the terminal. It should be the last number that was on screen, e.g. 32.

Now run test | less, wait a bit without scrolling, and quit. Ctrl+C to terminate the cmdlet (needed).
Check $i again. It will be a huge number like 6574, because the cmdlet kept producing output even though the user did not scroll further.

Out-Host -paging is really bare bones.. and not always functional. While I realize that the different platforms have different paging tools, to me, this is not an acceptable experience. My PS experience should be as identical as possible between the platforms, and should not depend on using separate OS executables to provide some relatively basic functionality. More on Windows is different than More on Linux is _probably_ different than More on Mac. And of course Less is different and not present on Windows. This means my experience is either very stripped down with Out-host -paging or I have learn/memorize all these different syntaxes and account for them in what I do - _if_ it even works.

Was this page helpful?
0 / 5 - 0 ratings