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

vro*_*911 1 bash haskell haskell-stack

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

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

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

echo Echo printing
my-exec
Run Code Online (Sandbox Code Playgroud)

当我跑它时,我得到了

$ ./bin/setup.sh
./bin/setup.sh: line 2: --: command not found
Echo printing
Hello, world!
Run Code Online (Sandbox Code Playgroud)

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

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

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

K. *_*uhr 6

这是问题所在.第一行:

#!/usr/bin/env stack
Run Code Online (Sandbox Code Playgroud)

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

$ /usr/bin/env stack setup.sh
Run Code Online (Sandbox Code Playgroud)

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

$ stack setup.sh
Run Code Online (Sandbox Code Playgroud)

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

-- stack blah blah whatever blah blah
Run Code Online (Sandbox Code Playgroud)

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

-- stack --resolver lts-10.0 script
Run Code Online (Sandbox Code Playgroud)

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

$ stack --resolver lts-10.0 script hello.sh
Run Code Online (Sandbox Code Playgroud)

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

但是,您已经告诉stack要使用该命令stack exec bash,因此stack调用您的脚本相当于:

$ stack exec bash hello.sh
Run Code Online (Sandbox Code Playgroud)

这与运行基本相同:

$ bash hello.sh
Run Code Online (Sandbox Code Playgroud)

设置stack路径后等.

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

$ -- stack exec bash
Run Code Online (Sandbox Code Playgroud)

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

哇.

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

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

echo Echo printing
./hello

EOF
Run Code Online (Sandbox Code Playgroud)

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