奇怪的堆栈重击错误: - :找不到命令

问题描述 投票:1回答:1

我有一个非常简单的haskell项目,只有可执行的my-exec。它所做的就是打印“Hello,world!”控制台。

我想创建脚本文件bin/setup.sh,它将运行我的可执行文件,也做一些echo

#!/usr/bin/env stack
-- stack exec bash

echo Echo printing
my-exec

当我跑它时,我得到了

$ ./bin/setup.sh
./bin/setup.sh: line 2: --: command not found
Echo printing
Hello, world!

我不明白这个文件的问题是什么,为什么它说--: command not found但仍然按预期工作。

我理解在这个简单的例子中我可以用更容易的形式编写它,但在我的实际情况下,我必须做10个非平凡的exec调用,并且不想多次复制stack exec

那么我该怎么做才能摆脱这个错误呢?

bash haskell haskell-stack
1个回答
6
投票

这是问题所在。第一行:

#!/usr/bin/env stack

由您的操作系统(例如,Linux内核)解释为指示应使用等效的shell命令调用脚本:

$ /usr/bin/env stack setup.sh

或者,因为env就在那里搜索stack的路径,相当于:

$ stack setup.sh

如果您手动运行,您将收到相同的错误。这是因为,当以这种方式调用stack时,它会读取指定的文件,搜索表单的一行:

-- stack blah blah whatever blah blah

在第一次#!线之后。通常,这一行看起来像:

-- stack --resolver lts-10.0 script

告诉堆栈运行脚本,就像运行shell命令一样:

$ stack --resolver lts-10.0 script hello.sh

它将hello.sh解释为Haskell程序,而不是shell脚本,但使用lts-10.0解析器运行它,一切都很好。

但是,你告诉stack使用命令stack exec bash,所以stack调用你的脚本相当于:

$ stack exec bash hello.sh

这与运行基本相同:

$ bash hello.sh

在设置stack路径之后等等。

最后,shell bash正在运行你的脚本。 Bash忽略第一行,因为它以#字符开头,表示shell注释。但是当Bash尝试解释第二行时,就好像你在shell提示符下输入了以下命令:

$ -- stack exec bash

Bash查找名为--的程序以使用参数stack exec bash运行,并且您收到错误消息。尽管如此,脚本仍在运行,因此echomy-exec行会按预期运行。

哇。

这是一种可能适合您的方式。您可以使用:

#!/bin/bash
exec stack exec bash <<EOF

echo Echo printing
./hello

EOF

这个shell脚本将使用所谓的“here doc”调用stack exec bash,基本上将所有内容传递给EOF作为stack exec bash运行的脚本文件。

© www.soinside.com 2019 - 2024. All rights reserved.