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

时间:2017-12-28 20:03:50

标签: bash haskell haskell-stack

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

我想创建一个脚本文件my-exec,它将运行我的可执行文件并执行一些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! 但仍然按预期工作。

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

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

1 个答案:

答案 0 :(得分: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的脚本文件来运行。