Run Zig source file as a script

Even though this was rejected and removed, it’s still possible:

//usr/bin/env zig run "$0"; exit

pub fn main() void {
    std.debug.print("Hello, world\n", .{});
}

const std = @import("std");

The trick here is that the file is both a valid shell script and Zig program. The first line is interpreted by the shell, which runs zig run "$0", where $0 contains the path to the current file (this also works with other languages that use // as comment tokens: C, Rust, etc.).

You can either run it with your shell

sh test.zig

or make the file executable

chmod +x test.zig

and “execute” it

./test.zig

You should probably never do this, but I just thought it was a fun little hack. That’s all- have a good day :slight_smile:

Related:

15 Likes

This single line shell script uses curl to download zig if env cannot find zig.
/usr/bin/env zig run "$0" || curl "https://.../zig-$(uname -s)-$(uname -m)" --output /tmp/zig && chmod +x /tmp/zig && /tmp/zig run "$0"


Unfortunately arguments need --. e.g. sh test.zig -- Hello World

//usr/bin/env zig run "$0" "$@"; exit

const std = @import("std");

pub fn main() !void {
    for (std.os.argv) |arg| {
        std.debug.print("{s}\n", .{arg});
    }
}
3 Likes

I think you can embed that in the first line, like:

//usr/bin/env zig run "$0" -- "$@"; exit

Edit: I guess if you do that you wouldn’t be able to pass any options to zig run (e.g. sh test.zig --gc-sections would fail).

2 Likes