From 7ca78e717892c56efa75b16a489075d6c30033c7 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Sat, 22 Nov 2025 16:13:28 +0100 Subject: [PATCH] share/functions: fix path to /bin/sh on android As mentioned in https://github.com/fish-shell/fish-shell/issues/12055#issuecomment-3554869126 > instances of `/bin/sh` as freestanding commands within `.fish` > files are most likely not automatically handled by `termux-exec` and > This topic is complicated by the fact that some Android ROMs _do_ > contain real `/bin/sh` files Core uses /system/bin/sh on Android. Let's do the same from script (even if /bin/sh exists), for consistency. --- share/functions/__fish_apropos.fish | 3 ++- share/functions/__fish_cached.fish | 2 +- share/functions/__fish_posix_shell.fish | 9 +++++++++ share/functions/fish_git_prompt.fish | 3 ++- share/functions/fish_update_completions.fish | 3 ++- share/functions/help.fish | 3 ++- src/fork_exec/mod.rs | 1 + tests/checks/__fish_posix_shell.fish | 5 +++++ 8 files changed, 24 insertions(+), 5 deletions(-) create mode 100644 share/functions/__fish_posix_shell.fish create mode 100644 tests/checks/__fish_posix_shell.fish diff --git a/share/functions/__fish_apropos.fish b/share/functions/__fish_apropos.fish index d826be325..7c4084326 100644 --- a/share/functions/__fish_apropos.fish +++ b/share/functions/__fish_apropos.fish @@ -42,7 +42,8 @@ if test (__fish_uname) = Darwin if test $age -ge $max_age test -d "$dir" || mkdir -m 700 -p $dir - /bin/sh -c '( "$@" ) >/dev/null 2>&1 /dev/null 2>&1 $cache_file || rm $cache_file 2>/dev/null diff --git a/share/functions/__fish_posix_shell.fish b/share/functions/__fish_posix_shell.fish new file mode 100644 index 000000000..4cffd1d41 --- /dev/null +++ b/share/functions/__fish_posix_shell.fish @@ -0,0 +1,9 @@ +# localization: skip(private) +function __fish_posix_shell + # NOTE: this is currently duplicated with PATH_BSHELL + if status build-info | string match -rq '^Target( \(and host\))?: .*-android(eabi)?$' + echo /system/bin/sh + else + echo /bin/sh + end +end diff --git a/share/functions/fish_git_prompt.fish b/share/functions/fish_git_prompt.fish index e050dba09..191670ea8 100644 --- a/share/functions/fish_git_prompt.fish +++ b/share/functions/fish_git_prompt.fish @@ -180,7 +180,8 @@ if string match -q Darwin -- (__fish_uname) && string match -q /usr/bin/git -- ( else # git is installed, but on the first run it may be very slow as xcrun needs to populate the cache. # Kick it off in the background to populate the cache. - /bin/sh -c '( /usr/bin/git --version; touch /tmp/__fish_git_ready ) >/dev/null 2>&1 &' + set -l sh (__fish_posix_shell) + $sh -c '( /usr/bin/git --version; touch /tmp/__fish_git_ready ) >/dev/null 2>&1 &' function __fish_git_prompt_ready path is /tmp/__fish_git_ready || return 1 # git is ready, erase the function. diff --git a/share/functions/fish_update_completions.fish b/share/functions/fish_update_completions.fish index 160a6a3a2..46e090cba 100644 --- a/share/functions/fish_update_completions.fish +++ b/share/functions/fish_update_completions.fish @@ -26,7 +26,8 @@ function fish_update_completions --description "Update man-page based completion # Orphan the job so that it continues to run in case of an early exit (#6269) # Note that some distros split the manpage completion script out (#7183). # In that case, we silence Python's failure. - /bin/sh -c ' + set -l sh (__fish_posix_shell) + $sh -c ' c=$(cat) ( printf %s "$c" | "$@" ) >/dev/null 2>&1 & ' -- $update_argv $argv diff --git a/share/functions/help.fish b/share/functions/help.fish index eb21e7172..057d7b3ac 100644 --- a/share/functions/help.fish +++ b/share/functions/help.fish @@ -228,7 +228,8 @@ chromium-browser # The space before the /c is to prevent msys2 from expanding it to a path $fish_browser " /c" start $page_url else if contains -- $fish_browser[1] $graphical_browsers - /bin/sh -c '( "$@" ) &' -- $fish_browser $page_url + set -l sh (__fish_posix_shell) + $sh -c '( "$@" ) &' -- $fish_browser $page_url else $fish_browser $page_url end diff --git a/src/fork_exec/mod.rs b/src/fork_exec/mod.rs index 4df8daf6f..d775db520 100644 --- a/src/fork_exec/mod.rs +++ b/src/fork_exec/mod.rs @@ -24,6 +24,7 @@ pub fn blocked_signals_for_job(job: &Job, sigmask: &mut libc::sigset_t) -> bool } // Bravely define _PATH_BSHELL. On practice it's /bin/sh everywhere, except on Android. +// NOTE: this is currently duplicated in __fish_posix_shell. #[cfg(not(target_os = "android"))] pub static PATH_BSHELL: &[u8] = b"/bin/sh\0"; diff --git a/tests/checks/__fish_posix_shell.fish b/tests/checks/__fish_posix_shell.fish new file mode 100644 index 000000000..117d248b0 --- /dev/null +++ b/tests/checks/__fish_posix_shell.fish @@ -0,0 +1,5 @@ +# RUN: %fish %s + +set -l sh (__fish_posix_shell) +command -v $sh +# CHECK: {{.*/sh}}