如何用shebang定义脚本解释器

时间:2013-03-27 17:13:13

标签: linux bash unix sml

很明显,人们可以使用

#!/usr/bin/perl
用于定义解释器的脚本的第一行中的shebang表示法。但是,这预先假定一个解释器忽略了散列标记起始行作为注释。如何使用没有此功能的解释器?

3 个答案:

答案 0 :(得分:2)

我认为第一行是由操作系统解释的。 将启动解释器,并将脚本的名称作为其第一个参数传递给脚本。 以下脚本'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!

答案 1 :(得分:2)

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

#!/bin/sh

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

tail -n +2 $1 | $REALINTERP

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

最后的手段:代码支持解释器的注释char进入内核。

答案 2 :(得分:0)

我做到了。我特别感谢holgero的尾巴选择技巧

tail -n +2 $1 | $REALINTERP

那,在Stack溢出上找到这个答案就可以了:

How to compile a linux shell script to be a standalone executable *binary* (i.e. not just e.g. chmod 755)?

“完全符合我需求的解决方案将是SHC - 免费工具”

SHC是C语言翻译的shell,见这里:

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中编写多维数据集可能会很有趣,但可能不会使它更快。

所以,这是多么简单。我欢迎任何评论。

相关问题