Native shebang: Difference between revisions

m
(added langur language example)
 
(20 intermediate revisions by 10 users not shown)
Line 55:
Also note that this ".so" will only be generated if the ".a68" source file
has been touched.
'''File: echo.a68'''<langsyntaxhighlight lang="algol68">#!/usr/bin/a68g --script #
# -*- coding: utf-8 -*- #
 
STRING ofs := "";
FOR i FROM 4 TO argc DO print((ofs, argv(i))); ofs:=" " OD</langsyntaxhighlight>
'''Test Execution:'''
<pre>
Line 68:
Hello, world!
</pre>
 
=={{header|Arturo}}==
Arturo is a scripting language and does not compile to a binary.
<syntaxhighlight lang="rebol">#!/usr/bin/env arturo
print "Hello from Arturo!"</syntaxhighlight>
 
{{out}}
 
<pre>$> ./native_shebang.art
Hello from Arturo!</pre>
 
=={{header|C}}==
Line 76 ⟶ 86:
 
'''File: script_gcc.c'''
<langsyntaxhighlight lang="c">#!/usr/local/bin/script_gcc.sh
/* Optional: this C code initially is-being/can-be boot strapped (compiled) using bash script_gcc.sh */
#include <errno.h>
Line 200 ⟶ 210:
perror(STRCAT(binpath, ": executable not available", ENDCAT));
exit(errno);
}</langsyntaxhighlight>
 
'''Test Source File: echo.c'''
<langsyntaxhighlight lang="c">#!/usr/local/bin/script_gcc.c
#include <stdio.h>
#include <string.h>
Line 216 ⟶ 226:
putchar('\n');
exit(EXIT_SUCCESS);
}</langsyntaxhighlight>
 
'''Test Execution:'''
Line 229 ⟶ 239:
===2nd version. Pure C, no extra bash script===
'''File: script_gcc.c'''
<langsyntaxhighlight lang="c">/*
* rosettacode.org: Native shebang
*
Line 400 ⟶ 410:
return !fprintf(stderr, "%s : executable not available\n", exec_path) | ENOENT;
}
</syntaxhighlight>
</lang>
 
'''Test Source File: echo.c'''
<langsyntaxhighlight lang="c">#!/usr/local/bin/script_gcc
/*
* note, any additional libs or include paths would have params added after
Line 421 ⟶ 431:
putchar('\n');
exit(EXIT_SUCCESS);
}</langsyntaxhighlight>
 
'''Test Execution:'''
Line 431 ⟶ 441:
Hello, world!
</pre>
 
=={{header|Forth}}==
Such functionality can be added easily by the following definition:
<syntaxhighlight lang="text">: #! [COMPILE] \ ; immediate</syntaxhighlight>
Some Forth compilers - like 4tH or Gforth - support this functionality out of the box.
This example program works as advertised:
<syntaxhighlight lang="text">#! /usr/local/bin/4th cxq
argn 1 ?do i args type space loop cr</syntaxhighlight>
 
=={{header|Free Pascal}}==
Since FPC (FreePascal compiler) version 2.6.0 the distribution – e.g. the Debian or FreeBSD packages <tt>fpc-utils</tt> – come with the program <tt>instantfpc(1)</tt>, or <tt>ifpc(1)</tt> for short.
The program fulfills this task’s specifications, plus other goodies.
The sources are available in [https://svngitlab.com/freepascal.org/cgifpc/source/-bin/viewvc.cgiblob/trunkrelease_3_2_0/utils/instantfpc/instantfpc.pas?view=markup <tt>trunk/utils/instantfpc/instantfpc.pas</tt>] and are not repeated here.
See the [https://wiki.freepascal.org/InstantFPC FreePascal wiki for <tt>ifpc</tt> usage].
 
Line 446 ⟶ 464:
 
The following works fine on Ubuntu 16.04.
<langsyntaxhighlight lang="go">///usr/bin/env go run echo.go "$@"; exit
package main
 
Line 458 ⟶ 476:
fmt.Println(os.Args[1])
}
}</langsyntaxhighlight>
 
{{out}}
Line 469 ⟶ 487:
As no compiling versions of J are currently available, the binaries are trivially empty and we shall store them in the empty path. We shall use /usr/local/bin/ijconsole (which was compiled using a C compiler) as the J interpreter, and <code>echo each ARGV</code> as our sample code:
 
<langsyntaxhighlight Jlang="j">#!/usr/local/bin/ijconsole
echo each ARGV</langsyntaxhighlight>
 
=={{header|jq}}==
Line 484 ⟶ 502:
 
'''Example 1:'''
<langsyntaxhighlight lang="sh">$ cat echo.foo
#!/usr/bin/env/jq -M -n -r -f
"Klaatu barada nikto!"</langsyntaxhighlight>
 
 
Line 500 ⟶ 518:
 
'''Example 2:'''
<langsyntaxhighlight lang="sh">$ cat echo.foo
#!/usr/bin/env/jq -M -n -r -f
$x</langsyntaxhighlight>
{{out}}
<langsyntaxhighlight lang="sh">$ ./echo.foo --arg x "Hello, world!"
Hello, world!</langsyntaxhighlight>
 
=={{header|Julia}}==
usage: ./thisfile.jl "hello"
<langsyntaxhighlight lang="julia">#!/usr/local/bin/julia
 
# Put the Julia code below this line. It will be compiled and run.
Line 516 ⟶ 534:
println(ARGS)
 
</langsyntaxhighlight>{{out}}
<pre>
_
Line 530 ⟶ 548:
 
=={{header|langur}}==
Langur uses a hash mark to start single line comments, so a shebang is not a problem, as the compiler will ignore it.
The _args system variable contains an array of strings of all arguments passed.
 
'''File: echo.langur'''
<langsyntaxhighlight lang="langur">#!/usr/bin/langur
writeln join " ", _args[1]</langsyntaxhighlight>
 
'''Usage:'''
<pre>./echo.langur "hello, peeps!"people</pre>
 
{{out}}
<pre>hello, peeps!people</pre>
 
=={{header|Nim}}==
===Using env===
Uses env -S to split up the commandline parameters,which is maybe cheating
but apart from that housekeeping this ticks all the boxes:
* it compiles the source code to an executable, if and only if it has changed
* it then runs that executable with the supplied arguments
 
'''File: nativeshebang.nim'''
<syntaxhighlight lang="nim">#!/usr/bin/env -S nim c -r --hints:off
import os,strutils
echo commandLineParams().join(" ")</syntaxhighlight>
'''Usage:'''
<pre>./nativeshebang.nim hello, world</pre>
{{out}}
<pre>hello, world</pre>
===Using a nim.cfg and/or nim r===
Alternatively, accept all the compiler messages, or create a nim.cfg that silences them:
 
'''File: nim.cfg'''
<syntaxhighlight lang="nim">--hints:off</syntaxhighlight>
'''File: nativeshebang2.nims'''
<syntaxhighlight lang="nim">#!nim r
import os,strutils
echo commandLineParams().join(" ")</syntaxhighlight>
'''Usage:'''
<pre>./nativeshebang2.nim hello, world</pre>
{{out}}
<pre>hello, world</pre>
 
=={{header|OCaml}}==
Line 546 ⟶ 593:
 
'''File: echo.ml'''
<langsyntaxhighlight lang="ocaml">#! /usr/bin/env ocaml
 
let () =
let argl = Array.to_list Sys.argv in
print_endline (String.concat " " (List.tl argl))</langsyntaxhighlight>
{{out}}
<pre>
Line 568 ⟶ 615:
 
'''File: echo.pl'''
<langsyntaxhighlight lang="perl">#!/usr/bin/perl
print "@ARGV\n";
</syntaxhighlight>
</lang>
 
'''Usage:'''
Line 581 ⟶ 628:
</pre>
 
=={{header|Perl 6Phix}}==
Phix is a hybrid interpreter/compiler, so a shebang adds little value anyway, however should the first
Perl 6 is not installed by default on most systems and does not have a default install directory, so the path will vary by system.
line of the main file start with #! it is ignored/skipped. The only difference between interpretation
{{works with|Rakudo|2015-11-20}}
and compilation, apart from the executable file, is a -c flag on the command line, which I recommend
 
omitting unless it proves helpful or necessary. Example (quietly ignored by pwa/p2js, and Phix in general):
'''File: echo.p6'''
<langsyntaxhighlight perl6lang="phix">#!/path/to/perl6phix</syntaxhighlight>
You can also invoke the compiler directly as follows
put @*ARGS;</lang>
<!--<syntaxhighlight lang="phix">(phixonline)-->
 
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- (system_exec)</span>
'''Usage:'''
<span style="color: #004080;">string</span> <span style="color: #000000;">sourcefile</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"test.exw"</span><span style="color: #0000FF;">,</span>
<pre>
<span style="color: #000000;">interpreter</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">get_interpreter</span><span style="color: #0000FF;">(</span><span style="color: #004600;">true</span><span style="color: #0000FF;">),</span>
./echo.p6 Hello, world!
<span style="color: #000000;">cmd</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%s %s"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">interpreter</span><span style="color: #0000FF;">,</span><span style="color: #000000;">sourcefile</span><span style="color: #0000FF;">})</span>
</pre>
<span style="color: #004080;">integer</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">system_exec</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cmd</span><span style="color: #0000FF;">)</span>
{{out}}
<!--</syntaxhighlight>-->
<pre>
See also demo/capture_console.exw which redirects stdin/out/err while interpreting a child process.
Hello, world!
</pre>
 
=={{header|Python}}==
Line 606 ⟶ 652:
 
'''File: echo.py'''
<langsyntaxhighlight lang="python">#!/path/to/python
# Although `#!/usr/bin/env python` may be better if the path to python can change
 
import sys
print " ".join(sys.argv[1:])</langsyntaxhighlight>
 
'''Usage:'''
Line 636 ⟶ 682:
 
File <tt>native-shebang.rkt</tt> contains the following:
<langsyntaxhighlight lang="racket">#! /usr/local/racket-6.1/bin/racket
#lang racket
(displayln "hello")</langsyntaxhighlight>
 
My directory contains only this:
Line 664 ⟶ 710:
hello</pre>
(although it's hard to prove)
 
=={{header|Raku}}==
(formerly Perl 6)
 
Raku is not installed by default on most systems and does not have a default install directory, so the path will vary by system.
{{works with|Rakudo|2020.02}}
 
'''File: echo.p6'''
<syntaxhighlight lang="raku" line>#!/path/to/raku
put @*ARGS;</syntaxhighlight>
 
'''Usage:'''
<pre>
./echo.p6 Hello, world!
</pre>
{{out}}
<pre>
Hello, world!
</pre>
 
=={{header|REXX}}==
===Unix shebang===
Using e.g. Regina open source REXX interpreter
<langsyntaxhighlight lang="rexx">
#!/usr/local/bin/regina
/* Echo the command line argument */
say arg(1)
</syntaxhighlight>
</lang>
 
===ARexx===
Under AmigaOS, the obligatory REXX starting comment /* is recognised as a shebang of its own, automatically causing the file to be parsed by ARexx as long as the file's script flag is set.
<langsyntaxhighlight lang="rexx">
/* Echo the command line argument */
say arg(1)
</syntaxhighlight>
</lang>
 
=={{header|Ruby}}==
Line 686 ⟶ 751:
=={{header|Sidef}}==
Sidef is a scripting language and does not compile to a binary.
<langsyntaxhighlight lang="ruby">#!/usr/bin/sidef
say ARGV.join(" ")</langsyntaxhighlight>
 
{{out}}
Line 699 ⟶ 764:
 
'''File: echo.swift'''
<langsyntaxhighlight lang="swift">#!/usr/bin/swift
 
import Foundation
 
print(Process.arguments[1..<Process.arguments.count].joinWithSeparator(" "))
</syntaxhighlight>
</lang>
 
'''Usage:'''
 
<langsyntaxhighlight lang="bash">
./echo.swift Hello, world!
</syntaxhighlight>
</lang>
 
{{Out}}
Line 723 ⟶ 788:
 
'''File: echo.sh'''
<langsyntaxhighlight lang="sh">#!/bin/sh
echo "$@"</langsyntaxhighlight>
 
'''Usage:'''
Line 741 ⟶ 806:
 
'''File: script_gcc.sh'''
<langsyntaxhighlight lang="bash">#!/bin/bash
 
# Actual shebang when using bash:
Line 804 ⟶ 869:
echo "$binpath: executable not available" 1>&2
exit $ENOENT
fi</langsyntaxhighlight>
'''Test Source File: echo.c'''
<langsyntaxhighlight lang="c">#!/usr/local/bin/script_gcc.sh
#include <stdio.h>
#include <string.h>
Line 819 ⟶ 884:
putchar('\n');
exit(EXIT_SUCCESS);
}</langsyntaxhighlight>
 
'''Test Execution:'''
Line 828 ⟶ 893:
<pre>
Hello, world!
</pre>
 
=={{header|V (Vlang)}}==
<syntaxhighlight lang="Vlang">
$ cat file.v
#!/usr/local/bin/v run
println('hello')
 
$ chmod 755 file.v
$ ./file.v
============ running ./file ============
hello
</syntaxhighlight>
V also knows to compile & run .vsh files immediately, so you do not need a separate step to compile them.
 
An example deploy.vsh:
<syntaxhighlight lang="Vlang">
#!/usr/bin/env -S v
 
// Note: The shebang line above, associates the .vsh file to V on Unix-like systems,
// so it can be run just by specifying the path to the .vsh file...
</syntaxhighlight>
 
=={{header|Wren}}==
Normally, Process.arguments[0] would return the (first) command line argument but here we need to use Process.arguments[1] because the first argument passed to Wren's command line interpreter is ''./native_shebang.wren''.
<syntaxhighlight lang="wren">#!/bin/wren native_shebang.wren
import "os" for Process
System.print(Process.arguments[1])</syntaxhighlight>
 
{{out}}
<pre>
$ chmod +x native_shebang.wren
$ ./native_shebang.wren "Hello world!"
Hello world!
</pre>
 
Line 834 ⟶ 933:
 
Since the #! parsing is done by a compiler front end and was designed to be used from the command line, we'll do that by forking zkl to compile the source if it is newer than the binary.
<langsyntaxhighlight lang="zkl">#!/home/craigd/Bin/zkl
// This file: nativeShebang.zkl, compiles to nativeShebang.zsc
// zkl --#! . -c nativeShebang -o.
Line 854 ⟶ 953:
 
////////////// the script:
println("Hello world!");</langsyntaxhighlight>
{{out}}
<pre>
Line 888 ⟶ 987:
#yep, new binary generated
</pre>
 
{{omit from|6502 Assembly|There's no real way to do this except maybe by loading a file containing code and then JSR to its memory location.}}
{{omit from|68000 Assembly|See above.}}
{{omit from|8080 Assembly|See above.}}
{{omit from|8086 Assembly|See above.}}
{{omit from|ARM Assembly|See above.}}
{{omit from|Z80 Assembly|See above.}}
885

edits