fix(bash): use `eval` instead of a procsub for the POSIX mode (#5020)

fix(bash): use eval instead of a procsub for the POSIX mode
This commit is contained in:
Koichi Murase 2024-04-02 17:45:02 +09:00 committed by GitHub
parent 55e11a42e5
commit 0f859e8b61
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 26 additions and 24 deletions

View File

@ -9,11 +9,11 @@ use which::which;
shell. This command evaluates a more complicated script using `source` and shell. This command evaluates a more complicated script using `source` and
process substitution. process substitution.
Directly using `eval` on a shell script causes it to be evaluated in Directly using `eval` on a shell script without proper quoting causes it to be
a single line, which sucks because things like comments will comment out the evaluated in a single line, which sucks because things like comments will
rest of the script, and you have to spam semicolons everywhere. By using comment out the rest of the script, and you have to spam semicolons
source and process substitutions, we make it possible to comment and debug everywhere. By using source and process substitutions, we make it possible to
the init scripts. comment and debug the init scripts.
In the future, this may be changed to just directly evaluating the initscript In the future, this may be changed to just directly evaluating the initscript
using whatever mechanism is available in the host shell--this two-phase solution using whatever mechanism is available in the host shell--this two-phase solution
@ -106,8 +106,13 @@ pub fn init_stub(shell_name: &str) -> io::Result<()> {
match shell_basename { match shell_basename {
"bash" => print!( "bash" => print!(
/* /* We now use the following bootstrap:
* The standard bash bootstrap is: * `eval -- "$(starship init bash --print-full-init)"`
* which works in any version of Bash from 3.2 to the latest
* version and also works in the POSIX mode.
*
* ----
* Historically, the standard bash bootstrap was:
* `source <(starship init bash --print-full-init)` * `source <(starship init bash --print-full-init)`
* *
* Unfortunately there is an issue with bash 3.2 (the MacOS * Unfortunately there is an issue with bash 3.2 (the MacOS
@ -129,28 +134,25 @@ pub fn init_stub(shell_name: &str) -> io::Result<()> {
* with the standard bootstrap, whereas bash 4.1 appears to be * with the standard bootstrap, whereas bash 4.1 appears to be
* consistently compatible. * consistently compatible.
* *
* The upshot of all of this, is that we will use the standard * We had been using the standard bootstrap whenever the bash
* bootstrap whenever the bash version is 4.1 or higher. Otherwise, * version is 4.1 or higher. Otherwise, we fell back to the
* we fall back to the `/dev/stdin` solution. * `/dev/stdin` solution.
*
* However, process substitutions <(...) are not supported in the
* POSIX mode of Bash <= 5.0, so we switch to the approach with
* `eval -- "$(...)"`. The reason for not using `eval` seems to be
* explained at the top of this file, i.e., the script will be
* evaluated as if it is a single line, but that is caused by an
* improper quoting.
* *
* More background can be found in these pull requests: * More background can be found in these pull requests:
* https://github.com/starship/starship/pull/241 * https://github.com/starship/starship/pull/241
* https://github.com/starship/starship/pull/278 * https://github.com/starship/starship/pull/278
* https://github.com/starship/starship/issues/1674
* https://github.com/starship/starship/pull/5020
* https://github.com/starship/starship/issues/5382
*/ */
r#" r#"eval -- "$({0} init bash --print-full-init)""#,
__main() {{
local major="${{BASH_VERSINFO[0]}}"
local minor="${{BASH_VERSINFO[1]}}"
if ((major > 4)) || {{ ((major == 4)) && ((minor >= 1)); }}; then
source <({0} init bash --print-full-init)
else
source /dev/stdin <<<"$({0} init bash --print-full-init)"
fi
}}
__main
unset -f __main
"#,
starship.sprint_posix()? starship.sprint_posix()?
), ),
"zsh" => print_script(ZSH_INIT, &starship.sprint_posix()?), "zsh" => print_script(ZSH_INIT, &starship.sprint_posix()?),