Skip to content

Direct Clear-Host output to terminal #10681

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 3, 2019

Conversation

iSazonov
Copy link
Collaborator

@iSazonov iSazonov commented Oct 2, 2019

PR Summary

Fix #10181

Clear-Host on Unix calls clear command which issues escapes. Before the change we write them to PowerShell output stream and it could be unwantedly intercepted. After the change we write the escapes directly to console as suggested by @mklement0 .

Added test is formal and we need manual check on Linux and MacOs too.

PR Context

PR Checklist

@iSazonov iSazonov added the CL-General Indicates that a PR should be marked as a general cmdlet change in the Change Log label Oct 2, 2019
@iSazonov iSazonov added this to the 7.0.0-preview.5 milestone Oct 2, 2019
@iSazonov iSazonov requested a review from SteveL-MSFT October 2, 2019 13:35
@iSazonov iSazonov self-assigned this Oct 2, 2019
@@ -4078,7 +4078,9 @@ internal static string GetClearHostFunctionText()
{
// Porting note: non-Windows platforms use `clear`
return @"
& (Get-Command -CommandType Application clear | Select-Object -First 1).Definition
[Console]::Write((
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use Write-Host here instead? There may be cases where there isn't a console?

Copy link
Contributor

@mklement0 mklement0 Oct 2, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SteveL-MSFT: In principle, $host.UI.Write() (or Write-Host) is better than [Console]::Write(), but note that we're calling a terminal-specific utility anyway - see also: #10181 (comment)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@iSazonov can you validate if this works remotely?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SteveL-MSFT: No, it doesn't (see linked comment), but it also didn't work before. However, if we're willing to assume an xterm terminal (which sounds like a safe bet), we can fix it as follows before calling clear: if (-not $env:TERM) { $env:TERM='xterm' } - probably better to reset the variable afterwards.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, we can defer the remote scenario since it doesn't work today (and I think there's a issue on that already). We can take this with the current change to address the specific problem of the VT codes emitted to the pipeline.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@SteveL-MSFT: Couldn't find an issue relating to remoting specifically.

As it turns out, my suggested $env:TERM='xterm' workaround for remoting only works with $host.UI.Write() (Write-Host -NoNewline), not with [console]::Write(), because the escape sequences must be sent to the caller's terminal.

In light of that - if you don't want to incorporate the full workaround yet - it's better to switch to $host.UI.Write().

For the record, here's the complete workaround (from my personal notes):


To fix the remoting problem, $env:TERM can be set to xterm temporarily, under the assumption that pretty much all terminals are Xterm-compatible these days - and that it is the caller that uses such a terminal, because the escape sequences must be printed to the caller's terminal:

  function Clear-Host {
    if ($noTerm = -not $env:TERM) { $env:TERM = 'xterm' }
    $host.UI.Write((
      & (Get-Command -CommandType Application clear | Select-Object -First 1).Definition
    ))
    if ($noTerm) { $env:TERM = $null }
  }

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the suggestion to switch to $host.UI.Write(). Not so sure about the assumption that terminals are xterm compatible. The issue I was thinking about is #8606 where remoting was discussed but wasn't the focus.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will look $host.UI.Write() today. I hope we could implement this step-by-step (first for local host. then remote one that would be more tricky)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the link, @SteveL-MSFT, but resolving #8608 will not address the remoting problem; while there is a single comment - #8606 (comment) - that touches on the need to support non-console hosts, a separate issue should really be opened for that.

As for assuming xterm: Anecdotally, I'd say it's a pretty safe bet, but the better solution would be to extend the $PSSenderInfo object to include the caller's $env:TERM value, if any, and have Clear-Host consult that.

Copy link
Member

@SteveL-MSFT SteveL-MSFT left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok with the changes scoped to the specific problem being fixed. We can defer the other issues as they are existing issues.

@iSazonov iSazonov merged commit 950e4ba into PowerShell:master Oct 3, 2019
@iSazonov iSazonov deleted the clear-host-linux branch October 3, 2019 03:51
@ghost
Copy link

ghost commented Oct 23, 2019

🎉v7.0.0-preview.5 has been released which incorporates this pull request.:tada:

Handy links:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CL-General Indicates that a PR should be marked as a general cmdlet change in the Change Log
Projects
None yet
Development

Successfully merging this pull request may close these issues.

PSCore: Linux - Clear-Host injects data into function return value
3 participants