【问题标题】:How to run SWI-Prolog from the command line?如何从命令行运行 SWI-Prolog?
【发布时间】:2014-10-17 11:49:27
【问题描述】:

有没有办法像这样创建一个名为 hello.pl 的 prolog 脚本:

#!/usr/local/bin/swipl -q -s -t main

main:-
  write('Hello World\n').

并且能够像这样从终端运行它?

$ hello.pl
Hello World
$

当我这样做时,它会给我这个:

hello.pl: line 3: main:-: command not found
hello.pl: line 4: syntax error near unexpected token `'Hello World\n''
hello.pl: line 4: `  write('Hello World\n').'

我可以通过在命令行上写这个来让它工作:

$ swipl -q -f hello.pl -t main
Hello World
$

但是有没有办法将直接脚本作为可执行文件运行?

编辑

还不能让它工作。这是@Boris 在他的回答中在 cmets 中询问的命令的输出:

$ ls -l
total 8
-rwxr-xr-x  1 viatropos  staff  235 Aug 26 20:28 example.pl
$ cat example.pl
#!/usr/local/bin/swipl

:- set_prolog_flag(verbose, silent).

:- initialization main.

main :-
    format('Example script~n'),
    current_prolog_flag(argv, Argv),
    format('Called with ~q~n', [Argv]),
    halt.
main :-
    halt(1).
$ which swipl
/usr/local/bin/swipl
$ swipl --version
SWI-Prolog version 6.6.6 for x86_64-darwin13.1.0
$ ./example.pl
./example.pl: line 3: syntax error near unexpected token `('
./example.pl: line 3: `:- set_prolog_flag(verbose, silent).'
$

我在 Mac OSX 10.9.2 上,并通过 brew install swi-prolog --with-libarchive 使用自制软件安装了 swipl

【问题讨论】:

  • 是的,您的操作系统似乎确实无法识别/尊重 shebang 行。放弃shebang并改用$ swipl example.pl是完全不可接受的,如我的答案的编辑所示? (您可以尝试将swipl example.pl 放在它自己的脚本中,看看是否这样做)。

标签: shell command-line prolog executable swi-prolog


【解决方案1】:

ISO 指令:initialization。这应该可以。

:- initialization main.

main :-
  write('Hello World\n').

edit 抱歉,我跳过了最有趣的细节。这是一个示例脚本,假设保存在 ~/test/main.pl

#!/home/carlo/bin/swipl -f -q

:- initialization main.

main :-
  current_prolog_flag(argv, Argv),
  format('Hello World, argv:~w\n', [Argv]),
  halt(0).

并使其可执行

chmod +x ~/test/main.pl

然后我得到

~$ ~/test/main.pl
Hello World, argv:[]

~$ ~/test/main.pl as,dnj asdl
Hello World, argv:[as,dnj,asdl]

在脚本main.pl 中,我使用了在没有管理员权限的情况下从源代码构建产生的 swipl 路径。 SWI-Prolog 构建过程将 bin 和 lib 放在 ~/bin 和 ~/lib 下

注意:-f 标志禁止加载初始化 ~/.plrc,这可能是对执行进行更“严格控制”所必需的...

我目前不确定文档页面是否与当前 SW 状态保持同步。从some mailing list message,以及我自己重用thea 的努力,似乎命令行标志最近发生了变化......

【讨论】:

  • 如何从命令行运行它?在执行./hello.pl 时仍然出现与以前相同的错误:/
  • 这在过去 2 年中多次出现在邮件列表中。出于兼容性原因,Jan Wielemaker 最终建议不要在 swipl 可执行路径的 shebang 行 appart 上放置任何内容(至少这是我所理解的)。看我的回答。
【解决方案2】:

另一个答案或多或少是正确的,但是,它的工作方式可能取决于您的操作系统。显然,最便携的方法是:

$ cat example.pl
#!/path/to/your/swipl

:- set_prolog_flag(verbose, silent).

:- initialization main.

main :-
    format('Example script~n'),
    current_prolog_flag(argv, Argv),
    format('Called with ~q~n', [Argv]),
    halt.
main :-
    halt(1).

这里的区别在于shebang线上除了swipl的路径之外什么都没有。其他一切都是使用指令完成的。在我的操作系统上,只有这样才有效

$ chmod u+x example.pl
$ example.pl foo bar baz
Example script
Called with [foo,bar,baz]

编辑

完全删除shebang行可能更干净,而是从命令行运行:

$ swipl -s example.pl -- foo bar baz
Example script
Called with [foo,bar,baz]

同样,使用指令将main/0 设置为初始化目标可以让您不必在命令行上显式执行此操作。另一方面,从命令行调用 swipl 可以让您的操作系统找到可执行文件的位置,而不是在脚本中硬编码这些信息。

【讨论】:

  • 感谢 Boris 关注这个问题。你在 MacOS 上使用 bash 吗?根据我的实验,罪魁祸首似乎是 -s 标志,以及与初始化脚本的交互 ~/.plrc
  • 这很奇怪,我的仍然给我和以前一样的错误,我认为它出于某种原因将其视为 shell 文件。有什么想法吗?
  • @LancePollard 那么你现在的文件是什么?您能否将脚本文件中ls -lcat 的输出以及which swiplswipl --version 的输出添加到您的原始问题中?
  • @CapelliC 我正在使用几种不同的 Linux 发行版(家庭、工作、笔记本电脑)。这个答案来自这里:lists.iai.uni-bonn.de/pipermail/swi-prolog/2013/011296.html
  • @Boris:谢谢,我无法恢复 Jan 的消息,它澄清了整个问题。我已将documentation 页面链接到此线程...
【解决方案3】:

您可以使用initialization/2

#!/path/to/swipl -q

:- initialization(main, program).

main :-
    write("Hello"), nl,
    halt.

理由:

  • -q (--quiet) 用于抑制所有信息性消息,包括源自 SWI-Prolog 初始化文件 (~/.swiplrc) 的信息性消息。可以改用:- set_prolog_flag(verbose, silent).,但它不会抑制来自初始化文件的信息性消息。

  • :- initialization(main, program). - program 导致 Prolog 在main 失败或遇到异常时以错误代码退出,而不是留在 REPL。

  • halt - 以退出代码 0 停止程序。

以上假设您希望在运行程序之前加载初始化文件 (~/.swipl)。如果您不想加载初始化文件,请使用#!/path/to/swipl -f -q 作为shebang。这使脚本启动得更快。

(另外,请务必在运行脚本(./hello.pl)之前设置可执行位(chmod +x hello.pl))

【讨论】:

  • 这不适用于 Windows 上的 SWI-Prolog(线程化,64 位,版本 8.1.21)。
  • @GuyCoder 在 Windows 上会发生什么?
  • What happens on Windows? 首先是#!/path/to/swipl -qSyntax error: Operator expected 中的类似结果。所以这需要注释掉我们为 Windows 删除的内容。
  • What happens on Windows? main 未运行。你只会得到?-
  • @GuyCoder 这是因为 Windows 不支持 shebangs。请注意,OP 要求为 OS X 提供解决方案,这是一个支持 shebang 的类 Unix 系统。在 Windows 上,您必须删除 shebang,并且您可以使用类似 swipl -q ./hello.pl 的东西来运行程序。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 1970-01-01
相关资源
最近更新 更多