What happens
I use fish, but my login shell is zsh, so $SHELL is /bin/zsh. try init returns the bash function instead of the fish function. The README line then fails:
❯ try init "$HOME/tries" | source
- (line 1): command substitutions not allowed in command position. Try var=(your-cmd) $var ...
try() {
^^
from sourcing file -
source: Error while reading file '<stdin>'
Cause
cmd_init! picks the syntax with fish? (try.rb:1281 on main):
shell = fish? ? 'fish' : 'bash'
fish? reads $SHELL first (try.rb:1646):
def fish?
shell = ENV["SHELL"].to_s
if shell.empty?
shell = (`ps c -p #{Process.ppid} -o 'ucomm='`.strip rescue "").to_s
end
shell.include?('fish')
end
The parent process check runs only when $SHELL is empty. $SHELL holds the login shell, not the shell that runs the command. Any user who starts fish from a different login shell gets bash syntax.
The existing fallback already works
The parent process check detects fish correctly. It is only unreachable. With $SHELL removed, try init returns the fish function:
❯ env -u SHELL try init "$HOME/tries" | head -2
function try
set -l out (/usr/bin/env ruby '.../try.rb' exec --path '/Users/samedwardes/tries' $argv 2>/dev/tty | string collect)
This also works through the Homebrew wrapper at /opt/homebrew/bin/try. The wrapper uses exec, so the Ruby process keeps fish as its parent.
Suggested fix
Check the parent process first in fish?, then fall back to $SHELL. The parent process is the shell that reads the output of try init.
A --shell flag on try init would also help. It makes the choice explicit and testable.
detect_shell (try.rb:1331), which try install uses, has the same $SHELL-first order. Reading $SHELL there is defensible, because install writes to the rc file of the login shell.
Workaround
env SHELL=(status fish-path) try init "$HOME/tries" | source
Environment
- try 1.10.1 (Homebrew). Confirmed on
main at try.rb:1281 and try.rb:1646.
- fish 4.8.1
- macOS 26.6.2, Apple Silicon
$SHELL=/bin/zsh, login shell zsh
What happens
I use fish, but my login shell is zsh, so
$SHELLis/bin/zsh.try initreturns the bash function instead of the fish function. The README line then fails:Cause
cmd_init!picks the syntax withfish?(try.rb:1281 onmain):fish?reads$SHELLfirst (try.rb:1646):The parent process check runs only when
$SHELLis empty.$SHELLholds the login shell, not the shell that runs the command. Any user who starts fish from a different login shell gets bash syntax.The existing fallback already works
The parent process check detects fish correctly. It is only unreachable. With
$SHELLremoved,try initreturns the fish function:This also works through the Homebrew wrapper at
/opt/homebrew/bin/try. The wrapper usesexec, so the Ruby process keeps fish as its parent.Suggested fix
Check the parent process first in
fish?, then fall back to$SHELL. The parent process is the shell that reads the output oftry init.A
--shellflag ontry initwould also help. It makes the choice explicit and testable.detect_shell(try.rb:1331), whichtry installuses, has the same$SHELL-first order. Reading$SHELLthere is defensible, becauseinstallwrites to the rc file of the login shell.Workaround
Environment
mainat try.rb:1281 and try.rb:1646.$SHELL=/bin/zsh, login shell zsh