You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
PSCore: Linux - Clear-Host injects data into function return value #10181
Function Get-SomeData {
Clear-Host
$somedata="somedata"
return $somedata
}
$myData = Get-SomeData
$myData[0] # will clear the screen
$myData[1] # "somedata"
$myData.Count # will be 2
Expected behavior
Function should return a single value ("somedata")
Actual behavior
Function returns an array with the Clear-Host command as the first object
Environment data
Verified in:
Name
Value
PSVersion
6.2.0
PSEdition
Core
GitCommitId
6.2.0
OS
Linux 4.15.0-47-generic #50-Ubuntu SMP Wed Mar 13 10:44:52 UTC 2019
which works by outputting a string with ANSI escape codes:
<esc>[3;J<esc>[H<esc>[2J
They are: clear screen including scrollback, move cursor to top left corner, clear screen. Source.
#8554 and #8603 and #8606 and #8609 are related issues, and it looks like there's some debate about whether it's PowerShell or .Net's responsibility, what the default bahviour should be, and how it should interact with "clearing" remote sessions or newly implemented hosts.
As a Linux-specific workaround, you could write that string (or the output of clear) to the host yourself:
... but that kind of obviates the point of a cross-platform language, doesn't it? :)
I think what's more concerning to me is why Clear-Host is messing with my variable stack. Whatever the subtle differences (clear screen, clear buffer+screen, etc) it definitely shouldn't be returning a value.
When I try that fix on Ubuntu 16, the screen is not cleared?
why Clear-Host is messing with my variable stack. Whatever the subtle differences (clear screen, clear buffer+screen, etc) it definitely shouldn't be returning a value.
All command output or free values anywhere in a PowerShell function become part of the return value of the function (that decision was taken to copy sh/bash/ksh/etc. behaviour). Clear-Host particularly returns a value because it wraps /user/bin/clear a native command which works by returning a value.
clear doesn't clear the screen directly, it prints a string expecting the display terminal to clear itself. If you do something to block that, the screen doesn't clear and you get the string instead. The same thing happens in Bash; at a shell prompt:
clear # screen is cleared
clear 1>/tmp/test # screen is not cleared, reset string written to file
result=`clear` #screen is not cleared, output -> variable
echo $result # screen is cleared.
function test { clear; echo "123"; }
test # screen is cleared and 123 is output
result=`test` # screen is not cleared, no visible output
echo $result | wc -c # result variable has 16 characters, not 3
16
echo $result # screen is cleared, 123 is output
that kind of obviates the point of a cross-platform language, doesn't it? :)
It seems to behaves like the platform it's running on. Whether that's badly or not, depends on what behaviour you want 🤔
I think it should be a bug because script behavior varies between platforms. Clear command issues escapes and PowerShell intercepts this. Perhaps we could re-send by raw interface API.
HumanEquivalentUnit: True, but since PowerShell, unlike Bash, is able to distinguish between to-terminal output and success-stream output, the fix is to write directly to the terminal:
${function:Clear-Host} prints the function definition, and on Unix-like platforms you get:
$host.UI.Write() would work too and is arguably conceptually better, but since /usr/bin/clear is being called, the code is terminal (console)-specific anyway.
Test:
& { Clear-Host; 'hi' } | Should -Be 'hi'
(Note: In PowerShell Core 7.0.0-preview.4 I get a spurious Suggestion [4,General]: The most similar commands are: New-Object, Tee-Object. message the first time Should is run in the session, but this is unrelated and can be ignored).
Taking a step back: By unconditionally delegating to /usr/bin/clear on Unix-like platforms, we've actually already made Clear-Hostterminal-specific, which means that it may malfunction / not do anything meaningful in other types of hosts.
This isn't going to work for non-console hosts [...] and remoting. On those platforms, you still need to use the $RawUI portability APIs. A nice solution would be to actually add a new RawUI.Clear() API and then implement that using Console.Clear() in the console host but that may end up being a bunch of work...
Case in point: If you currently execute Clear-Host in a remoting session connected to a Unix machine, it prints the following message to stderr (and does nothing else).
Michael Klement (@mklement0) I see we have some issues with Clear-Host. but I still don't have the ability to test on Unix-s and can not grab this. (Although we could do RawUI.Clear() step by step).
Reacted by Michael Klement and Rain Sallow (/u/ta11ow)
Activity
tobyscales commentedon Jul 19, 2019
(BTW this works as expected in PSCore - Windows)
HumanEquivalentUnit commentedon Jul 28, 2019
Clear-Hoston Linux calls the native command/usr/bin/clear,which works by outputting a string with ANSI escape codes:
They are: clear screen including scrollback, move cursor to top left corner, clear screen. Source.
#8554 and #8603 and #8606 and #8609 are related issues, and it looks like there's some debate about whether it's PowerShell or .Net's responsibility, what the default bahviour should be, and how it should interact with "clearing" remote sessions or newly implemented hosts.
As a Linux-specific workaround, you could write that string (or the output of
clear) to the host yourself:tobyscales commentedon Jul 31, 2019
Sure, I could also (as I've done) fork the logic:
if ($isLinux) { etc }... but that kind of obviates the point of a cross-platform language, doesn't it? :)
I think what's more concerning to me is why Clear-Host is messing with my variable stack. Whatever the subtle differences (clear screen, clear buffer+screen, etc) it definitely shouldn't be returning a value.
But that seems to be what's happening here.
tobyscales commentedon Jul 31, 2019
Actually the more elegant fix, in case anyone runs across this, is simply:
$null = Clear-HostWhich will clear the call stack so everything behaves as expected. But it's still code behaving badly.
HumanEquivalentUnit commentedon Aug 1, 2019
When I try that fix on Ubuntu 16, the screen is not cleared?
All command output or free values anywhere in a PowerShell function become part of the return value of the function (that decision was taken to copy sh/bash/ksh/etc. behaviour).
Clear-Hostparticularly returns a value because it wraps/user/bin/cleara native command which works by returning a value.cleardoesn't clear the screen directly, it prints a string expecting the display terminal to clear itself. If you do something to block that, the screen doesn't clear and you get the string instead. The same thing happens in Bash; at a shell prompt:It seems to behaves like the platform it's running on. Whether that's badly or not, depends on what behaviour you want 🤔
iSazonov commentedon Oct 2, 2019
I think it should be a bug because script behavior varies between platforms.
Clearcommand issues escapes and PowerShell intercepts this. Perhaps we could re-send by raw interface API./cc Michael Klement (@mklement0)
mklement0 commentedon Oct 2, 2019
I agree, Ilya (@iSazonov).
HumanEquivalentUnit: True, but since PowerShell, unlike Bash, is able to distinguish between to-terminal output and success-stream output, the fix is to write directly to the terminal:
${function:Clear-Host}prints the function definition, and on Unix-like platforms you get:The above writes implicitly to the success output stream, so wrapping it in
[Console]::Write()fixes the problem:$host.UI.Write()would work too and is arguably conceptually better, but since/usr/bin/clearis being called, the code is terminal (console)-specific anyway.Test:
(Note: In PowerShell Core 7.0.0-preview.4 I get a spurious
Suggestion [4,General]: The most similar commands are: New-Object, Tee-Object.message the first timeShouldis run in the session, but this is unrelated and can be ignored).iSazonov commentedon Oct 2, 2019
Michael Klement (@mklement0) Many thanks! I pulled PR with your suggestion.
mklement0 commentedon Oct 2, 2019
Thanks for the quick turnaround, Ilya (@iSazonov).
Taking a step back: By unconditionally delegating to
/usr/bin/clearon Unix-like platforms, we've actually already madeClear-Hostterminal-specific, which means that it may malfunction / not do anything meaningful in other types of hosts.To quote Bruce Payette (@BrucePay) from one of the linked issues, at #8603 (comment):
Case in point: If you currently execute
Clear-Hostin a remoting session connected to a Unix machine, it prints the following message to stderr (and does nothing else).iSazonov commentedon Oct 2, 2019
Michael Klement (@mklement0) I see we have some issues with Clear-Host. but I still don't have the ability to test on Unix-s and can not grab this. (Although we could do
RawUI.Clear()step by step).