diff --git a/content/meta/index.json b/content/meta/index.json index 83e49b50d..e487b3548 100644 --- a/content/meta/index.json +++ b/content/meta/index.json @@ -7036,5 +7036,12 @@ ], "path_alias.6c561329-c2fe-415b-a5b1-56b8bcd8481e": [ "node.ba1ab96b-7ef0-4ef4-a525-2bdd6898ac42" + ], + "node.3825516e-0d22-4770-9a2a-73dacd086d59": [ + "user.b8966985-d4b2-42a7-a319-2e94ccfbb849", + "node.20cde1b4-efdc-46a4-a6a4-4fd2264f617e" + ], + "path_alias.fe67ed01-809a-44a5-b2c2-86de66adfb54": [ + "node.3825516e-0d22-4770-9a2a-73dacd086d59" ] } \ No newline at end of file diff --git a/content/node.3825516e-0d22-4770-9a2a-73dacd086d59.yml b/content/node.3825516e-0d22-4770-9a2a-73dacd086d59.yml new file mode 100644 index 000000000..7d4afe54e --- /dev/null +++ b/content/node.3825516e-0d22-4770-9a2a-73dacd086d59.yml @@ -0,0 +1,155 @@ +uuid: + - value: 3825516e-0d22-4770-9a2a-73dacd086d59 +langcode: + - value: en +type: + - target_id: daily_email + target_type: node_type + target_uuid: 8bde1f2f-eef9-4f2d-ae9c-96921f8193d7 +revision_timestamp: + - value: '2025-07-11T19:48:56+00:00' +revision_uid: + - target_type: user + target_uuid: b8966985-d4b2-42a7-a319-2e94ccfbb849 +revision_log: { } +status: + - value: true +uid: + - target_type: user + target_uuid: b8966985-d4b2-42a7-a319-2e94ccfbb849 +title: + - value: 'Writing robust bash scripts with Nix' +created: + - value: '2025-07-08T19:45:04+00:00' +changed: + - value: '2025-07-11T19:48:56+00:00' +promote: + - value: false +sticky: + - value: false +default_langcode: + - value: true +revision_translation_affected: + - value: true +path: + - alias: /daily/2025/07/08/writing-robust-bash-scripts-nix + langcode: en +body: + - value: |- + 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 + format: markdown + processed: | +
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 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:
+{ 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.
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:
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.
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.
+ summary: '' +field_daily_email_cta: + - target_type: node + target_uuid: 20cde1b4-efdc-46a4-a6a4-4fd2264f617e diff --git a/content/path_alias.fe67ed01-809a-44a5-b2c2-86de66adfb54.yml b/content/path_alias.fe67ed01-809a-44a5-b2c2-86de66adfb54.yml new file mode 100644 index 000000000..d13b94b27 --- /dev/null +++ b/content/path_alias.fe67ed01-809a-44a5-b2c2-86de66adfb54.yml @@ -0,0 +1,10 @@ +uuid: + - value: fe67ed01-809a-44a5-b2c2-86de66adfb54 +langcode: + - value: en +path: + - value: /node/3825516e-0d22-4770-9a2a-73dacd086d59 +alias: + - value: /daily/2025/07/08/writing-robust-bash-scripts-nix +status: + - value: true