Non-interactive `chruby-exec` fails with `zsh:1: command not found: chruby`
amomchilov opened this issue · 4 comments
Description
chruby.sh
is typically sourced from ~/.zshrc
, which is only run in interactive shells. For non-interactive shells, chruby-exec
calls zsh
without the -i
:
Line 41 in 6719201
This causes the ~/.zshrc
to never be sourced, and thus, for chruby
to be unavailable.
Steps To Reproduce
Steps to reproduce the bug:
-
Install the latest release (0.39.0 right now) with
brew install chruby
-
Run
chruby-exec
with a non-terminal STDIN. E.g. with:echo "abc" | chruby-exec "ruby-3.3.0" -- ruby --version
Expected Behavior
Run the command successfully, (in this example, ruby --version
). It works correctly if you drop the echo "abc" |
:
$ chruby-exec "ruby-3.3.0" -- ruby --version
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23]
This works fine because it hits this other branch, which include -i
and runs ~/.zshrc
:
Line 40 in 6719201
This also works on the latest master
branch, so it looks like it's a packaging/release issue:
$ brew uninstall chruby && brew install chruby --head
$ echo "abc" | chruby-exec "ruby-3.3.0" -- ruby --version
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [arm64-darwin23]
Actual Behavior
$ echo "abc" | chruby-exec "ruby-3.3.0" -- ruby --version
zsh:1: command not found: chruby
Notes
https://github.com/postmodern/chruby/releases/tag/v0.3.9 was release in April 19, 2023, but for some reason, it doesn't include this change to chruby-exec
from 2014. I confirmed this in 2 ways:
- Inspecting
bin/chruby-exec
of thechruby-0.3.9.tar.gz
downloaded right from the release page - Inspecting
/opt/homebrew/bin/chruby-exec
installed by homebrew.
It looks to me like the release process just didn't package up this file correctly.
Environment
$ bash --version
GNU bash, version 5.2.26(1)-release (aarch64-apple-darwin23.2.0)
Copyright (C) 2022 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
$ zsh --version
zsh 5.9 (x86_64-apple-darwin23.0)
$ chruby --version
Untitled 10.sh: line 8: chruby: command not found
$ ruby --version
ruby 2.6.10p210 (2022-04-12 revision 67958) [universal.arm64e-darwin23]
$ gem --version
3.0.3.1
$ gem env
RubyGems Environment:
- RUBYGEMS VERSION: 3.0.3.1
- RUBY VERSION: 2.6.10 (2022-04-12 patchlevel 210) [universal.arm64e-darwin23]
- INSTALLATION DIRECTORY: /Library/Ruby/Gems/2.6.0
- USER INSTALLATION DIRECTORY: /Users/Alex/.gem/ruby/2.6.0
- RUBY EXECUTABLE: /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby
- GIT EXECUTABLE: /usr/bin/git
- EXECUTABLE DIRECTORY: /usr/local/bin
- SPEC CACHE DIRECTORY: /Users/Alex/.gem/specs
- SYSTEM CONFIGURATION DIRECTORY: /Library/Ruby/Site
- RUBYGEMS PLATFORMS:
- ruby
- universal-darwin-23
- GEM PATHS:
- /Library/Ruby/Gems/2.6.0
- /Users/Alex/.gem/ruby/2.6.0
- /System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/gems/2.6.0
- GEM CONFIGURATION:
- :update_sources => true
- :verbose => true
- :backtrace => false
- :bulk_threshold => 1000
- REMOTE SOURCES:
- https://rubygems.org/
- SHELL PATH:
- /opt/homebrew/bin
- /Users/Alex/.cargo/bin
- /usr/local/bin
- /System/Cryptexes/App/usr/bin
- /usr/bin
- /bin
- /usr/sbin
- /sbin
- /var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin
- /var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin
- /var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin
- /Library/Apple/usr/bin
- /Users/Alex/.antigen/bundles/robbyrussell/oh-my-zsh/lib
- /Users/Alex/.antigen/bundles/marlonrichert/zsh-autocomplete-main
- /Users/Alex/.antigen/bundles/marlonrichert/zsh-autocomplete-main/functions
- /Users/Alex/.antigen/bundles/robbyrussell/oh-my-zsh/plugins/git
- /Users/Alex/.antigen/bundles/robbyrussell/oh-my-zsh/plugins/last-working-dir
- /Users/Alex/.antigen/bundles/robbyrussell/oh-my-zsh/plugins/macos
- /Users/Alex/.antigen/bundles/robbyrussell/oh-my-zsh/plugins/sudo
- /Users/Alex/.antigen/bundles/robbyrussell/oh-my-zsh/plugins/alias-finder
- /Users/Alex/.antigen/bundles/robbyrussell/oh-my-zsh/plugins/rust
- /Users/Alex/.antigen/bundles/robbyrussell/oh-my-zsh/plugins/colored-man-pages
- /Users/Alex/.antigen/bundles/robbyrussell/oh-my-zsh/plugins/command-not-found
- /Users/Alex/.antigen/bundles/robbyrussell/oh-my-zsh/plugins/common-aliases
- /Users/Alex/.antigen/bundles/robbyrussell/oh-my-zsh/plugins/dircycle
- /Users/Alex/.antigen/bundles/robbyrussell/oh-my-zsh/plugins/encode64
- /Users/Alex/.antigen/bundles/robbyrussell/oh-my-zsh/plugins/extract
- /Users/Alex/.antigen/bundles/robbyrussell/oh-my-zsh/plugins/jsontools
- /Users/Alex/.antigen/bundles/robbyrussell/oh-my-zsh/plugins/swiftpm
- /Users/Alex/.antigen/bundles/dracula/zsh-syntax-highlighting
- /Users/Alex/.antigen/bundles/zsh-users/zsh-syntax-highlighting
- /Applications/CodeRunner.app/Contents/SharedSupport/Developer/bin
@amomchilov Could you post your ~/.zshrc
and /etc/zshrc
files? I suspect there's extra logic there that is exiting if the shell is not in interactive mode. On Fedora Linux with zsh 5.9, if I added echo "loaded"
to my ~/.zshrc
, it shows that the configuration file is loaded when running zsh
and zsh -i
.
We cannot always specify -i
because that would assume you are always running in an interactive shell, which might not always be the case (ex: running chruby-exec
in a cronjob).
Also note that chruby-0.3.9 was indeed released 2014-11-23. GitHub releases are separate from the git tags, and I didn't start adding GitHub releases for git tags until much later.
Could you post your ~/.zshrc and /etc/zshrc files? I suspect there's extra logic there that is exiting if the shell is not in interactive mode.
My ~/.zshrc
was pretty extensive, but I minimized it down to the bare minimum (and still reproduced the issue with the steps in the OP):
zsh_user_path=(
"/opt/homebrew/bin"
)
export path=($zsh_user_path $path)
if [[ -f"/opt/homebrew/opt/chruby/share/chruby/chruby.sh" ]]; then
source "/opt/homebrew/opt/chruby/share/chruby/chruby.sh"
fi
My /etc/zshrc
is stock from macOS:
/etc/zshrc
# System-wide profile for interactive zsh(1) shells.
# Setup user specific overrides for this in ~/.zshrc. See zshbuiltins(1)
# and zshoptions(1) for more details.
# Correctly display UTF-8 with combining characters.
if [[ "$(locale LC_CTYPE)" == "UTF-8" ]]; then
setopt COMBINING_CHARS
fi
# Disable the log builtin, so we don't conflict with /usr/bin/log
disable log
# Save command history
HISTFILE=${ZDOTDIR:-$HOME}/.zsh_history
HISTSIZE=2000
SAVEHIST=1000
# Beep on error
setopt BEEP
# Use keycodes (generated via zkbd) if present, otherwise fallback on
# values from terminfo
if [[ -r ${ZDOTDIR:-$HOME}/.zkbd/${TERM}-${VENDOR} ]] ; then
source ${ZDOTDIR:-$HOME}/.zkbd/${TERM}-${VENDOR}
else
typeset -g -A key
[[ -n "$terminfo[kf1]" ]] && key[F1]=$terminfo[kf1]
[[ -n "$terminfo[kf2]" ]] && key[F2]=$terminfo[kf2]
[[ -n "$terminfo[kf3]" ]] && key[F3]=$terminfo[kf3]
[[ -n "$terminfo[kf4]" ]] && key[F4]=$terminfo[kf4]
[[ -n "$terminfo[kf5]" ]] && key[F5]=$terminfo[kf5]
[[ -n "$terminfo[kf6]" ]] && key[F6]=$terminfo[kf6]
[[ -n "$terminfo[kf7]" ]] && key[F7]=$terminfo[kf7]
[[ -n "$terminfo[kf8]" ]] && key[F8]=$terminfo[kf8]
[[ -n "$terminfo[kf9]" ]] && key[F9]=$terminfo[kf9]
[[ -n "$terminfo[kf10]" ]] && key[F10]=$terminfo[kf10]
[[ -n "$terminfo[kf11]" ]] && key[F11]=$terminfo[kf11]
[[ -n "$terminfo[kf12]" ]] && key[F12]=$terminfo[kf12]
[[ -n "$terminfo[kf13]" ]] && key[F13]=$terminfo[kf13]
[[ -n "$terminfo[kf14]" ]] && key[F14]=$terminfo[kf14]
[[ -n "$terminfo[kf15]" ]] && key[F15]=$terminfo[kf15]
[[ -n "$terminfo[kf16]" ]] && key[F16]=$terminfo[kf16]
[[ -n "$terminfo[kf17]" ]] && key[F17]=$terminfo[kf17]
[[ -n "$terminfo[kf18]" ]] && key[F18]=$terminfo[kf18]
[[ -n "$terminfo[kf19]" ]] && key[F19]=$terminfo[kf19]
[[ -n "$terminfo[kf20]" ]] && key[F20]=$terminfo[kf20]
[[ -n "$terminfo[kbs]" ]] && key[Backspace]=$terminfo[kbs]
[[ -n "$terminfo[kich1]" ]] && key[Insert]=$terminfo[kich1]
[[ -n "$terminfo[kdch1]" ]] && key[Delete]=$terminfo[kdch1]
[[ -n "$terminfo[khome]" ]] && key[Home]=$terminfo[khome]
[[ -n "$terminfo[kend]" ]] && key[End]=$terminfo[kend]
[[ -n "$terminfo[kpp]" ]] && key[PageUp]=$terminfo[kpp]
[[ -n "$terminfo[knp]" ]] && key[PageDown]=$terminfo[knp]
[[ -n "$terminfo[kcuu1]" ]] && key[Up]=$terminfo[kcuu1]
[[ -n "$terminfo[kcub1]" ]] && key[Left]=$terminfo[kcub1]
[[ -n "$terminfo[kcud1]" ]] && key[Down]=$terminfo[kcud1]
[[ -n "$terminfo[kcuf1]" ]] && key[Right]=$terminfo[kcuf1]
fi
# Default key bindings
[[ -n ${key[Delete]} ]] && bindkey "${key[Delete]}" delete-char
[[ -n ${key[Home]} ]] && bindkey "${key[Home]}" beginning-of-line
[[ -n ${key[End]} ]] && bindkey "${key[End]}" end-of-line
[[ -n ${key[Up]} ]] && bindkey "${key[Up]}" up-line-or-search
[[ -n ${key[Down]} ]] && bindkey "${key[Down]}" down-line-or-search
# Default prompt
PS1="%n@%m %1~ %# "
# Useful support for interacting with Terminal.app or other terminal programs
[ -r "/etc/zshrc_$TERM_PROGRAM" ] && . "/etc/zshrc_$TERM_PROGRAM"
We cannot always specify
-i
because that would assume you are always running in an interactive shell, which might not always be the case (ex: runningchruby-exec
in a cronjob).
Yeah, agreed. This seems like more of a defect in the zsh conventions, but that isn't something we can really change.
If zsh kept the same convention as ~/.bashrc
(minimal, always run) vs ~/.bash_profile
(more "bloat", for interactive shells only), then we could have just always used non-interactive shells, and rely on the path being set.
But since most people set their $PATH
in ~/.zshrc
... welp, idk what we can do to reasonably handle that.
I'm also totally confused as to what --head
does to make this work, that 0.38.0
didn't.
Also note that chruby-0.3.9 was indeed released 2014-11-23. GitHub releases are separate from the git tags, and I didn't start adding GitHub releases for git tags until much later.
Ah, that explains that part.
FWIW there is ~/.zshenv
which is always sourced. That's where I do PATH modifications.
And my ~/.zshrc
is then for interative-only stuff like completion, etc.
Hey @eregon,
I agree that's the right approach in the abstract, but regrettably, that's just not the common convention with ZSH.
For example, Homebrew's official installation instructions used to suggest adding to your .zshrc
. They only recently switched to using .zprofile
in Sept 2023. There's a contention between what's "right" and what's most common in people's real-world usage.
To me, the most puzzling part here is why --head
works. I would have expected it to fail with the same issue.