7

很明显,可以使用

#!/usr/bin/perl

在脚本的第一行中使用 shebang 表示法来定义解释器。然而,这预设了一个解释器,它忽略了以井号开始的行作为注释。如何使用没有此功能的解释器?

4

3 回答 3

4

使用包装器删除第一行并使用文件的其余部分调用真正的解释器。它可能看起来像这样:

#!/bin/sh

# set your "real" interpreter here, or use cat for debugging
REALINTERP="cat"

tail -n +2 $1 | $REALINTERP

除此之外:在某些情况下,忽略有关第一行的错误消息可能是一种选择。

最后的手段:将解释器的注释字符的代码支持到内核中。

于 2013-03-27T21:55:31.680 回答
3

我认为第一行是由操作系统解释的。解释器将被启动并且脚本的名字作为它的第一个参数传递给脚本。以下脚本“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!
于 2013-03-27T20:09:32.620 回答
1

我让它工作了。我特别感谢 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 可能会很有趣,但这可能不会让它更快。

所以,这就是这么简单。我欢迎任何意见。

于 2013-03-29T09:00:47.527 回答