Skip to main content

Module command_cwd

Module command_cwd 

Source
Expand description

Which directory a command’s segments actually run in (GH #1661, #1662).

A tool call carries one cwd, but the command it runs may move: cd repo && grep -rn … . walks a tree the call never named, and cd "$SCRATCH" && curl -o shot.png … writes to a directory that is sanctioned for exactly that. Judging either against the call’s cwd alone gets the answer wrong — too lenient in the first case, too strict in the second.

Only a plain cd <literal> segment is followed, and only where it is certain to have run before the next command (#1850). A target spelled through a variable is followed when that variable is known — $TMPDIR, or one this same command set to a literal (#2079, command_vars). Everything else that can move the shell — any other variable, a substitution, pushd/popd, a cd inside a subshell, a brace group, a loop or a function, a cd that may be skipped (a || cd x) or may fail (cd missing; …) — leaves the directory unknown, and an unknown directory is reported as such rather than guessed at. The write guard relies on that: judging a later command against a directory it does not run in is how a redirect lands in the project.

Quoted text is data: printf '… cd /tmp …' > f does not move anything (#2081). The exception is eval, which runs text in this shell, so any eval leaves the directory unknown.

Structs§

SegmentCwd
One command segment together with the directory it runs in.

Functions§

final_cwd
The directory in effect once every segment has run.
join_in
Join rel under base, keeping a POSIX-rooted base POSIX.
segments_with_cwd
Split command into segments, tracking cd as it goes.