Strange stack bash error: --: command not found
Strange stack bash error: --: command not found
我有一个非常简单的 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
多次次。
那么我该怎么做才能摆脱这个错误呢?
问题来了。第一行:
#!/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
与运行ning:
基本相同
$ bash hello.sh
设置 stack
路径等之后。
最终,然后,shell bash
运行正在编写您的脚本。 Bash 忽略第一行,因为它以 #
字符开头,表示 shell 注释。但是当 Bash 试图解释第二行时,就好像您在 shell 提示符下输入了以下命令:
$ -- stack exec bash
Bash 查找名为 --
到 运行 且参数为 stack exec bash
的程序,您会收到一条错误消息。不过,该脚本保持 运行ning,因此 echo
和 my-exec
行按预期得到 运行。
哇哦。
这是一种可能适合您的方法。您可以使用:
#!/bin/bash
exec stack exec bash <<EOF
echo Echo printing
./hello
EOF
此 shell 脚本将使用所谓的 "here doc" 调用 stack exec bash
,基本上将所有内容传递给 EOF
作为 [=26= 的脚本文件] 到 运行.
我有一个非常简单的 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
多次次。
那么我该怎么做才能摆脱这个错误呢?
问题来了。第一行:
#!/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
与运行ning:
基本相同$ bash hello.sh
设置 stack
路径等之后。
最终,然后,shell bash
运行正在编写您的脚本。 Bash 忽略第一行,因为它以 #
字符开头,表示 shell 注释。但是当 Bash 试图解释第二行时,就好像您在 shell 提示符下输入了以下命令:
$ -- stack exec bash
Bash 查找名为 --
到 运行 且参数为 stack exec bash
的程序,您会收到一条错误消息。不过,该脚本保持 运行ning,因此 echo
和 my-exec
行按预期得到 运行。
哇哦。
这是一种可能适合您的方法。您可以使用:
#!/bin/bash
exec stack exec bash <<EOF
echo Echo printing
./hello
EOF
此 shell 脚本将使用所谓的 "here doc" 调用 stack exec bash
,基本上将所有内容传递给 EOF
作为 [=26= 的脚本文件] 到 运行.