Skip to content

Initial-directory command uses POSIX 'cd … && pwd', fails on Windows PowerShell 5.1 SSH targets #713

@ahbarnum

Description

@ahbarnum

Summary

When a terminal is opened with an initial directory (e.g. via the file
manager's open-terminal action), Termix sends a hardcoded POSIX-style
cd "<path>" && pwd command to the remote shell. On an SSH host whose
session shell is Windows PowerShell 5.1, && is not a valid statement
separator, so the initial cd fails immediately.

Environment

  • Termix 2.2.1 (ghcr.io/lukegus/termix:latest), Docker.
  • Managed host: Windows; the SSH session shell is Windows PowerShell 5.1
    (Windows OpenSSH DefaultShell set to powershell.exe).

Reproduction

  1. Add a Windows SSH host whose login shell is Windows PowerShell 5.1.
  2. In the file manager for that host, open a terminal at a folder (i.e.,
    open a terminal with an initial path).

Observed (verbatim)

The remote PowerShell receives and rejects the injected command:

PS C:\Users\abarn> cd "/C:/requests" && pwd
At line:1 char:19
+ cd "/C:/requests" && pwd
+                   ~~
The token '&&' is not a valid statement separator in this version.
    + CategoryInfo          : ParserError: (:) [], ParentContainsErrorRecordException
    + FullyQualifiedErrorId : InvalidEndOfLine

Source

On main, src/backend/ssh/terminal.ts (around line 1627) builds the
initial-directory command unconditionally as:

const cdCommand = `cd "${initialPath.replace(/"/g, '\\"')}" && pwd\r`;

What is certain

&& (and ||) pipeline-chain operators were introduced in PowerShell 7.0.
Windows PowerShell 5.1 does not support && and errors exactly as shown
above. So this initial-cd form cannot succeed on SSH targets whose shell
is Windows PowerShell 5.1 or earlier.

(The exact command as received is quoted verbatim above, including the path
string as it arrived — /C:/requests — without further interpretation.)

Suggestion

The cd "<path>" && pwd form assumes a POSIX shell (or PowerShell 7+).
Consider making the initial-directory step shell-appropriate for non-POSIX
targets, or configurable per host, rather than emitting a POSIX && chain
unconditionally. Happy to test a patch.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions