Skip to content

Bash script handler doesn't quote the script path, breaking hooks/scripts in directories with spaces #4404

@sc0rp10

Description

@sc0rp10

Description

The bash script handler template in ScriptHandlerHelpers.cs does not quote the {0} placeholder, which causes word splitting when the resolved script path contains spaces.

Root cause

In src/Runner.Worker/Handlers/ScriptHandlerHelpers.cs, the default arguments for bash are:

_defaultArguments["bash"] = "--noprofile --norc -e -o pipefail {0}";

When {0} is replaced with a path like /Volumes/My Shared Files/hook.sh, the resulting command becomes:

bash --noprofile --norc -e -o pipefail /Volumes/My Shared Files/hook.sh

Bash interprets this as two separate arguments: /Volumes/My and Shared Files/hook.sh, causing a "No such file or directory" error.

Comparison with other shells

The PowerShell and cmd templates correctly quote the path:

_defaultArguments["pwsh"] = "-command \"& '{0}'\"";
_defaultArguments["powershell"] = "-command \". '{0}'\"";
_defaultArguments["cmd"] = "/D /E:ON /V:OFF /S /C \"CALL \"{0}\"\"";

Only bash and sh leave {0} unquoted.

Impact

This affects any scenario where the runner executes a bash script from a path containing spaces, including:

  • Job hooks (ACTIONS_RUNNER_HOOK_JOB_STARTED, etc.) when the hook script resides under a shared directory with spaces in its path (e.g., macOS Tart VMs mount shared directories at /Volumes/My Shared Files/)
  • run: steps if the workspace path contains spaces (less common but possible)

Note: the hook discovery itself (File.Exists(hookData.Path) in JobHookProvider.cs) works fine because .NET handles spaces natively — it's only the bash execution that breaks.

Suggested fix

Quote {0} in the bash/sh templates:

_defaultArguments["bash"] = "--noprofile --norc -e -o pipefail \"{0}\"";
_defaultArguments["sh"]   = "-e \"{0}\"";

This matches the quoting approach already used by pwsh, powershell, and cmd.

Environment

  • Runner version: main branch (also affects all released versions)
  • OS: any (reproducible on macOS with Tart VM shared directories, but the code is platform-agnostic)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions