很明显,可以使用
#!/usr/bin/perl
在脚本的第一行中使用 shebang 表示法来定义解释器。然而,这预设了一个解释器,它忽略了以井号开始的行作为注释。如何使用没有此功能的解释器?
使用包装器删除第一行并使用文件的其余部分调用真正的解释器。它可能看起来像这样:
#!/bin/sh
# set your "real" interpreter here, or use cat for debugging
REALINTERP="cat"
tail -n +2 $1 | $REALINTERP
除此之外:在某些情况下,忽略有关第一行的错误消息可能是一种选择。
最后的手段:将解释器的注释字符的代码支持到内核中。
我认为第一行是由操作系统解释的。解释器将被启动并且脚本的名字作为它的第一个参数传递给脚本。以下脚本“first.myint”调用解释器“myinterpreter”,它是来自下面 C 程序的可执行文件。
#!/usr/local/bin/myinterpreter
% 1 #########
2 xxxxxxxxxxx
333
444
% the last comment
个人翻译示意图:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFERSIZE 256 /* input buffer size */
int
main ( int argc, char *argv[] )
{
char comment_leader = '%'; /* define the coment leader */
char *line = NULL;
size_t len = 0;
ssize_t read;
// char buffer[BUFFERSIZE];
// argv[0] : the name of this executable
// argv[1] : the name the script calling this executable via shebang
FILE *input; /* input-file pointer */
char *input_file_name = argv[1]; /* the script name */
input = fopen( input_file_name, "r" );
if ( input == NULL ) {
fprintf ( stderr, "couldn't open file '%s'; %s\n",
input_file_name, strerror(errno) );
exit (EXIT_FAILURE);
}
while ((read = getline(&line, &len, input)) != -1) {
if ( line[0] != comment_leader ) {
printf( "%s", line ); /* print line as a test */
}
else {
printf ( "Skipped a comment!\n" );
}
}
free(line);
if( fclose(input) == EOF ) { /* close input file */
fprintf ( stderr, "couldn't close file '%s'; %s\n",
input_file_name, strerror(errno) );
exit (EXIT_FAILURE);
}
return EXIT_SUCCESS;
} /* ---------- end of function main ---------- */
现在调用脚本(之前可执行)并查看输出:
...~> ./first.myint
#!/usr/local/bin/myinterpreter
Skipped a comment!
2 xxxxxxxxxxx
333
444
Skipped a comment!
我让它工作了。我特别感谢 holgero 的尾巴技巧
tail -n +2 $1 | $REALINTERP
那,并在堆栈溢出上找到这个答案使得它成为可能:
如何将 linux shell 脚本编译为独立的可执行文件 *binary*(即不仅仅是 chmod 755)?
“完全满足我需求的解决方案是 SHC - 免费工具”
SHC 是一个 shell 到 C 的翻译器,见这里:
http://www.datsi.fi.upm.es/~frosal/
所以我写道polyscript.sh
:
$ cat polyscript.sh
#!/bin/bash
tail -n +2 $1 | poly
我用 shc 编译它,然后用 gcc 编译:
$ shc-3.8.9/shc -f polyscript.sh
$ gcc -Wall polyscript.sh.x.c -o polyscript
现在,我能够创建第一个用 ML 编写的脚本:
$ cat smlscript
#!/home/gergoe/projects/shebang/polyscript $0
print "Hello World!"
而且,我能够运行它:
$ chmod u+x smlscript
$ ./smlscript
Poly/ML 5.4.1 Release
> > # Hello World!val it = (): unit
Poly 没有抑制编译器输出的选项,但这不是问题。按照 fgm 的建议,直接在 C 中编写 polyscript 可能会很有趣,但这可能不会让它更快。
所以,这就是这么简单。我欢迎任何意见。