Skip to content

shell: single-quote the profile line before echoing it - #24042

Open
rawsun007 wants to merge 1 commit into
Homebrew:mainfrom
rawsun007:fix/shell-profile-single-quote
Open

rawsun007 wants to merge 1 commit into
Homebrew:mainfrom
rawsun007:fix/shell-profile-single-quote

Conversation

@rawsun007

Copy link
Copy Markdown
Contributor

  • Have you followed our Contributing guidelines?
  • Have you checked for other open Pull Requests for the same change?
  • Have you explained what your changes do? Performance claims (e.g. "this is faster") must include brew benchmark results.
  • Have you explained why you'd like these changes included, not just what they do?
  • For bug fixes, have you given step-by-step brew commands to reproduce the bug?
  • Have you written new tests (excluding integration tests)? Here's an example.
  • Have you successfully run brew lgtm (style, typechecking and tests) locally?

  • I did not use AI/LLM to create this PR, or I disclosed the tool/model below and reviewed its output; I did not attribute commits to AI and will answer maintainer questions and review comments myself without AI/LLM.

Follow-up to #24035, which named this as the part it deliberately left alone.

set_variable_in_profile and prepend_path_in_profile build a command for the user to paste, wrapping the whole profile line in literal single quotes. A single quote in the value closes that string early:

$ brew ruby -e 'require "utils/shell"; ENV["SHELL"]="/bin/bash"; puts Utils::Shell.prepend_path_in_profile("/Users/o'brien/bin")'
echo 'export PATH=/Users/o\'brien/bin:$PATH' >> /Users/me/.bash_profile

$ bash --norc -c "echo 'export PATH=/Users/o\'brien/bin:\$PATH' >> prof"
bash: -c: line 0: unexpected EOF while looking for matching `''

Nothing is written. The \ that sh_quote adds is literal inside single quotes, so it does not escape anything; a single-quoted string can only be interrupted, escaped and resumed.

The pwsh branch already passes its whole line through pwsh_quote. sh_single_quote does the same for the Bourne, rc, csh and fish branches.

Emitting the command for five values (apostrophe, space, $, double quote, plain) under bash, zsh, sh, ksh and tcsh, then running it and sourcing the profile it writes: before, the five apostrophe cases fail to run at all, one per shell; after, all 30 run and source back the exact value. The output is byte-identical to today's for every value that does not contain a quote, so nothing that works now changes.

Reachable wherever HOMEBREW_PREFIX or a keg path contains an apostrophe, which on Linux means a home-directory install for someone whose username has one. The callers are brew link for keg-only formulae, the keg-only caveats, and the HOMEBREW_TEMP advice in the Linux diagnostic.

Three new examples, one per changed behaviour; reverting only utils/shell.rb fails exactly those three and nothing else. brew tests also passes for caveats, diagnostic, cmd/link and cmd/--env.

rc is covered by the same change but I have no rc to run it under, so that branch is reasoned from the shared echo '...' shape rather than measured. Saying so rather than implying I tested it.

AI disclosure: written with Claude Code (Claude Opus 5) on my account. The before/after counts come from a harness that ran each emitted command in the real shell and sourced the profile it produced. I answer review comments myself.

The profile helpers wrapped the whole line in literal single quotes, so
a value containing one closed the string early and the emitted command
was a syntax error that wrote nothing. The pwsh branch already quoted
the line through pwsh_quote; sh_single_quote gives the Bourne, rc, csh
and fish branches the same treatment.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant