Difference between revisions of "Nix-shell shebang"
From NixOS Wiki
(add section: Performance) |
(add rust) |
||
Line 55: | Line 55: | ||
print(ansicolor.green(f"done {path}")) | print(ansicolor.green(f"done {path}")) | ||
</syntaxHighlight> | </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> | ||
+ | |||
== Pinning nixpkgs == | == Pinning nixpkgs == |
Revision as of 19:56, 2 April 2022
You can use nix-shell
as a script interpreter to
- run scripts in arbitrary languages
- provide dependencies with Nix
To do this, start the script with multiple shebang (#!
) lines.
The first shebang line is always #! /usr/bin/env nix-shell
.
The second shebang line declares the script language and the script dependencies.
Examples
Bash
To run bash scripts, set the interpreter with -i bash
#! /usr/bin/env nix-shell
#! nix-shell -i bash
echo hello world
You can use nix-shell -p ...
to add dependencies:
#! /usr/bin/env nix-shell
#! nix-shell -i bash -p imagemagick cowsay
# scale image by 50%
convert "$1" -scale 50% "$1.s50.jpg" &&
cowsay "done $1.q50.jpg"
Python
#! /usr/bin/env nix-shell
#! nix-shell -i python3
print("hello world")
#! /usr/bin/env nix-shell
#! nix-shell -i python3 -p python3Packages.pillow python3Packages.ansicolor
# scale image by 50%
import sys, PIL.Image, ansicolor
path = sys.argv[1]
image = PIL.Image.open(path)
factor = 0.5
image = image.resize((round(image.width * factor), round(image.height * factor)))
path = path + ".s50.jpg"
image.save(path)
print(ansicolor.green(f"done {path}"))
Rust
No dependencies
#!/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(""));
}
With dependencies
uses rust-script
#!/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());
}
Pinning nixpkgs
To pin nixpkgs to a specific version, add a third shebang line:
#! /usr/bin/env nix-shell
#! nix-shell -i bash
#! nix-shell -I nixpkgs=https://github.com/NixOS/nixpkgs-channels/archive/nixos-18.03.tar.gz
echo hello world
Performance
TODO ... why the startup delay? how to make it faster?
- Speeding up nix-shell shebang
- cached-nix-shell - Instant startup time for nix-shell