Shell 如何从命令行运行SWI Prolog?

Shell 如何从命令行运行SWI Prolog?,shell,command-line,prolog,executable,swi-prolog,Shell,Command Line,Prolog,Executable,Swi Prolog,有没有办法创建一个名为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

有没有办法创建一个名为
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
$
$ swipl -s example.pl -- foo bar baz
Example script
Called with [foo,bar,baz]
但是,有没有一种方法可以将直接脚本作为可执行文件运行呢

编辑

我还没能让它工作。以下是@Boris在其回答中的评论中提出的命令的输出:

$ 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安装swi prolog--使用libarchive
ISO指令使用自制软件安装swipl:。这应该行得通

:- initialization main.

main :-
  write('Hello World\n').
对不起,我跳过了最有趣的细节。下面是一个示例脚本,假设保存在~/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]
在script
main.pl
中,我使用了在没有管理员权限的情况下从源代码生成的swipl路径。SWI Prolog构建过程将bin和lib放在~/bin和~/lib下

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


我目前不确定文档页面是否是最新的软件状态。从中,以及我自己的重用努力,似乎命令行标志最近发生了变化…

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

$ 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).
这里的区别在于,除了通往swipl的路径外,shebang线上没有任何东西。其他一切都是使用指令完成的。在我的操作系统上,只有这样才有效

$ chmod u+x example.pl
$ example.pl foo bar baz
Example script
Called with [foo,bar,baz]
编辑 完全删除shebang行,而从命令行运行,可能会更干净:

$ swipl -q -f hello.pl -t main
Hello World
$
$ swipl -s example.pl -- foo bar baz
Example script
Called with [foo,bar,baz]

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

您可以使用
初始化/2

#!/path/to/swipl -q

:- initialization(main, program).

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

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

  • -
    程序
    导致Prolog在主出现故障或遇到异常时退出,并显示错误代码,而不是停留在REPL中

  • halt
    -使用退出代码0停止程序

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


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

如何从命令行运行此脚本?仍然收到与以前相同的错误:/,在执行
/hello.pl
时,在过去的两年中,这在邮件列表中出现了好几次。Jan Wielemaker最终建议不要从swipl可执行路径在shebang行appart上添加任何内容,这是出于兼容性的原因(至少我是这么理解的)。请看我的答案。谢谢Boris,感谢您关注这个问题。你在MacOS上使用bash吗?根据我的实验,罪魁祸首似乎是-s标志,与初始化脚本~/.plrcthis的交互很奇怪,我的错误仍然和以前一样,我认为出于某种原因,它将其视为shell文件。有什么想法吗?@LancePollard那么你现在的档案是什么?您是否可以在原始问题中添加脚本文件上的
ls-l
cat
的输出,以及
哪个swipl
swipl--version
?@我正在使用几种不同的Linux发行版(家庭、工作、笔记本电脑)。这个答案来自这里:lists.iai.uni-bonn.de/pipermail/swi-prolog/2013/011296。html@Boris:谢谢,我无法恢复Jan的信息,这澄清了整个问题。我已经将页面链接到了这个线程……是的,看起来你的操作系统确实不认可/尊重shebang行。放弃shebang并改为执行
$swipl example.pl
是完全不可接受的,如我的答案编辑中所示?(您可以尝试将
swipl example.pl
放在自己的脚本中,看看是否可以)。这不适用于Windows上的SWI Prolog(线程,64位,版本8.1.21)。@GuyCoder Windows上会发生什么?
Windows上会发生什么?
首先是
#/path/to/swipl-q
或类似结果导致
语法错误:应为运算符
。因此需要注释掉我们的Windows删除。
Windows上发生了什么?
main
未运行。你只得到了
?-
@GuyCoder,这是因为Windows不支持shebangs。请注意,OP要求为OSX提供一个解决方案,这是一个支持shebangs的类Unix系统。在Windows上,您必须删除shebang,您可能可以使用类似于
swipl-q./hello.pl
的东西来运行程序。