fix: .bashrc merge algorithm corrupted multi-line shell constructs (issue #66)#67
Merged
fix: .bashrc merge algorithm corrupted multi-line shell constructs (issue #66)#67
Conversation
Adding .gitkeep for PR creation (default mode). This file will be removed when the task is complete. Issue: #66
…ssue #66) Root cause: the line-level deduplication in the Dockerfile merge step treated every shell line in isolation. Since Ubuntu's base .bashrc already contains standalone `fi` lines (closing its own if blocks), the closing `fi` from the Perlbrew `if [ -n "$PS1" ]; then ... fi` block was silently deduplicated away. This left an unclosed `if` in the merged .bashrc, causing: bash: /home/sandbox/.bashrc: line N: syntax error: unexpected end of file The error appeared only when running `bash` inside the container (not at container start), because .bashrc has an early-return guard for non-interactive shells — entrypoint.sh is non-interactive, so it returned before the broken block; an explicit `bash` invocation is interactive and hit the syntax error. Fixes: 1. Replace line-level deduplication with section-header deduplication in both Dockerfiles. Sections are identified by their unique `# <Tool> configuration` comment. If the header already exists in the base, the entire section is skipped; otherwise the full section (header + body) is appended intact. This preserves all multi-line shell constructs (if/fi, etc.) correctly. 2. Replace bash-specific `[[ ]]` and `source` with POSIX `[ ]` and `.` in SDKMAN .bashrc snippets (java/install.sh, kotlin/install.sh, full-sandbox/install.sh). Ubuntu's /bin/sh is dash, not bash. Added: - experiments/test-bashrc-merge.sh — reproduces the bug (confirms root cause) - experiments/test-bashrc-merge-fix.sh — verifies the fix (13/13 tests pass) - docs/case-studies/issue-66/CASE-STUDY.md — full root cause analysis Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
bash inside bash
Member
Author
🤖 Solution Draft LogThis log file contains the complete execution trace of the AI solution draft process. 💰 Cost estimation:
Now working session is ended, feel free to review and add any feedback on the solution draft. |
Member
Author
✅ Ready to mergeThis pull request is now ready to be merged:
Monitored by hive-mind with --auto-restart-until-mergeable flag |
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.
Fixes #66
Root Cause
When running
bashinside an already-running bash session in the sandbox container, bash sources~/.bashrcand hits a fatal syntax error:The error occurs only on explicit
bashinvocations (not at container start) because.bashrchas an early-return guard:entrypoint.shis non-interactive → returns early, never reaches the broken block. An explicitbashis interactive → executes the full.bashrc→ hits the unclosedif.Root cause: The
.bashrcmerge algorithm in the Dockerfile used line-level deduplication (grep -qxF "$line"). Since Ubuntu's base.bashrcalready contains standalonefilines (closing its built-inifblocks), the closingfiof the Perlbrewif [ -n "$PS1" ]; then ... fiblock was silently deduplicated away, leaving an unclosedif.Verified with
experiments/test-bashrc-merge.sh:Solution
Fix 1: Section-Header Deduplication
Replace line-level deduplication with section-header deduplication in both Dockerfiles. Each language's
.bashrcblock starts with a unique# <Tool> configurationcomment. The new algorithm:.bashrcfi,done, etc.) as a complete unitThis preserves all multi-line shell constructs intact and handles cross-language deduplication correctly (e.g., both
java/install.shandkotlin/install.shwrite# SDKMAN configuration— the second is correctly skipped as a whole).Fix 2: POSIX-Compatible SDKMAN Syntax
Replace
[[ -s ... ]] && sourcewith[ -s ... ] && .in SDKMAN.bashrcsnippets. Ubuntu's/bin/shisdash— bash-specific[[ ]]andsourcewould fail if.bashrcis ever sourced from a POSIX shell script.Files Changed
Dockerfileubuntu/24.04/full-sandbox/Dockerfileubuntu/24.04/java/install.sh[ ]and.instead of[[ ]]andsourceubuntu/24.04/kotlin/install.shubuntu/24.04/full-sandbox/install.shVerification
experiments/test-bashrc-merge-fix.sh— 13/13 tests pass:.bashrc(fix confirmed ✓)if/fiblock is complete and balanced ✓[[ ]]bash-specific syntax in merged output ✓Case Study
Full root cause analysis, timeline, and solution in
docs/case-studies/issue-66/CASE-STUDY.md.🤖 Generated with Claude Code