【问题标题】:Bash script: after installation script following command isn't executed [closed]Bash脚本:安装脚本后不执行以下命令[关闭]
【发布时间】:2022-01-07 06:51:40
【问题描述】:

我只想编写一个小脚本来自动化我的fish 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 命令后,我的脚本中的以下命令都没有执行,它无法继续。有人对此有答案吗?

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

【问题讨论】:

  • 可能安装脚本尚未终止 - 是否正在等待输入?
  • 在某些情况下是的,但你们中没有人进行空白安装。
  • 我怀疑脚本中的某些内容正在从标准输入中读取,因此窃取了您本应作为命令读取的内容。但是我对fish语法还不够熟悉,无法说出如何解决这个问题。
  • 我会以... | fish --init-command='set fish_trace on' 运行它,看看它挂在哪里。
  • 由于您的问题似乎与 fish 而不是 bash 有关,因此我会将其正确标记为 fish 以吸引了解鱼的人(我不)。另外,我不明白你为什么坚持盲目地做curl .... | fish,而是先下载安装文件,然后打开一个fish shell,然后手动查看安装脚本后,在fish shell中运行它。

标签: bash shell fish


【解决方案1】:

如果我理解正确,您正在尝试做这样的事情:

#!/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+Ctrl 创建的 fish shell -- 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 替换安装程序运行的 fish shell,以便 oh-my-fish 可以在该 shell 实例中使用
  • &lt; /dev/tty 强制新的 shell 开始从终端读取输入。没有这个,脚本将退出,返回到您的调用脚本。安装程序的开发人员不希望发生这种情况 - 他们希望新的 fish 实例在安装程序运行后与 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 实例。

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

$ 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 退出最后一个fishbash ./wrapper.sh 将继续运行,输出:

Why doesn't this run?

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

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

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


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

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

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

【讨论】:

  • 感谢您非常好的解释!基于此,我可以完成我的安装脚本。
猜你喜欢
  • 2017-01-04
  • 1970-01-01
  • 1970-01-01
  • 2014-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-28
  • 2020-06-24
相关资源
最近更新 更多