Bash 脚本:安装脚本后不执行以下命令

Bash script: after installation script following command isn't executed

我只想编写一个小脚本来自动安装我的鱼 shell。该安装的一部分包括调用官方 omf oh-my-fish 安装程序脚本(curl ...)。

#!/bin/bash

sudo apt update \
&& sudo apt install fish -y \
&& sudo chsh -s /usr/bin/fish \
&& curl https://raw.githubusercontent.com/oh-my-fish/oh-my-fish/master/bin/install | fish \
&& fish -c "omf install bira" \
&& echo -e "\nDone.\n"

不幸的是,我脚本中以下命令的curl install命令none执行后,无法继续。有人对此有答案吗?

更新:很抱歉对我的问题的描述不准确。我已经编辑了我的问题,我希望现在每个人都能更好地理解它。如果我的描述还不够好,请告诉我,我会重新编辑。

如果我理解正确的话,你正试图做这样的事情:

#!/usr/bin/env bash
curl https://raw.githubusercontent.com/oh-my-fish/oh-my-fish/master/bin/install | fish 
echo "Why doesn't this run?"
echo "Do something else!"

但是最后两行没有执行,对吧?

简答

我能想到的几种方案:

  • 运行 带有 --noninteractive 标志的 oh-my-fish 安装程序使用进程替换:

    fish <(curl https://raw.githubusercontent.com/oh-my-fish/oh-my-fish/master/bin/install) --noninteractive
    
  • 退出 oh-my-fish 通过 exitCtrl+ 创建的鱼 shell Ctrl -- 您的 bash 脚本的其余部分应在该点执行。

更多详情

问题是 oh-my-fish 安装脚本最后包含这个“清理”部分:

# We made it!
say "Installation successful!"

# Open a brand new shell if we are in interactive mode.
set -q NONINTERACTIVE
  or exec fish < /dev/tty

最后一行做了两件事:

  • exec 用新的 fish shell 替换了安装程序正在 运行 加入的鱼 shell,这样 oh-my-fish 就是准备好在 shell 实例中使用
  • < /dev/tty 强制新的 shell 开始从终端读取输入。如果没有这个,脚本将退出,returning 到您的调用脚本。安装程序的开发人员不希望发生这种情况 - 他们希望新的 fish 实例在安装程序 运行s.
  • 之后与 oh-my-fish 一起“准备就绪”

无论如何,该组合将阻止任何“包含”脚本继续执行,直到新的 fish 实例终止。

您可以在 MRE:

中看到这一点

test_exec.fish:

#!/usr/bin/fish
exec fish < /dev/tty
echo "This never runs"

wrapper.sh:

#!/usr/bin/env bash
cat test_exec.fish | fish
echo "Why doesn't this run?"

执行 wrapper.sh 没有输出,因为 test_exec.fish 创建了一个从终端读取的新 fish 实例。

但是,如果您 运行 ps 在 运行 宁 ./wrapper.sh 之后,您可以看到幕后还有更多事情要做:

$ ps
  PID TTY          TIME CMD
 1494 pts/1    00:00:00 fish
 1751 pts/1    00:00:00 bash
 1753 pts/1    00:00:00 fish
 1904 pts/1    00:00:00 ps

第一个fish(pid 1494,此处供参考)是您开始的地方; bash 仍然是 运行 宁 wrapper.sh 脚本;最后一个 fish 是我们强制从 /dev/tty 读取的一个读数,现在正在读取和执行 ps.

如上所述,如果您使用 exitCtrl+Ctrl 退出最后一个 fish ,bash ./wrapper.sh会继续运行ning,输出:

Why doesn't this run?

然后会自动退出脚本/bash和return原来的fish(pid 1494):

$ ps
  PID TTY          TIME CMD
 1494 pts/1    00:00:00 fish
 1958 pts/1    00:00:00 ps

请注意,至少在我的系统上,tty 重定向会导致一些问题,例如损坏的 Backspace 需要使用终端 [=45] 进行更正=]命令。


或者,我们可以通过使用 --noninteractive 标志调用安装程序来完全阻止 exec fish < /dev/tty 运行ning。

为了将标志传递给您正在下载的脚本,我们使用进程替换。这将替换:

curl https://raw.githubusercontent.com/oh-my-fish/oh-my-fish/master/bin/install | fish

fish <(curl https://raw.githubusercontent.com/oh-my-fish/oh-my-fish/master/bin/install) --noninteractive

请注意,如果您是从 fish 脚本而不是 bash 脚本调用它,则语法为:

fish (curl https://raw.githubusercontent.com/oh-my-fish/oh-my-fish/master/bin/install | psub) --noninteractive