Skip to content

Powershell commands run to completion with a broken pipe to an external program #15329

Closed

Description

@stinos

Steps to reproduce

Run

Get-ChildItem -Recurse -Force | more

then exit more by pressing q.

Expected behavior

The pipe stops after quitting more.

Actual behavior

The pipe keeps on running until all child items listed.

Environment data

PSVersion                      7.1.3
PSEdition                      Core

Description

There are a couple of issues related to unix-like plaforms and pipe handling (#8420 #8421) but the same behavior seems to appears on any platform with any type of external program.

Is this a known/documented issue? I looked around but maybe my search terms are not ok, I couldn't find a related issue.

For example: these keep running the upstream command even after the downstream command closes; (the cmd /c '@echo off' command is just to mimick an external program which consumes the pipe then stops without output before all items are consumed - a real example would be a program like fzf):

ls -Rec -Fo -File | more
ls -Rec -Fo -File | cmd /c '@echo off'

this can be worked around with Select-Object to force a StopUpstreamCommandsException, e.g. this works as expected in that the pipe stops:

ls -Rec -Fo -File | & "C:\Program Files\Git\usr\bin\head.exe" | Select-Object -First 10

however that's only ok because it is known head will by default produce 10 items. That's a problem because it means piping into a command which produces no output will not stop the pipe when that command exits. So this still keeps on running:

ls -Rec -Fo -File | cmd /c '@echo off' | Select-Object -First 1 | Out-Null

One workaround is be to launch the external program with the .net Process API, then use Register-ObjectEvent -EventName 'Exited' and then throw a StopUpstreamCommandsException using a technique like https://stackoverflow.com/a/34800670. But that's non-trivial.

Another simpler one would be to make the external command always produce output no matter what. I hoped pipeline chain operators could do that but due to associativity that doesn't cut it. That is to say, I assume that

ls -Rec -Fo -File | cmd /c '@echo off' || 'TERMINATOR' | Select-Object -First 1 | Out-Null

doesn't stop right away because it comes down to

(ls -Rec -Fo -File | cmd /c '@echo off') || 'TERMINATOR' | Select-Object -First 1 | Out-Null

and not

ls -Rec -Fo -File | (cmd /c '@echo off' || 'TERMINATOR') | Select-Object -First 1 | Out-Null

(which yields a ParserError).

The idea to always have the external command produce output can be done in cmd like

ls -Rec -Fo -File | cmd /c '(@echo off || echo TERMINATOR) && echo TERMINATOR' | Select-Object -First 1 | Out-Null

i.e. no matter if the external program (as said mimicked by @echo off) produces output or not, the echos after it make sure it does. Is there another workaround?

Activity

  1. added
    Needs-TriageThe issue is new and needs to be triaged by a work group.
    on Apr 30, 2021
  2. added
    Issue-BugIssue has been identified as a bug in the product
    and removed
    Needs-TriageThe issue is new and needs to be triaged by a work group.
    on May 3, 2021
  3. daxian-dbw commented on May 3, 2021

    @daxian-dbw
    Member

    This is a known issue that James Truher (@JamesWTruher) recently raised internally, but there may not be an issue tracking it yet, so thanks for opening this issue! A native command processor should detect the exit of an executable and stop the upstream commands properly.

  4. microsoft-github-policy-service commented on Nov 16, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

  5. microsoft-github-policy-service commented on Nov 16, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

  6. microsoft-github-policy-service commented on Nov 16, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has not had any activity in 6 months, if this is a bug please try to reproduce on the latest version of PowerShell and reopen a new issue and reference this issue if this is still a blocker for you.

  7. microsoft-github-policy-service commented on Nov 23, 2023

    @microsoft-github-policy-service
    Contributor

    This issue has been marked as "No Activity" as there has been no activity for 6 months. It has been closed for housekeeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions