Shell Scripts: Difference between revisions
imported>Milahu + External builder.sh script |
imported>Milahu + runCommand + builder.sh, fix links |
||
Line 25: | Line 25: | ||
outputTxtPath = stdenv.mkDerivation rec { | outputTxtPath = stdenv.mkDerivation rec { | ||
name = "output.txt"; | name = "output.txt"; | ||
# disable unpackPhase etc | # disable unpackPhase etc | ||
phases = "buildPhase"; | phases = "buildPhase"; | ||
builder = ./builder.sh; | builder = ./builder.sh; | ||
Line 43: | Line 43: | ||
</syntaxHighlight> | </syntaxHighlight> | ||
See also | |||
* [https://github.com/NixOS/nixpkgs/issues/23099 make a derivation with no source] | |||
* [https://nixos.org/guides/nix-pills/working-derivation.html Nix Pills: Chapter 7. Working Derivation] | |||
=== runCommand + builder.sh === | |||
Instead of <code>stdenv.mkDerivation</code>, we can also use <code>runCommand</code> to call an external bash script: | |||
<syntaxHighlight lang="nix"> | |||
# default.nix | |||
{ | |||
outputTxtPath = runCommand "output.txt" { | |||
nativeBuildInputs = [ coreutils jq ]; | |||
# only strings can be passed to builder | |||
someString = "hello"; | |||
someNumber = builtins.toString 42; | |||
someJson = builtins.toJSON { dst = "world"; }; | |||
} (builtins.readFile ./builder.sh); | |||
} | |||
</syntaxHighlight> | |||
== Packaging == | == Packaging == |
Revision as of 13:22, 9 October 2021
the package writeShellScript
can be used to add shell scripts to nix expressions
someBuildHelper = { name, sha256 }:
stdenv.mkDerivation {
inherit name;
outputHashMode = "recursive";
outputHashAlgo = "sha256";
outputHash = sha256;
builder = writeShellScript "builder.sh" ''
echo "hi, my name is ''${0}" # escape bash variable
echo "hi, my hash is ${sha256}" # use nix variable
echo "hello world" >output.txt
'';
};
External builder.sh script
Longer bash scripts are usually stored as external script files, and called from Nix:
# default.nix
{
outputTxtPath = stdenv.mkDerivation rec {
name = "output.txt";
# disable unpackPhase etc
phases = "buildPhase";
builder = ./builder.sh;
nativeBuildInputs = [ coreutils jq ];
PATH = lib.makeBinPath nativeBuildInputs;
# only strings can be passed to builder
someString = "hello";
someNumber = builtins.toString 42;
someJson = builtins.toJSON { dst = "world"; };
};
}
# builder.sh
echo "$someString $(echo "$someJson" | jq -r '.dst') $someNumber" >$out
See also
runCommand + builder.sh
Instead of stdenv.mkDerivation
, we can also use runCommand
to call an external bash script:
# default.nix
{
outputTxtPath = runCommand "output.txt" {
nativeBuildInputs = [ coreutils jq ];
# only strings can be passed to builder
someString = "hello";
someNumber = builtins.toString 42;
someJson = builtins.toJSON { dst = "world"; };
} (builtins.readFile ./builder.sh);
}
Packaging
example:
# nix-build -E 'with import <nixpkgs> { }; callPackage ./default.nix { }'
{ stdenv
, lib
, fetchFromGitHub
, bash
, subversion
, makeWrapper
}:
stdenv.mkDerivation {
pname = "github-downloader";
version = "08049f6";
src = fetchFromGitHub {
# https://github.com/Decad/github-downloader
owner = "Decad";
repo = "github-downloader";
rev = "08049f6183e559a9a97b1d144c070a36118cca97";
sha256 = "073jkky5svrb7hmbx3ycgzpb37hdap7nd9i0id5b5yxlcnf7930r";
};
buildInputs = [ bash subversion ];
nativeBuildInputs = [ makeWrapper ];
installPhase = ''
mkdir -p $out/bin
cp github-downloader.sh $out/bin/github-downloader.sh
wrapProgram $out/bin/github-downloader.sh \
--prefix PATH : ${lib.makeBinPath [ bash subversion ]}
'';
};
wrapProgram
will move the original script to .github-downloader.sh-wrapped
Command not found
for example, the script throws the error svn: command not found
, because the dependency subversion
is missing.
when a command is missing, you can use nix-locate
to find the package name. for example, the stat
command:
$ nix-locate bin/stat | grep 'bin/stat$'
coreutils.out 0 s /nix/store/vr96j3cxj75xsczl8pzrgsv1k57hcxyp-coreutils-8.31/bin/stat
Posix Shell
some environments (like OpenWRT, via busybox
) offer only a "limited" shell (sh
instead of bash
).
on nixos, posix shells are provided by the packages dash
and posh