<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.nixos.org/w/index.php?action=history&amp;feed=atom&amp;title=Shell_scripts%2Fen</id>
	<title>Shell scripts/en - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.nixos.org/w/index.php?action=history&amp;feed=atom&amp;title=Shell_scripts%2Fen"/>
	<link rel="alternate" type="text/html" href="https://wiki.nixos.org/w/index.php?title=Shell_scripts/en&amp;action=history"/>
	<updated>2026-08-06T02:41:15Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>https://wiki.nixos.org/w/index.php?title=Shell_scripts/en&amp;diff=33969&amp;oldid=prev</id>
		<title>FuzzyBot: Updating to match new version of source page</title>
		<link rel="alternate" type="text/html" href="https://wiki.nixos.org/w/index.php?title=Shell_scripts/en&amp;diff=33969&amp;oldid=prev"/>
		<updated>2026-07-28T01:28:19Z</updated>

		<summary type="html">&lt;p&gt;Updating to match new version of source page&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;languages/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The package &amp;lt;code&amp;gt;writeShellScript&amp;lt;/code&amp;gt; can be used to add shell scripts to Nix expressions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxHighlight lang=&amp;quot;nix&amp;quot;&amp;gt;&lt;br /&gt;
someBuildHelper = { name, sha256 }:&lt;br /&gt;
  stdenv.mkDerivation {&lt;br /&gt;
    inherit name;&lt;br /&gt;
    outputHashMode = &amp;quot;recursive&amp;quot;;&lt;br /&gt;
    outputHashAlgo = &amp;quot;sha256&amp;quot;;&lt;br /&gt;
    outputHash = sha256;&lt;br /&gt;
    builder = writeShellScript &amp;quot;builder.sh&amp;quot; &amp;#039;&amp;#039;&lt;br /&gt;
      echo &amp;quot;hi, my name is &amp;#039;&amp;#039;${0}&amp;quot; # escape bash variable&lt;br /&gt;
      echo &amp;quot;hi, my hash is ${sha256}&amp;quot; # use nix variable&lt;br /&gt;
      echo &amp;quot;hello world&amp;quot; &amp;gt;output.txt&lt;br /&gt;
    &amp;#039;&amp;#039;;&lt;br /&gt;
  };&lt;br /&gt;
&amp;lt;/syntaxHighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== External builder.sh script ==&lt;br /&gt;
&lt;br /&gt;
Longer Bash scripts are usually stored as external script files, and called from Nix:&lt;br /&gt;
&lt;br /&gt;
{{file|default.nix|nix|3=&lt;br /&gt;
{&lt;br /&gt;
  outputTxtDrv = stdenv.mkDerivation rec {&lt;br /&gt;
    name = &amp;quot;output.txt&amp;quot;;&lt;br /&gt;
    # disable unpackPhase etc&lt;br /&gt;
    phases = &amp;quot;buildPhase&amp;quot;;&lt;br /&gt;
    builder = ./builder.sh;&lt;br /&gt;
    nativeBuildInputs = [ coreutils jq ];&lt;br /&gt;
    PATH = lib.makeBinPath nativeBuildInputs;&lt;br /&gt;
    # only strings can be passed to builder&lt;br /&gt;
    someString = &amp;quot;hello&amp;quot;;&lt;br /&gt;
    someNumber = builtins.toString 42;&lt;br /&gt;
    someJson = builtins.toJSON { dst = &amp;quot;world&amp;quot;; };&lt;br /&gt;
  };&lt;br /&gt;
}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
{{file|builder.sh|sh|3=&lt;br /&gt;
echo &amp;quot;$someString $(echo &amp;quot;$someJson&amp;quot; | jq -r &amp;#039;.dst&amp;#039;) $someNumber&amp;quot; &amp;gt;$out&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
See also:&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/NixOS/nixpkgs/issues/23099 Make a derivation with no source]&lt;br /&gt;
* [https://nixos.org/guides/nix-pills/working-derivation.html Nix Pills: Chapter 7. Working Derivation]&lt;br /&gt;
&lt;br /&gt;
=== runCommand + builder.sh ===&lt;br /&gt;
&lt;br /&gt;
Instead of &amp;lt;code&amp;gt;stdenv.mkDerivation&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;runCommand&amp;lt;/code&amp;gt; can also be used to call an external Bash script:&lt;br /&gt;
&lt;br /&gt;
{{file|default.nix|nix|3=&lt;br /&gt;
{&lt;br /&gt;
  outputTxtDrv = runCommand &amp;quot;output.txt&amp;quot; {&lt;br /&gt;
    nativeBuildInputs = [ coreutils jq ];&lt;br /&gt;
    # only strings can be passed to builder&lt;br /&gt;
    someString = &amp;quot;hello&amp;quot;;&lt;br /&gt;
    someNumber = builtins.toString 42;&lt;br /&gt;
    someJson = builtins.toJSON { dst = &amp;quot;world&amp;quot;; };&lt;br /&gt;
  } (builtins.readFile ./builder.sh);&lt;br /&gt;
}&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Packaging ==&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxHighlight lang=&amp;quot;nix&amp;quot;&amp;gt;&lt;br /&gt;
# nix-build -E &amp;#039;with import &amp;lt;nixpkgs&amp;gt; { }; callPackage ./default.nix { }&amp;#039;&lt;br /&gt;
&lt;br /&gt;
{ stdenv&lt;br /&gt;
, lib&lt;br /&gt;
, fetchFromGitHub&lt;br /&gt;
, bash&lt;br /&gt;
, subversion&lt;br /&gt;
, makeWrapper&lt;br /&gt;
}:&lt;br /&gt;
  stdenv.mkDerivation {&lt;br /&gt;
    pname = &amp;quot;github-downloader&amp;quot;;&lt;br /&gt;
    version = &amp;quot;08049f6&amp;quot;;&lt;br /&gt;
    src = fetchFromGitHub {&lt;br /&gt;
      # https://github.com/Decad/github-downloader&lt;br /&gt;
      owner = &amp;quot;Decad&amp;quot;;&lt;br /&gt;
      repo = &amp;quot;github-downloader&amp;quot;;&lt;br /&gt;
      rev = &amp;quot;08049f6183e559a9a97b1d144c070a36118cca97&amp;quot;;&lt;br /&gt;
      sha256 = &amp;quot;073jkky5svrb7hmbx3ycgzpb37hdap7nd9i0id5b5yxlcnf7930r&amp;quot;;&lt;br /&gt;
    };&lt;br /&gt;
    buildInputs = [ bash subversion ];&lt;br /&gt;
    nativeBuildInputs = [ makeWrapper ];&lt;br /&gt;
    installPhase = &amp;#039;&amp;#039;&lt;br /&gt;
      mkdir -p $out/bin&lt;br /&gt;
      cp github-downloader.sh $out/bin/github-downloader.sh&lt;br /&gt;
      wrapProgram $out/bin/github-downloader.sh \&lt;br /&gt;
        --prefix PATH : ${lib.makeBinPath [ bash subversion ]}&lt;br /&gt;
    &amp;#039;&amp;#039;;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxHighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;wrapProgram&amp;lt;/code&amp;gt; will move the original script to &amp;lt;code&amp;gt;.github-downloader.sh-wrapped&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
=== Command not found ===&lt;br /&gt;
&lt;br /&gt;
For example, the script throws the error &amp;lt;code&amp;gt;svn: command not found&amp;lt;/code&amp;gt;, because the dependency &amp;lt;code&amp;gt;subversion&amp;lt;/code&amp;gt; is missing.&lt;br /&gt;
&lt;br /&gt;
When a command is missing, you can use &amp;lt;code&amp;gt;nix-locate&amp;lt;/code&amp;gt; to find the package name. for example, the &amp;lt;code&amp;gt;stat&amp;lt;/code&amp;gt; command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxHighlight lang=&amp;quot;console&amp;quot;&amp;gt;&lt;br /&gt;
$ nix-locate bin/stat | grep &amp;#039;bin/stat$&amp;#039;&lt;br /&gt;
coreutils.out       0 s /nix/store/vr96j3cxj75xsczl8pzrgsv1k57hcxyp-coreutils-8.31/bin/stat&lt;br /&gt;
&amp;lt;/syntaxHighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Debugging embedded scripts ==&lt;br /&gt;
&lt;br /&gt;
When a bash script fails, it prints only an error message, but no code location.&lt;br /&gt;
&lt;br /&gt;
To trace commands and line numbers, one can use&lt;br /&gt;
&lt;br /&gt;
{{file|test-trace.nix|nix|3=&lt;br /&gt;
{ runCommand, coreutils }:&lt;br /&gt;
runCommand &amp;quot;output.txt&amp;quot; { nativeBuildInputs = [ coreutils ]; } &amp;#039;&amp;#039;&lt;br /&gt;
  # line 5 in nix file = line 1 in bash script -&amp;gt; offset 4&lt;br /&gt;
  PS4=&amp;#039;+ Line $(expr $LINENO + 4): &amp;#039;&lt;br /&gt;
  set -o xtrace # print commands&lt;br /&gt;
&lt;br /&gt;
  echo hello &amp;gt;$out # line 9 in nix file&lt;br /&gt;
&lt;br /&gt;
  set +o xtrace # hide commands&lt;br /&gt;
&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxHighlight lang=&amp;quot;console&amp;quot;&amp;gt;&lt;br /&gt;
$ nix-build -E &amp;#039;with import &amp;lt;nixpkgs&amp;gt; { }; callPackage ./test-trace.nix { }&amp;#039;&lt;br /&gt;
this derivation will be built:&lt;br /&gt;
  /nix/store/2v5biwny8plpyk2bv6cfr41ppp0a1i4k-output.txt.drv&lt;br /&gt;
building &amp;#039;/nix/store/2v5biwny8plpyk2bv6cfr41ppp0a1i4k-output.txt.drv&amp;#039;...&lt;br /&gt;
++ Line 9: echo hello&lt;br /&gt;
++ Line 11: set +o xtrace&lt;br /&gt;
/nix/store/ppidmnpd5m762x9kqj8jd3g7df7dknrz-output.txt&lt;br /&gt;
&amp;lt;/syntaxHighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== POSIX shell ==&lt;br /&gt;
&lt;br /&gt;
Some environments (like OpenWRT, via BusyBox) offer only a &amp;quot;limited&amp;quot; shell (&amp;lt;code&amp;gt;sh&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;bash&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
On NixOS, POSIX shells are provided by the packages &amp;lt;code&amp;gt;dash&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;posh&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== See also ==&lt;br /&gt;
&lt;br /&gt;
* [[Nix-shell shebang|Nix-shell shebang]]&lt;br /&gt;
* [https://nixos.org/manual/nixpkgs/stable/#ssec-stdenv-functions Shell functions section in the Nixpkgs manual]&lt;br /&gt;
* [https://gist.github.com/travisbhartwell/f972aab227306edfcfea nix-shell and Shebang Lines]&lt;br /&gt;
* [https://ertt.ca/nix/shell-scripts/ Shell Scripts with Nix]&lt;br /&gt;
&lt;br /&gt;
[[Category:Development{{#translation:}}|Shell scripts]]&lt;br /&gt;
[[Category:Shell{{#translation:}}|Shell scripts]]&lt;/div&gt;</summary>
		<author><name>FuzzyBot</name></author>
	</entry>
</feed>