bash: re-enable automatic bash shell detection

Bash shell detection was originally disabled in #1823 due to problems
with /bin/bash on macOS.

Apple distributes their own patched version of Bash 3.2 on macOS that
disables the POSIX-style $ENV-based startup path:

e5397a7e74/bash-3.2/shell.c (L1112-L1114)

This means we're unable to perform our automatic shell integration
sequence in this specific environment. Standard Bash 3.2 works fine.

Knowing this, we can re-enable bash shell detection by default unless
we're running "/bin/bash" on Darwin. We can safely assume that's the
unsupported Bash executable because /bin is non-writable on modern macOS
installations due to System Integrity Protection.

macOS users can either manually source our shell integration script
(which otherwise works fine with Apple's Bash) or install a standard
version of Bash from Homebrew or elsewhere.
This commit is contained in:
Jon Parise
2024-12-14 17:17:52 -05:00
parent fba10a442c
commit a0ce70651a
3 changed files with 29 additions and 10 deletions

View File

@@ -1,4 +1,5 @@
const std = @import("std");
const builtin = @import("builtin");
const Allocator = std.mem.Allocator;
const ArenaAllocator = std.heap.ArenaAllocator;
const EnvMap = std.process.EnvMap;
@@ -57,11 +58,21 @@ pub fn setup(
};
const result: ShellIntegration = shell: {
// For now, bash integration must be explicitly enabled via force_shell.
// Our automatic shell integration requires bash version 4 or later,
// and systems like macOS continue to ship bash version 3 by default.
// This approach avoids the cost of performing a runtime version check.
if (std.mem.eql(u8, "bash", exe) and force_shell == .bash) {
if (std.mem.eql(u8, "bash", exe)) {
// Apple distributes their own patched version of Bash 3.2
// on macOS that disables the ENV-based POSIX startup path.
// This means we're unable to perform our automatic shell
// integration sequence in this specific environment.
//
// If we're running "/bin/bash" on Darwin, we can assume
// we're using Apple's Bash because /bin is non-writable
// on modern macOS due to System Integrity Protection.
if (comptime builtin.target.isDarwin()) {
if (std.mem.eql(u8, "/bin/bash", command)) {
return null;
}
}
const new_command = try setupBash(
alloc_arena,
command,