问题
This is not a duplicate of the various other questions around this (I reviewed them and this was not answered in the ones that I saw). Those other questions revolve around Out-Host -Paging
and more
(even if they mention less
in the question title).
To focus on this specific point, does anyone know of a PowerShell method of replicating the functionality of less
, but on Microsoft Windows environments? i.e. giving us the ability to scroll down and up through a document (line by line with cursor keys or page by page with the PgUp / PgDn keys) to view help and other files (e.g. so that we can do Get-Help Get-ChildItem -Full | less
).
This would be very useful. I am not after a 3rd party executable less
tool (because that won't be pipeline enabled etc) for Windows (there are many of course). I believe that there is something in PSCX like this, but whenever I try to install that, I see lots of conflicts and I'm not sure to use -AllowClobber
in case it breaks something else. Maybe on that though, if there is a less
in there, has anyone been able to split out that function and use independently of PSCX?
回答1:
Get-Help Get-ChildItem -Full | less
works just fine on Unix-like platforms, using the given platform's less
utility (typically, /usr/bin/less
) - no extra work needed.
I am not after a 3rd party executable
less
tool (because that won't be pipeline enabled etc)
Any external program (utility) that reads from stdin (standard input) and outputs to stdout (standard output) is by definition pipeline-enabled, albeit invariably only with respect to text: data sent to such utilities is converted to text, and data returned from such utilities is interpreted as text.
On Windows, only the - feature-limited - more.com
pager is available by default - see below.
However, it is possible to install less
on Windows:
If you have a Linux distro for the WSL installed, you can simply pipe to
wsl less
; e.g.:Get-Help Get-ChildItem | wsl less
- Caveat: PageUp / PageDown seemingly do not work when invoked from PowerShell, but f (forward) and b (back) provide the same utility.
Otherwise, consider installing the less.exe Windows console application (pick the version inside the most recent folder) that is part of the GnuWin project (the installer requires admin privileges).
- This gives you normal PageUp / PageDown support.
Note: There's another port of less
to Windows, which comes bundled with other utilities; haven't personally tried it: UnxUtils.
Caveats:
less
apparently expects UTF-8 input, irrespective of the active OEM code page, and additionally only displays non-ASCII characters correctly if[console]::OutputEncoding]
is set to UTF-8.Therefore, both
$OutputEncoding
and[console]::OutputEncoding]
must be set to UTF-8 ([Text.Utf8Encoding]::new()
) for the display of non-ASCII characters to work properly. (In PowerShell [Core] v6+,$OutputEncoding
defaults to UTF-8, but[console]::OutputEncoding]
still reflects the system's OEM code page.)See the bottom section for how to make the command
more
/ thehelp
function in PowerShell useless
instead ofmore.com
, via a custommore
function that also ensures use of UTF-8 encoding.
GnuWin
less.exe
version394
(current as of this writing, but published in 2006-01-03) sometimes acts erratically and displays nothing; starting a new session makes the problem go away.
The - less powerful (no pun intended) - Windows counterpart to less
is more
(more.com
), which accepts text via stdin / the pipeline or via a filename arguments.
Remarkably, more.com
only seems to support paging down, with space, and not back up; that is, you can't scroll back - see here.
PowerShell's own Out-Host -Paging
has the same limitation.
Windows PowerShell provides a built-in wrapper function around
more.com
also namedmore
(which means that executing justmore
executes the function), which ensures that the content of specified files is output with the encoding of the active OEM code page, which is whatmore.com
expects.PowerShell [Core] 6+ doesn't provide this wrapper anymore.
In both editions, the built-in help
function, which itself wraps Get-Help
, implicitly pipes the latter's output to more
- invariably in Windows PowerShell, by default in PowerShell 6+ on Windows (on Unix, it defaults to less
.
In PowerShell 6+, you can also define a custom pager by setting the $env:PAGER
variable to the command line you want invoked for paging help
output.
In Windows PowerShell, your only option is to replace / define a custom more
function (which would also work in PowerShell 6+).
In other words: Something like the following gives you interactively paged output by default:
help Get-ChildItem # Effectively the same as: Get-Help Get-ChildItem | more
If you have less
available on Windows and want to use it instead of more
:
Overwrite the built-in / define a more
function as follows (in your $PROFILE
file):
- Use of
less
via WSL:
# Via WSL
function more {
$prevOe, $prevCoe = $OutputEncoding, [console]::OutputEncoding
try {
$OutputEncoding = [console]::OutputEncoding = [Text.Utf8Encoding]::new()
$Input | wsl less
}
finally {
$OutputEncoding, [console]::OutputEncoding = $prevOe, $prevCoe
}
}
# If running PowerShell Core (v6+):
# Force the `help` function to use the custom function.
if ($IsCoreClr) { $env:PAGER = 'more' }
- Use of GnuWin
less.exe
:
# Via GnuWin (assuming the default installation location)
function more {
$prevOe, $prevCoe = $OutputEncoding, [console]::OutputEncoding
try {
$OutputEncoding = [console]::OutputEncoding = [Text.Utf8Encoding]::new()
$Input | & 'C:\Program Files (x86)\GnuWin32\bin\less.exe'
}
finally {
$OutputEncoding, [console]::OutputEncoding = $prevOe, $prevCoe
}
}
# If running PowerShell Core (v6+):
# Force the `help` function to use the custom function.
if ($IsCoreClr) { $env:PAGER = 'more' }
Note: This makes more
only accept pipeline input, but it wouldn't be hard to extend the function to accept filename arguments too.
If the following conditions are met, there is a simpler solution, suggested by David Hatch:
You have GnuWin
less.exe
installed.You don't need support for non-ASCII characters.
You do, but your sessions are already configured to set both
$OutputEncoding
and[console]::OutputEncoding
to UTF-8. ($OutputEncoding
defaults to UTF-8 in PowerShell [Core] v6+, but not[console]::OutputEncoding]
).See this answer for how to switch your PowerShell sessions to use UTF-8 consistently, via
$PROFILE
.See this answer for how to configure Windows 10 system-wide to use code page
65001
== UTF-8, but note that the feature is still in beta as of this writing, and that it has side effects and limitations; notably, it makes Windows PowerShell commands that use the active ANSI code page (Get-Content
/Set-Content
) then default to UTF-8.
Windows PowerShell:
Set-Alias more 'C:\Program Files (x86)\GnuWin32\bin\less.exe'
PowerShell [Core] v6+:
$env:PAGER = 'C:\Program Files (x86)\GnuWin32\bin\less.exe'
来源:https://stackoverflow.com/questions/59240742/powershell-less-tool