How to Use the Command 'nix-shell' (with Examples)
The nix-shell
command is a powerful tool from the Nix package manager that allows users to spawn an interactive shell environment based on a Nix expression. It is particularly useful for development environments or any scenario where you need a specified set of dependencies temporarily available without affecting the primary system configuration. The flexibility of nix-shell
lies in its ability to manage dependencies and environments independently, ensuring reproducibility and consistency.
Use Case 1: Start with Nix Expression in shell.nix
or default.nix
in the Current Directory
Code:
nix-shell
Motivation:
When working on a project, you often need a specific environment that includes various tools, libraries, and configurations. By specifying these in a shell.nix
or default.nix
file in your project directory, you can easily recreate that environment on any machine simply by running nix-shell
. This ensures that all team members or build environments have exactly the same setup.
Explanation:
nix-shell
: This runs the command using the Nix expression found in the current directory’sshell.nix
ordefault.nix
. It reads the dependencies and settings listed in the file and sets up the shell environment based on those specifications.
Example Output:
[nix-shell:~/project]$
You are dropped into a shell with all the dependencies and environment variables as specified in your shell.nix
or default.nix
file.
Use Case 2: Run Shell Command in Non-Interactive Shell and Exit
Code:
nix-shell --run "command argument1 argument2 ..."
Motivation:
Sometimes you just need to run a command with a specific set of dependencies without entering an interactive shell. This is useful for running scripts or tools within a defined environment, especially in automation scripts or CI/CD pipelines where interactivity is not needed.
Explanation:
--run
: This option tellsnix-shell
to execute the command provided as a string and exit immediately after it’s done, without starting an interactive shell.command argument1 argument2 ...
: Replace with your specific command and its arguments. The command will run in the environment set up bynix-shell
.
Example Output:
Hello, Nix!
This would be the output if your command was echo "Hello, Nix!"
.
Use Case 3: Start with Expression in default.nix
in the Current Directory
Code:
nix-shell default.nix
Motivation:
In some cases, you specifically want to ensure that the shell environment is created using a particular Nix expression file, ignoring any shell.nix
that might exist. This is particularly useful in monorepo setups where different parts of the repository might require different environments.
Explanation:
default.nix
: The command directly specifiesdefault.nix
as the Nix expression file to be used for setting up the environment, overriding any implicit searching or defaults.
Example Output:
[nix-shell:~/project]$
You’re now in an environment specified by the default.nix
file.
Use Case 4: Start with Packages Loaded from Nixpkgs
Code:
nix-shell --packages package1 package2 ...
Motivation:
Sometimes all you need is to quickly have access to some packages that are available in the Nixpkgs repository without setting up a full shell.nix
or default.nix
file. This is perfect for ad-hoc development or testing tasks where you might need access to tools like git
, python
, etc.
Explanation:
--packages
: This option allows you to specify which packages to install from the Nixpkgs repository for the shell session.package1 package2 ...
: Replace with the specific package names you’d like to have available.
Example Output:
[nix-shell:~/project]$ git --version
git version 2.30.0
This output indicates that the Git package is available within your Nix shell environment.
Use Case 5: Start with Packages Loaded from a Specific Nixpkgs Revision
Code:
nix-shell --packages package1 package2 ... -I nixpkgs=https://github.com/NixOS/nixpkgs/archive/nixpkgs_revision.tar.gz
Motivation:
Different projects might need different versions of the same package due to varying requirements or compatibility issues. By specifying a Nixpkgs revision, you can ensure that your development environment uses the exact versions of packages that your project depends on, maintaining consistency.
Explanation:
--packages
: Specifies the desired packages to load.-I nixpkgs=...
: Points to a specific revision of the Nixpkgs repository, allowing you to load packages exactly as they were at the time of that revision.nixpkgs_revision
: Placeholder for a specific commit hash or tag to use from the Nixpkgs repository.
Example Output:
[nix-shell:~/project]$ python --version
Python 3.9.0
The exact version reflects what’s available at the specified Nixpkgs revision.
Use Case 6: Evaluate Rest of File in Specific Interpreter for Use in #!-scripts
Code:
nix-shell -i interpreter --packages package1 package2 ...
Motivation:
Creating #!-scripts
that work in any environment by specifying their dependencies through Nix is extremely powerful. This use case is prevalent for scripts that need a specific version of an interpreter or libraries to ensure that they work correctly regardless of the user’s underlying system configuration.
Explanation:
-i interpreter
: This flag tellsnix-shell
to use the specified interpreter, likebash
,python
, or another language interpreter, for running the remainder of the script.--packages
: Specifies any dependencies required by the script, ensuring they are available when the script is executed.package1 package2 ...
: The list of all packages needed for the script to run.
Example Output:
Script executed successfully.
After executing a script with the environment set up, you observe the intended outputs or results.
Conclusion:
The versatility of nix-shell
shines in various scenarios, ranging from setting up complex development environments to running simple scripts with specific dependencies. By understanding these use cases, users can leverage nix-shell
to improve reproducibility, consistency, and reliability in their workflows. Whether working individually or in a large team, these examples highlight how nix-shell
can be tailored to meet diverse development needs.