镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Unix: ./build.sh with no WorkingDirectory runs a same-named file next to the host app, and a bare id/git runs (or fails on) a file in the caller's current directory before PATH #153

Open

Description

@matt-edmondson

What's wrong

ResolveFileName (RunCommand/RunCommand.cs:345-356) hands two kinds of name to Process.Start unchanged:

  • a relative path with a directory part when WorkingDirectory is null (the early return on line 347)
  • any bare name, which also falls back unchanged at :431 when the overlay finds no match

On Unix, .NET's Process.ResolvePath tries, in order:

  1. Path.Combine(dirname(Environment.ProcessPath), fileName)
  2. the current directory
  3. PATH

A shell does neither of the first two for these names.

Case 1: a relative path with no WorkingDirectory

  • Setup: build.sh that prints "APP-DIR copy" sits in dirname(Environment.ProcessPath), and build.sh that prints "CWD copy" sits in the current directory.

  • Call:

    Directory.SetCurrentDirectory(root);
    await RunCommand.ExecuteAsync("./build.sh", [], new OutputHandler(Console.Write));
  • Observed: APP-DIR copy, both through the apphost and through dotnet app.dll. Under dotnet app.dll the "app dir" is /usr/share/dotnet.

  • Expected: CWD copy, which is what sh -c ./build.sh prints.

Case 2: a bare name runs a file in the caller's current directory before PATH

Why it matters

Suggested fix

On non-Windows:

  • When fileName has a directory part and is not rooted, combine it with WorkingDirectory ?? Directory.GetCurrentDirectory(). Leave the result unnormalized, as Resolve ".." in a relative executable from where a symlinked working directory points [patch] #149 does, so .. resolves the way the shell resolves it.
  • Resolve a bare name on the effective PATH (the overlay PATH if set, else Environment.GetEnvironmentVariable("PATH")), reusing ResolveOnSearchPath/TryExecutable, and pass the absolute result.
  • If nothing matches, fail the way a shell does ("not found") instead of handing the bare name to .NET.
  • Update README.md:223 and :238 to match.

Tests to add:

  • ./x.sh with no WorkingDirectory runs the current directory's copy, not the app-directory copy.
  • A bare name that exists both on PATH and as a file in the caller's current directory (executable, or not executable) runs the PATH copy.

Activity

  1. matt-edmondson commented on Nov 12, 2026

    @matt-edmondson
    ContributorAuthor

    Triage


    Generated by Claude Code

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

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions