-
Notifications
You must be signed in to change notification settings - Fork 564
Fix zsh compatibility: Replace $(...) with backticks #974
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Replaces all $(...) command substitution syntax with backticks for shell portability. The Bash tool in Claude Code uses the user's default shell (zsh in many cases), and $(...) produces parse errors in zsh. Changes: - Converted 217 instances across 29 files - Preserved multi-line format with backslash continuation - No functional changes, only syntax conversion Files modified: - 11 shell scripts (.sh) - 13 command files (commands/pm/*.md) - 5 rule files (rules/*.md) Fixes automazeio#973 Tested in zsh 5.9 - all commands now work correctly.
WalkthroughBroad replacement of POSIX command substitution $(...) with backticks Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor U as User
participant EM as epic-merge.sh
participant Git as Git
U->>EM: Run epic-merge
EM->>Git: git status --porcelain
Git-->>EM: Output
alt Uncommitted changes detected
EM->>U: Print error
EM-->>U: exit 1
else Clean working tree
EM->>EM: Proceed with merge steps
EM-->>U: Continue script
end
%% Note: Added explicit exit 1 on dirty state
sequenceDiagram
autonumber
actor U as User
participant IS as issue-sync.sh
participant Git as Git
U->>IS: Run issue-sync
IS->>Git: git remote get-url origin
Git-->>IS: remote_url
IS->>IS: Derive REPO
alt REPO matches forbidden CCPM origin
IS->>U: Print guard message
IS-->>U: exit 1
else Safe to sync
IS->>IS: Continue sync logic
end
%% Note: Added explicit exit 1 on forbidden remote
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (29)
ccpm/commands/pm/epic-merge.md(6 hunks)ccpm/commands/pm/epic-refresh.md(1 hunks)ccpm/commands/pm/epic-start.md(1 hunks)ccpm/commands/pm/epic-sync.md(11 hunks)ccpm/commands/pm/issue-close.md(1 hunks)ccpm/commands/pm/issue-sync.md(1 hunks)ccpm/commands/pm/test-reference-update.md(2 hunks)ccpm/hooks/bash-worktree-fix.sh(6 hunks)ccpm/rules/agent-coordination.md(1 hunks)ccpm/rules/datetime.md(2 hunks)ccpm/rules/github-operations.md(2 hunks)ccpm/rules/path-standards.md(1 hunks)ccpm/rules/strip-frontmatter.md(2 hunks)ccpm/scripts/check-path-standards.sh(1 hunks)ccpm/scripts/fix-path-standards.sh(1 hunks)ccpm/scripts/pm/blocked.sh(2 hunks)ccpm/scripts/pm/epic-list.sh(3 hunks)ccpm/scripts/pm/epic-show.sh(3 hunks)ccpm/scripts/pm/epic-status.sh(5 hunks)ccpm/scripts/pm/in-progress.sh(3 hunks)ccpm/scripts/pm/init.sh(3 hunks)ccpm/scripts/pm/next.sh(1 hunks)ccpm/scripts/pm/prd-list.sh(3 hunks)ccpm/scripts/pm/prd-status.sh(3 hunks)ccpm/scripts/pm/search.sh(4 hunks)ccpm/scripts/pm/standup.sh(5 hunks)ccpm/scripts/pm/status.sh(3 hunks)ccpm/scripts/pm/validate.sh(3 hunks)ccpm/scripts/test-and-log.sh(3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
ccpm/scripts/fix-path-standards.sh (1)
ccpm/scripts/check-path-standards.sh (1)
print_success(16-18)
🪛 Shellcheck (0.11.0)
ccpm/scripts/pm/epic-status.sh
[warning] 38-38: status appears unused. Verify use (or export if used externally).
(SC2034)
[warning] 39-39: progress appears unused. Verify use (or export if used externally).
(SC2034)
ccpm/scripts/pm/standup.sh
[warning] 7-7: today appears unused. Verify use (or export if used externally).
(SC2034)
ccpm/scripts/pm/validate.sh
[warning] 77-77: For loops over find output are fragile. Use find -exec or a while read loop.
(SC2044)
ccpm/scripts/pm/init.sh
[error] 77-77: [ .. ] can't match globs. Use [[ .. ]] or case statement.
(SC2081)
🔇 Additional comments (1)
ccpm/scripts/fix-path-standards.sh (1)
56-60: Backtick substitution breaks due to unescaped quotesSwitching to backticks here introduces a syntax error: the inner
"around$fileterminate the outer string before the backtick closes, so the script aborts at runtime. Pull the basename into a variable (still using backticks) before building the message so the quotes stay balanced.- if ! diff -q "$file" "$backup_file" >/dev/null 2>&1; then - print_success "File fixed: `basename "$file"`" + local display_name=`basename "$file"` + if ! diff -q "$file" "$backup_file" >/dev/null 2>&1; then + print_success "File fixed: $display_name" return 0 else - print_info "File needs no changes: `basename "$file"`" + print_info "File needs no changes: $display_name" rm "$backup_file" # Remove unnecessary backup return 1 fiLikely an incorrect or invalid review comment.
| [ -d "$dir" ] && echo " • `basename "$dir"`" | ||
| done |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Backtick substitution breaks quoting here
echo " • \basename "$dir"`"now closes the surrounding double-quoted string at the inner"`, causing a parse error. Use escaped quotes inside the backticks (or assign to a temp variable) so the script stays syntactically valid.
- [ -d "$dir" ] && echo " • `basename "$dir"`"
+ [ -d "$dir" ] && echo " • `basename \"$dir\"`"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| [ -d "$dir" ] && echo " • `basename "$dir"`" | |
| done | |
| [ -d "$dir" ] && echo " • `basename \"$dir\"`" | |
| done |
🤖 Prompt for AI Agents
In ccpm/scripts/pm/epic-show.sh around lines 23-24 the command echo " •
`basename "$dir"`" breaks the surrounding double quotes because of the inner
unescaped quotes; replace the backtick form with a safe command substitution or
temp variable (e.g. name=$(basename "$dir") then echo " • $name") or use echo "
• $(basename "$dir")" so the inner quotes are not interpreted and the script
remains syntactically valid.
| echo " ⚠️ Missing epic.md in `basename "$epic_dir"`" | ||
| ((warnings++)) | ||
| fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Escape quotes inside these backtick substitutions
Each of these lines now contains something like echo " … \basename "$foo"`", so the inner "` prematurely closes the outer string and the script fails to parse. Escape the inner quotes (or capture the basename into a variable first) before echoing.
- echo " ⚠️ Missing epic.md in `basename "$epic_dir"`"
+ echo " ⚠️ Missing epic.md in `basename \"$epic_dir\"`"
...
- echo " ⚠️ Task `basename "$task_file" .md` references missing task: $dep"
+ echo " ⚠️ Task `basename \"$task_file\" .md` references missing task: $dep"
...
- echo " ⚠️ Missing frontmatter: `basename "$file"`"
+ echo " ⚠️ Missing frontmatter: `basename \"$file\"`"Also applies to: 60-62, 79-80
🤖 Prompt for AI Agents
In ccpm/scripts/pm/validate.sh around lines 29 to 31 (and similarly at 60-62 and
79-80), the echo lines use backtick command substitutions containing unescaped
double quotes (e.g. `basename "$epic_dir"`), which prematurely close the outer
echo string; either escape the inner quotes inside the backticks (e.g. `basename
\"...\"`) or, preferably, assign the basename to a temporary variable before
echoing and reference that variable in the echo to avoid nested-quote issues.
|
Having slept on it, I think this is the wrong approach. While it does fix the immediate portability issue for this project in its current state, it doesn't get around the fundamental and ongoing issue: CC's models will continue to write Bash scripts that are designed to work in Bash, without consideration for other shells! it's only a matter of time before this pops up again. The true fix is for Anthropic to address #7507. I'll leave this PR open for now, in case you're interested in fixing for CCPM's current state only, otherwise feel free to reject it 👍🏼 |
Applied PR #974 from automazeio/ccpm to fix shell compatibility issues. Replaces all command substitution syntax from $(...) to backticks for cross-shell portability between bash and zsh. Changes: - Convert $(...) to backticks in all shell scripts (30 files) - Preserve $((arithmetic)) expressions - Update commands, rules, hooks, and scripts - Test all modified scripts for syntax correctness This fixes parse errors when Claude Code Bash tool executes commands through zsh as the default shell. Related: automazeio/ccpm#974, automazeio/ccpm#973 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Summary
Fixes #973
Replaces all
$(...)command substitution syntax with backticks for shell portability across bash and zsh.Problem
The Bash tool in Claude Code executes commands through the user's default shell, not necessarily bash. Commands using
$(...)command substitution fail with parse errors when the default shell is zsh.Error example:
Solution
Converted all
$(...)to backticks`...`which works in both bash and zsh.Test Results
Before (zsh with
$(...)):After (zsh with backticks):
Changes
Files Modified
.sh)commands/pm/*.md)rules/*.md)Testing
Related Issues
Summary by CodeRabbit