Move all files to sculpin/
This commit is contained in:
parent
c5d71803a5
commit
0f61b4e9ee
1514 changed files with 0 additions and 0 deletions
73
sculpin/source/_posts/2025-07-08.md
Normal file
73
sculpin/source/_posts/2025-07-08.md
Normal file
|
@ -0,0 +1,73 @@
|
|||
---
|
||||
date: 2025-07-08
|
||||
title: Writing robust bash scripts with Nix
|
||||
permalink: /daily/2025/07/08/writing-robust-bash-scripts-nix
|
||||
---
|
||||
|
||||
I have a lot of custom Bash scripts I use - some to perform simple commands like `git log` with some additional arguments, to more complex ones that mount and unmount USB devices plugged into my laptop.
|
||||
|
||||
A lot of people will post their scripts online along with their dotfiles for others to read and take inspiration from.
|
||||
|
||||
Mine are in my [nix config][0] directory and each script is added as a custom package I can install.
|
||||
|
||||
Here's an example of a script written as a Nix package:
|
||||
|
||||
```nix
|
||||
{ pkgs }:
|
||||
|
||||
pkgs.writeShellApplication {
|
||||
name = "get-tags";
|
||||
|
||||
runtimeInputs = with pkgs; [ git ];
|
||||
|
||||
text = ''
|
||||
if [[ "$#" -gt 0 ]]; then
|
||||
git tag | grep "$*"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
git tag
|
||||
'';
|
||||
}
|
||||
```
|
||||
|
||||
It gets a filtered list of Git tags within a repository using the `git tag` and `grep` commands.
|
||||
|
||||
Nix automatically adds the shebang line and sets some default shell options, so those aren't included within the script text.
|
||||
|
||||
It also automatically runs `shellcheck` to ensure the script is correct.
|
||||
|
||||
## Injecting Dependencies
|
||||
|
||||
This script depends on `git`. Without it, it would not run successfully.
|
||||
|
||||
Instead of assuming it is installed, `runtimeInputs` ensures any dependencies are present and the script can be executed, even if the dependencies aren't enabled globally.
|
||||
|
||||
Scripts can also rely on other scripts.
|
||||
|
||||
`get-tags` has a corresponding `count-tags` script that counts the returned tags:
|
||||
|
||||
```nix
|
||||
pkgs.writeShellApplication {
|
||||
name = "count-tags";
|
||||
|
||||
runtimeInputs = with pkgs; [
|
||||
coreutils
|
||||
get-tags
|
||||
];
|
||||
|
||||
text = ''
|
||||
get-tags "''${1:-}" | wc -l
|
||||
'';
|
||||
}
|
||||
```
|
||||
|
||||
`get-tags` is declared as a dependency, as well as `coreutils` to add the `wc` command that counts the lines.
|
||||
|
||||
## Here's the thing
|
||||
|
||||
Using this approach gives me more robust scripts that are checked and verified, and will always have the required dependencies.
|
||||
|
||||
And, because they are added as custom Nix packages in my configuration, I am able to decide which scripts to install on which computer, giving me the most flexibility.
|
||||
|
||||
[0]: https://code.oliverdavies.uk/opdavies/nix-config
|
Loading…
Add table
Add a link
Reference in a new issue