Repository navigation
fix(pty-proxy): don't re-exec shells running commands from a string or file - #4414
Merged
atuin-bot merged 1 commit intoOct 20, 2026
Conversation
Contributor
[Medium impact] The PR appears safe to merge; no actionable new issues were found. SummaryPrevents Bash and Zsh from replacing command or file invocations with a PTY proxy.
Reviews (3) Β· Last reviewed commit: "Fix tests on older Bash" Β· Reviewed by Greptile |
Member
|
Thanks for the PR! I'm trying to see if we can also detect |
Member
|
/merge |
Collaborator
|
Landed as 658b539. GitHub shows this merged once it reaches main. |
β¦r file (atuinsh#4414) The bash/zsh preamble re-execs any interactive shell attached to a terminal as `atuin pty-proxy`, which drops the command passed to `bash -ic` or `zsh -ic` and leaves the user at a prompt. Skip the re-exec when BASH_EXECUTION_STRING or ZSH_EXECUTION_STRING is set. Fixes atuinsh#4412 Edit by @taylordotfish: I added support for detecting `bash -i <file>` and `zsh -i <file>` too. There are some caveats as it isn't possible to check for this with 100% accuracy. In particular, these cases will continue to have incorrect behavior: * Zsh: - If the basename of `<file>` is `zsh` or `-zsh`, we will incorrectly spawn a proxy (though this can depend on whether the shell is a login shell). - If Zsh is spawned with a custom `argv[0]`, we will, in general, not spawn a proxy even though we should. However, before this PR, we would actually try to execute `argv[0]` which would simply kill the shell, so this is an improvement. (Note that if `argv[0]` happens to be a valid executable, we will still incorrectly execute it as before.) - If Zsh is an older version that doesn't set `ZSH_ARGZERO`, we can't detect when we're reading from a file and will always spawn a proxy. * Bash: - If `<file>` is `bash` or `-bash`, we will incorrectly spawn a proxy (though can depend on whether the shell is a login shell). - If Bash is invoked via a relative path (`./bin/bash`) and the shell has changed CWD before the proxy check is run, we will not spawn a proxy even though we should. - If Bash is spawned with a custom `argv[0]`, we will, in general, not spawn a proxy even though we should. - If Bash is started as a login shell but the user's shell in `/etc/passwd` isn't Bash, we will not spawn a proxy even though we should. However, before this PR, we would incorrectly execute that non-Bash program, so this is an improvement. However, if the `/etc/passwd` shell is a different installation of Bash, we will still incorrectly spawn that other Bash as before. - If Bash is older than version 5.2, we can't detect when we're reading from a file and will always spawn a proxy. <!-- Thank you for making a PR! Bug fixes are always welcome, but if you're adding a new feature or changing an existing one, we'd really appreciate if you open an issue, post on the forum, or drop in on Discord --> ## Checks - [x] I am happy for maintainers to push small adjustments to this PR, to speed up the review cycle - [x] I have checked that there are no existing pull requests for the same thing Co-authored-by: taylor.fish <contact@taylor.fish>
atuin-bot
force-pushed
the
fix-4412-pty-proxy-noninteractive-command
branch
from
October 20, 2026 21:15
5f68b0c to
658b539
Compare
atuin-bot
pushed a commit
that referenced
this pull request
Oct 22, 2026
### Bug Fixes - *(ai)* Import IntoStaticStr from strum_macros, not strum ([#4480](#4480)) - *(ai)* Improve detection of git repositories ([#4450](#4450)) - *(client)* Resolve relative config paths beside config.toml, not the cwd ([#4479](#4479)) - *(config)* Don't print errors twice ([#4501](#4501)) - *(daemon)* Fetch the server's capabilities until a fetch succeeds - *(daemon)* Spare a stale pidfile's PID when evicting ([#4512](#4512)) - *(daemon)* Handle daemons not spawned by atuin ([#4516](#4516)) - *(output)* Keep quoted words together in output search ([#4502](#4502)) - *(packfile)* Load only the records inside a manifest's range - *(pty-proxy)* Standalone init with `atuin pty-proxy init` ([#4449](#4449)) - *(pty-proxy)* Wait for input on a non-blocking inherited stdin ([#4486](#4486)) - *(pty-proxy)* Don't re-exec shells running commands from a string or file ([#4414](#4414)) - *(search)* Don't panic when copying with no results ([#4426](#4426)) - *(server)* Let `ATUIN_*` environment variables override server.toml ([#4456](#4456)) - *(update)* Accept ATUIN_GITHUB_TOKEN ([#4262](#4262)) - Remove duplicated word in the no-history stats message ([#4451](#4451)) - Error printing in `?` handler ([#4448](#4448)) - Normalize relative gitdir paths in worktree resolution ([#4506](#4506)) - Upgrade regressions found in release QA ([#4519](#4519)) ### Documentation - Fix ctrl_n_shortcuts default value ([#4458](#4458)) - List all history list --format variables ([#4460](#4460)) - Fix the --reverse default for history list ([#4472](#4472)) - Mention December default in wrapped --year help ([#4476](#4476)) ### Features - *(common)* AbsPath and AbsPathBuf, Path and PathBuf checked to be absolute ([#4481](#4481)) - *(common)* Find a process's cgroup under cgroup v1 and v2 ([#4513](#4513)) - *(daemon)* Run the daemon as a launchd agent on macOS ([#4517](#4517)) - *(pty-proxy)* Window title follows child process ([#4447](#4447)) - *(secrets)* Keep HashiCorp tokens out of history ([#4445](#4445)) ### Miscellaneous Tasks - Give mono its own nixfmt step and scope atuin's to atuin/ - Say a /merge's landed commit gets CI on main - Rebuild the apt .deb cache for Ubuntu 24.04 ([#4504](#4504)) - Remove the benchmarks ([#4511](#4511)) ### Performance - *(common)* Compile the vendor regexes once ([#4485](#4485)) - *(common)* Drop the tree watcher's file-id cache ([#4492](#4492)) - *(common)* Release a line reader's buffer at the end of the file ([#4494](#4494)) - *(common)* Keep no tree watcher entry for a rejected file ([#4493](#4493)) - *(daemon)* Warm up only a resumed session's unanswered calls ([#4490](#4490)) - *(packfile)* Compress packs in one shot ([#4484](#4484)) ### Refactor - *(daemon)* Managed daemon service with multiple backends ([#4488](#4488)) - *(daemon)* Move daemon startup into the service module ([#4503](#4503)) - *(daemon)* Keep where the daemon listens behind service::address ([#4514](#4514)) - *(daemon)* Take up the daemon's socket in SocketHolder, not Backend ([#4515](#4515)) - *(deps)* Bump clap_complete_nushell from 4.6.0 to 4.6.2 ([#4473](#4473)) - *(deps)* Bump clap_complete from 4.6.9 to 4.6.11 ([#4396](#4396)) - *(deps)* Bump ratatui from 0.30.0 to 0.30.2 ([#4474](#4474)) - *(deps)* Bump certifi from 2025.11.12 to 2026.10.19 in /docs in the uv group across 1 directory ([#4500](#4500)) - *(pty-proxy)* Run on tokio with the parser on its own runtime ([#4482](#4482)) - *(pty-proxy)* Forward captures to the daemon on the proxy's runtime ([#4487](#4487)) - *(pty-proxy)* Rename the screen's parser to Emulator ([#4510](#4510)) - *(pty-proxy)* Migrate output parsing to vte ([#4518](#4518)) ### Testing - *(daemon)* Run the output index tests under rstest ([#4496](#4496))
1 task
1 task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bash/zsh preamble re-execs any interactive shell attached to a terminal as
atuin pty-proxy, which drops the command passed tobash -icorzsh -icand leaves the user at a prompt. Skip the re-exec when BASH_EXECUTION_STRING or ZSH_EXECUTION_STRING is set.Fixes #4412
Edit by @taylordotfish: I added support for detecting
bash -i <file>andzsh -i <file>too. There are some caveats as it isn't possible to check for this with 100% accuracy. In particular, these cases will continue to have incorrect behavior:Zsh:
<file>iszshor-zsh, we will incorrectly spawn a proxy (though this can depend on whether the shell is a login shell).argv[0], we will, in general, not spawn a proxy even though we should. However, before this PR, we would actually try to executeargv[0]which would simply kill the shell, so this is an improvement. (Note that ifargv[0]happens to be a valid executable, we will still incorrectly execute it as before.)ZSH_ARGZERO, we can't detect when we're reading from a file and will always spawn a proxy.Bash:
<file>isbashor-bash, we will incorrectly spawn a proxy (though can depend on whether the shell is a login shell)../bin/bash) and the shell has changed CWD before the proxy check is run, we will not spawn a proxy even though we should.argv[0], we will, in general, not spawn a proxy even though we should./etc/passwdisn't Bash, we will not spawn a proxy even though we should. However, before this PR, we would incorrectly execute that non-Bash program, so this is an improvement. However, if the/etc/passwdshell is a different installation of Bash, we will still incorrectly spawn that other Bash as before.Checks