Powershell: Invoke-History doesn't execute programs such as Vim correctly

Created on 13 Apr 2020  路  5Comments  路  Source: PowerShell/PowerShell

Programs such as vi / vim rely on being able to control the terminal buffer directly, which works fine with direct invocation.

However, on re-execution of a call to such a program via Invoke-History / r / ihy, PowerShell unexpectedly inserts itself as an intermediary, which makes the program malfunction.

Note: It looks like an attempt was made to fix this before: see #614

Steps to reproduce

# On macOS or Linux, for instance.

# Invoke vi directly (exit by typing ':q', then Enter):
PS> vi /etc/profile

# Now re-invoke the same command via Invoke-History  (via built-in alias `r`):
PS> r

Expected behavior

The editor should open again.

Actual behavior

The following error message prints:

Invoke-History: Vim: Warning: Output is not to a terminal

vi still runs, but cannot show its UI (again, type ':q', then Enter to exit).

Environment data

PowerShell Core 7.1.0-preview.1

Also affects Windows PowerShell.

Issue-Enhancement Up-for-Grabs WG-Engine

All 5 comments

Out of curiosity does the same thing happen if you use, say, invoke-command -scriptblock {vi /etc/profile} just thinking it probably happens in a bunch of places and it may be fixable in some but not others.

Invoke-History needs to check if:

  1. It's the last item in the pipeline
  2. this.CommandRuntime.OutputPipe.DownstreamCmdlet is Out-Default

If those are true, it should add Out-Default to it's nested PowerShell instance. If not, it should continue as normal.

It may also need to check ErrorOutputPipe, and merge the two streams with Command.MergeMyResults.

Thanks, @SeeminglyScience.

@jhoneill, it works fine with Invoke-Command; however, you can provoke the symptom with
vi /etc/profile | Tee-Object -ov v (which doesn't make sense to do; exit with ^C).

P.S.: While this fix is pending, https://stackoverflow.com/a/61192256/45375 offers a workaround.

you can provoke the symptom with
vi /etc/profile | Tee-Object -ov v (which doesn't make sense to do; exit with ^C).

You probably know this @mklement0, but just to clarify this one is purposeful. If the native command isn't the last thing in the pipeline then it needs to redirect output so that it can be saved.

Thanks, @SeeminglyScience, understood. The purpose of the example command was to demonstrate that Invoke-History - inappropriately, and unlike Invoke-Command - behaves as if its output were redirected (pipeline, file) even when it isn't (and you've fortunately already provided detailed pointers to a fix).

Was this page helpful?
0 / 5 - 0 ratings