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§
- Segment
Cwd - 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
relunderbase, keeping a POSIX-rooted base POSIX. - segments_
with_ cwd - Split
commandinto segments, trackingcdas it goes.