There is intentionally no way to do that globally. There are essentially two proper methods:
Packaging the shell script as Nix derivation
(pkgs.writeShellScriptBin "toggle-color-scheme" ''
XDG_DATA_DIRS="${pkgs.glib.getSchemaPath pkgs.glib}" "${pkgs.glib}/bin/gsettings" set org.gnome.desktop.interface color-scheme prefer-dark
'')
You can just install the package created by the expression (e.g. through environment.systemPackages
or by storing it to a variable and then using ${variable}/bin/toggle-color-scheme
in your swaync config (if it is generated in Nix)).
There are also other variations of the method:
Wrapping a separate script
#!/usr/bin/env bash
gsettings set org.gnome.desktop.interface color-scheme prefer-dark
(pkgs.runCommand
"toggle-color-scheme"
{
nativeBuildInputs = [
pkgs.makeWrapper
];
}
''
mkdir -p "$out/bin"
cp -r "${./toggle-color-scheme.sh}" "$out/bin/toggle-color-scheme"
# Replace the interpreter with static path not relying on PATH.
patchShebangs "$out/bin/toggle-color-scheme"
# Wrap the script with environment variables necessary for finding dependencies.
wrapProgram "$out/bin/toggle-color-scheme" \
--prefix PATH : "${lib.makeBinPath [ pkgs.glib ]}" \
--prefix XDG_DATA_DIRS : "${pkgs.glib.getSchemaPath pkgs.glib}"
'')
This might be useful if you want to package a third-party script or you want to use the script outside of NixOS as well.
If you just need PATH
fixed, resholved
might be less tedious and error-prone.
This is useful if you want something that is more immediately runnable without having to jump through packaging:
#! /usr/bin/env nix-shell
#! nix-shell -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/842d9d80cfd4560648c785f8a4e6f3b096790e19.tar.gz -i bash -p glib -p gsettings-desktop-schemas
export XDG_DATA_DIRS="$GSETTINGS_SCHEMAS_PATH"
gsettings set org.gnome.desktop.interface color-scheme prefer-dark
The above shebang runs the script as if it was run in a shell created with something like pkgs.mkShell { buildInputs = [ pkgs.glib pkgs.gsettings-desktop-schemas ]; }
. The glib
setup hook populates the Nixpkgs-specific GSETTINGS_SCHEMAS_PATH
environment variable, which you can use in XDG_DATA_DIRS
to make gsettings
command find the schemas.
I also pin the Nixpkgs revision to ensure long term reproducibility.
This option will be a lot slower than the first one since, unless you abandon reproducibility and use system-wide NIX_PATH
, Nixpkgs will need to be fetched at minimum the first time the script is executed. Then Nix will need to evaluate the Nix environment derivation on each execution. There are some links on how to improve performance on the unofficial wiki.
See also Reproducible interpreted scripts — nix.dev documentation