Nix-shell shebang: Difference between revisions
imported>Milahu Created page with "You can use <code>nix-shell</code> as a script interpreter to * run scripts in arbitrary languages * provide dependencies with Nix To do this, start the script with multiple..." |
→C#: Add EntryPointFileDirectoryPath to sample, new in preview 6 |
||
| (15 intermediate revisions by 11 users not shown) | |||
| Line 7: | Line 7: | ||
The first shebang line is always <code>#! /usr/bin/env nix-shell</code>.<br> | The first shebang line is always <code>#! /usr/bin/env nix-shell</code>.<br> | ||
The second shebang line declares the script language and the script dependencies. | The second shebang line declares the script language and the script dependencies. | ||
As of Nix 2.19.0 you can also use the new CLI <code>nix shell</code> and flakes to define shebangs. See [https://nixos.org/manual/nix/stable/command-ref/new-cli/nix.html?highlight=shebang#shebang-interpreter docs]. | |||
== Examples == | == Examples == | ||
| Line 16: | Line 18: | ||
<syntaxHighlight lang="bash"> | <syntaxHighlight lang="bash"> | ||
#! /usr/bin/env nix-shell | #! /usr/bin/env nix-shell | ||
#! nix-shell -i bash | #! nix-shell -i bash -p bash | ||
echo hello world | echo hello world | ||
| Line 30: | Line 32: | ||
convert "$1" -scale 50% "$1.s50.jpg" && | convert "$1" -scale 50% "$1.s50.jpg" && | ||
cowsay "done $1.q50.jpg" | cowsay "done $1.q50.jpg" | ||
</syntaxHighlight> | |||
=== C# === | |||
Using file-based apps, new in .NET 10: | |||
<syntaxHighlight lang="csharp"> | |||
#!/usr/bin/env nix-shell | |||
/* | |||
#! nix-shell -i dotnet -p dotnetCorePackages.dotnet_10.sdk | |||
*/ | |||
#:package Humanizer@2.14.1 | |||
using Humanizer; | |||
Environment.CurrentDirectory = (string) AppContext.GetData("EntryPointFileDirectoryPath")!; // equivalent of `cd $(dirname $0)` | |||
var dotNet9Released = DateTimeOffset.Parse("2024-12-03"); | |||
var since = DateTimeOffset.Now - dotNet9Released; | |||
Console.WriteLine($"It has been {since.Humanize()} since .NET 9 was released."); | |||
</syntaxHighlight> | </syntaxHighlight> | ||
| Line 36: | Line 59: | ||
<syntaxHighlight lang="python"> | <syntaxHighlight lang="python"> | ||
#! /usr/bin/env nix-shell | #! /usr/bin/env nix-shell | ||
#! nix-shell -i python3 | #! nix-shell -i python3 -p python3 | ||
print("hello world") | print("hello world") | ||
| Line 54: | Line 77: | ||
image.save(path) | image.save(path) | ||
print(ansicolor.green(f"done {path}")) | print(ansicolor.green(f"done {path}")) | ||
</syntaxHighlight> | |||
=== Rust === | |||
==== No dependencies ==== | |||
<syntaxHighlight lang="bash"> | |||
#!/usr/bin/env nix-shell | |||
#![allow()] /* | |||
#!nix-shell -i bash -p rustc | |||
rsfile="$(readlink -f $0)" | |||
binfile="/tmp/$(basename "$rsfile").bin" | |||
rustc "$rsfile" -o "$binfile" --edition=2021 && exec "$binfile" $@ || exit $? | |||
*/ | |||
fn main() { | |||
for argument in std::env::args().skip(1) { | |||
println!("{}", argument); | |||
}; | |||
println!("{}", std::env::var("HOME").expect("")); | |||
} | |||
</syntaxHighlight> | |||
==== With dependencies ==== | |||
uses [https://github.com/fornwall/rust-script rust-script] | |||
<syntaxHighlight lang="bash"> | |||
#!/usr/bin/env nix-shell | |||
//! ```cargo | |||
//! [dependencies] | |||
//! time = "0.1.25" | |||
//! ``` | |||
/* | |||
#!nix-shell -i rust-script -p rustc -p rust-script -p cargo | |||
*/ | |||
fn main() { | |||
for argument in std::env::args().skip(1) { | |||
println!("{}", argument); | |||
}; | |||
println!("{}", std::env::var("HOME").expect("")); | |||
println!("{}", time::now().rfc822z()); | |||
} | |||
</syntaxHighlight> | |||
=== Haskell === | |||
<syntaxHighlight lang="haskell"> | |||
#! /usr/bin/env nix-shell | |||
#! nix-shell -p "haskellPackages.ghcWithPackages (p: with p; [turtle])" -i runghc | |||
{-# LANGUAGE OverloadedStrings #-} | |||
import Turtle | |||
main = echo "Hello world!" | |||
</syntaxHighlight> | </syntaxHighlight> | ||
| Line 63: | Line 140: | ||
#! /usr/bin/env nix-shell | #! /usr/bin/env nix-shell | ||
#! nix-shell -i bash | #! nix-shell -i bash | ||
#! nix-shell -I nixpkgs=https://github.com/NixOS/nixpkgs | #! nix-shell -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/aed4b19d312525ae7ca9bceb4e1efe3357d0e2eb.tar.gz | ||
echo hello world | echo hello world | ||
</syntaxHighlight> | </syntaxHighlight> | ||
== Flake == | |||
It is also possible to make it work for flake like in: | |||
<syntaxHighlight lang="bash"> | |||
#!/usr/bin/env -S nix shell nixpkgs#bash nixpkgs#hello nixpkgs#cowsay --command bash | |||
hello | cowsay | |||
</syntaxHighlight> | |||
The [https://nix.dev/manual/nix/2.19/command-ref/new-cli/nix3-shell doc] mentions that it should be possible to run more complex commands using multiple lines, but it does not work for me as reported [https://github.com/NixOS/nixpkgs/issues/280033 here]. | |||
== Performance == | |||
TODO ... why the startup delay? how to make it faster? | |||
* [https://discourse.nixos.org/t/speeding-up-nix-shell-shebang/4048 Speeding up nix-shell shebang] | |||
* [https://github.com/xzfc/cached-nix-shell cached-nix-shell] - Instant startup time for nix-shell | |||
* [https://www.tweag.io/blog/2020-06-25-eval-cache/ Nix Flakes, Part 2: Evaluation caching - Tweag] | |||
== See also == | == See also == | ||
| Line 74: | Line 171: | ||
* [https://gist.github.com/travisbhartwell/f972aab227306edfcfea nix-shell and Shebang Lines] | * [https://gist.github.com/travisbhartwell/f972aab227306edfcfea nix-shell and Shebang Lines] | ||
* [https://notes.yukiisbo.red/posts/2021/07/Spice_up_with_Nix_Scripts.html Spice up with Nix: Scripts with magical dependencies] | * [https://notes.yukiisbo.red/posts/2021/07/Spice_up_with_Nix_Scripts.html Spice up with Nix: Scripts with magical dependencies] | ||
[[Category:Nix]] | |||
[[Category:Shell]] | |||