HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
abathur
resholve
Python2021–2025
abathur / resholve

resholve

a shell resolver? :) (find and resolve shell script dependencies)

2Distinct people
10Mentions
1Explicit recommenders
267GitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

a shell resolver? :) (find and resolve shell script dependencies)

GitHub

Where it is used

No documented product use has been verified yet.

What people are saying

> Same w/ the "pipe to read" (although it doesn't seem to work right with OSX's bash-3.2). I found this gizmo somewhere and it's worth sharing as well... Yes, you need a recent…

pxc used a recommendation phrase. One indexed comment matches. This is a phrase match, not a verdict.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

No other repository is repeatedly linked in the same discussions.

This week on Hacker News

Nov 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 1:49:46 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year10 dated mentions

Observed mentions: 2021-11-02 01:58:49 UTC to 2025-12-13 22:29:07 UTC.

012342021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments20212022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 4 mentions; 0 submissions, 4 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments20232024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2025

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC101
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC404
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC101
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC202
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC202

What Hacker News says

10 sources
> If a script is simple - I use posix sh + awk, sed, etc. > But if a script I write needs to use arrays, sets, hashtable or processes many files One option that I sometimes use at work (in addition to writing some Python CLIs) that is a pretty nice next step on this spectrum is Bash-with-all-the-fixins'. I use a Nix-based dependency resolver for shell scripts called resholve¹ to parse scripts so that it can identify all of their dependencies (including Bash itself), then produce a "compiled" script as a Nix build where all of the references to external programs are replaced with pinned Nix store paths. Then I have a fixed (and recent) version of GNU Bash regardless of platform, so I'm free to use Bash features that are newer or nicer than POSIX sh. My favorite such features are `mapfile` and `lastpipe` for writing in a more functional sty
Read the rest
le, plus of course maps ("associative arrays"). I don't have to worry about portability problems with common utilities, because my scripts will bring along the expected implementations of coreutils, `find`, `grep`, etc. I'm free to use "modern" alternatives to classic utilities (like `rg` instead of GNU grep or `fd` instead of GNU findutils) if they offer better performance or more readable syntax. Polished interactivity is easy to build by just embedding a copy of `fzf`. And while I don't love Bash for working with structured data, it becomes a lot less painful when I can just pull in `jq`. It's obviously got some disadvantages versus an option like Python, but the amount-of-code to functionality ratio is also much more favorable than Python's. I typically use this for scripting build and development tasks in projects that already use Nix (via Devenv— I have some unpublished changes to the scripts module that add resholve and ShellCheck integration) to manage their environments, so there's no special packaging/distribution/setup burden. IME it makes for vastly more readable and maintainable shell scripts than painstakingly limiting oneself to pure POSIX sh, so it can serve quite well as a middle ground option between barebones sh and a "real" programming language as your little script gradually grows in complexity. > if you need external deps - just statically link them and distribute a cross-compiled binary (use zigcc[1] or easy Nim cross-compilation). The deployment story sounds very slick and hard to beat! This is something I might want to try for scripts I want to be easy to distribute on macOS systems that don't have Nix installed. -- 1: https://github.com/abathur/resholve
In Using Python for Scripting
I've written most of the development environment declarations for my team's projects, which are mostly glue code or IaC in Terraform, Python, Bash (Nix can do some really cool things with Bash scripts[1]), and Ruby, and some Nix packages that we also use to deploy those projects. About half of my team uses Nix on macOS, and the other half uses Nix on Linux (via WSL), and our other deployment targets are all Linux on AWS (some EC2 boxes, some Lambda services, some ECS/Fargate deployments), though not all of those are Nix-based. There are sometimes small differences, like sometimes a Python package with native dependencies will fail to build in some Linux environments but not on macOS or vice-versa, but generally you don't, even then, need to special-case things by operating system to make them work uniformly. As for overall support, macOS
Read the rest
is a more chaotic and quirky environment: macOS updates break applications or remove APIs more often than Linux updates do, macOS updates nuke configuration files in `/etc`, or blindly steamroll system users (low UIDs), the login shell doesn't manage environment variables or other aspects of the GUI session, etc. These are extra hurdles that Nix has to work around on macOS. But it generally works well and the only real hooks that Nix needs into your environment are some shell scripts that need to be sourced on startup. If you know how to manage your PATH and shell initialization in general, you can do it with Nix. (Additionally, one distributions of Nix itself includes some extra software for managing these hurdles that works pretty well at the cost of a more opinionated and more "invasive" install-- check out "Determinate Nix" if you're interested.) Other than that, it's basically the same as on Linux. Package selection is good, things mostly work the same way. Nix's support for platforms other than Linux and macOS is less mature. In years past, efforts have waxed and waned, but in the past few years there've been some concerted and persistent efforts to make Nix and Nixpkgs more usable on Windows, NetBSD, and FreeBSD. Even native (e.g., not just cross-compilation from other platforms) support for Windows is actually a thing! You can also easily set up "remote builders" to local VMs for Linux and FreeBSD so that you can transparently build packages and environments for those platforms on your Mac, if that's a frequent choice of development platform. Overall I'd say it's pretty good, but I don't personally know much about the current status of FreeBSD. It looks like there are a few hundred FreeBSD-specific packages in Nixpkgs, and there's also a fork of NixOS based on FreeBSD called NixBSD. Most packages include "platforms = [ unix ];" in their metadata, which means they're at least intended to build for not just Linux and macOS but also FreeBSD, but I don't know if Hydra is building binaries for any FreeBSD platforms. If it's not, then many packages may be untested and have small build problems. My guess is that at worst, Nix on FreeBSD is probably slightly behind where Nix on Linux was when I got into it 7 or 8 years ago. At that time, Nix still felt amazing and very worth it, but certainly required a willingness to learn how to package things and fill in gaps yourself to get the most out of it. Consider dropping by NixOS' Matrix community; I'm sure there's a FreeBSD channel. -- 1: https://github.com/abathur/resholve/
In Claude Code IDE integration for Emacs
pxc·Sep 18, 2024Recommendation phrase
> Same w/ the "pipe to read" (although it doesn't seem to work right with OSX's bash-3.2). I found this gizmo somewhere and it's worth sharing as well... Yes, you need a recent Bash for this (and lots of other nice things like 'associative arrays' (maps)). To free myself up to write more concise and legible scripts, I lean into bashisms and make use of external programs without restriction, regardless of what's shipped by default on any system. To recover portability where I need it, I use Nix to fix my Bash interpreter versions as well as the versions of external tools. When my scripts are 'packaged' by Nix, their bodies are written as multiline strings in Nix. In that case, Nix takes care of setting the shebang to a fixed version of Bash, and I interpolate external commands in like this: "${pkgs.coreutils}/bin/realpath" . # these
Read the rest
do "${pkgs.coreutils}/bin/pwd" --physical # the same thing and in that way my scripts use only their fixed dependencies at fixed versions without modifying the environment at all. This also works nicely across platforms, so when these scripts run on macOS they get the same versions of the GNU coreutils as they do when they run on Linux, just compiled for the appropriate platform and architecture. Same goes for different architectures. So this way your script runs 'natively' (no virtualization) but you still pin all its dependencies. In other contexts (e.g., cloud-init), I use bash a bit more restrictively depending on what versions I'm targeting. But I still use Nix to provide dependencies so that my scripts use the same versions of external tools regardless of distro or platform: nix shell nixpkgs#toybox --command which which # these do nix run nixpkgs#which -- which # the same thing `nix run` and `nix shell` both behave as desired in pipelines and subshells and all that. (To get the same level of determinism as with the method of use outlined earlier, you'd want to either pin the `nixpkgs` ref in your local flake registry or replace it with a reference that pinned the ref down to a commit hash.) There are is a really cool tool[1] by the Nixer abathur for automagically converting naively-written scripts to ones that pin their deps via Nix, as in the first example. I'm not using it yet but I likely will if the scripts I use for our development environments at work get much bigger-- that way I can store them as normal scripts without any special escaping/templating and linters will know how to read them and all that. Anyhow, it's totally safe to install a newer Bash on macOS, and I recommend doing it for personal interactive use and private scripts. Pkgsrc and MacPorts both have Bash 5.x, if you don't have or want Nix. > I need to write up some thoughts on bash being effectively a lisp if you stare at it the right way. You should! It's totally true, since external commands and shell builtins are in a prefix syntax just like Lisp function calls. Some shells accentuate this a bit, like Fish, where subshells are just parens with no dollar signs so nested subcommands look very Lisp-y, and Elvish, whose author (xiaq) has tried to lean into that syntactic convergence designing a new shell (drawing inspiration from Scheme in various places). > I found this gizmo somewhere and it's worth sharing as well... # MAGIC DEBUGGING LINE #trap '(read -p "[$BASH_SOURCE:$LINENO] $BASH_COMMAND? ")' DEBUG Okay that looks really nifty. I will definitely find a use for that literally tomorrow, if not today. -- 1: https://github.com/abathur/resholve
In Show HN: Sol – A de-minifier for shell programs
We have some common cause / need in the Nix/nixpkgs ecosystem, where finding missing package dependencies (whether they're bare invocations or absolute paths) is a bit of an ongoing problem. The golden path stuff isn't too hard to find during packaging, but there's a long tail of stuff that only shows up when you hold something exactly right. We can (with some effort) handle a decent fraction of posix/bash shell statically with https://github.com/abathur/resholve. I think a similar approach could generalize to most interpreted languages (but I haven't gotten around to it myself and I think it's broadly rarer beyond Shell). I have taken one or two steps into a lower-fidelity approach (https://github.com/abathur/binlore) that uses YARA rules to scan for signs of ~exec in both binary formats and interpreted languages. For now this is mostly
Read the rest
just a top-N formats thing, but there's no reason we can't keep going. One of the big advantages is that it's fairly cross-platform, even if accuracy is suboptimal. The scanning approach isn't just amazing for resholve's specific needs. I'm stepping down this path to try to identify executables that likely exec their command-line arguments--because this is a sign that resholve need to know how to check invocations of that command for other executables. But it's a good bit better at flagging things that have _any_ exec behavior, and that's a decent-enough first step for letting focus on a smaller set. Once we find these, though, we're generally left with human analysis of the help, manpage, and/or source to figure out what exec the scanner is hitting on and whether it's part of the CLI. I've been ~snoozing on this front for a while, but I feel like a decent fraction of the components for building something like an 80% toolkit exist in at least a primitive form. It could probably benefit from some more static source analysis bits. I also vaguely intend to look into whether LLMs can do a reasonably-good job of making it easier to answer these questions from the help/man/source. Unless something out in that space can be reliably automated, it also needs some way to ~pin assertions about the arguments to the relevant code in a way that they'll break if that specific corner of the codebase changes. (I've wondered if semgrep expressions could handle this.) There are also some other bits around that might fit in, though cross-platform is a common-ish problem. We've looked a little at using a FUSE, but that is hard to operationalize on macOS. I also poked at 3 or so less-interactive dynamic approaches a few years back in https://github.com/abathur/commandeer/ and I'm sure a few more have cut their teeth since then. I also wrote a ~shelved-for-now WIP (https://github.com/abathur/faffer) for using some cursed shell metaprogramming to do something like fuzz/tree-shake a shell script for loose dependencies. That isn't directly viable for many languages, but its focus on ~overloading flow-control structures to make it easier for force branch coverage does seem like something that might be feasible with rewriting tools.
In Show HN: Tracexec – TUI for tracing execve and pre-exec behavior
> I think you misunderstood me. My comment about being native is that Linux does not look at your path when handling the shebang. I understood your comment. Maybe we're just doing a prescriptivist/descriptivist thing. The shebang is a good example of a Unixy affordance with creative applications, and I asked for clarification because I (a descriptivist :) don't see why any specific functionality enabled by this affordance is more or less valid. > Since POSIX doesn't standardize where env is there is no way to know how to launch env ahead of time. In a fundamental sense, it's impossible to be certain that code written to run on one system will run on any ~other (including the one it was written on, since it may have mutated it in incompatible ways as soon as execution starts). We can try to trust POSIX, but most distros enable users to mut
Read the rest
ate the system in ways that even it can't protect us from. > If there is no way to write a generic shebang you might as well just accept that you will need to change it. I'm of (at least) two minds about this. It's obviously correct that there's no way to write a generic shebang that will work everywhere. But I think it's also obviously a poor use of human time and attention, at scale, for us to all individually waste time ~localizing every third-party script for every system we ever run it on (perhaps repeatedly, as the system changes). The impossibility of a 100% solution isn't a good reason to shun 90% solutions. (I say this as someone who develops a tool, https://github.com/abathur/resholve, for ~localizing bash/shell scripts--shebang included. In some sense my ego could benefit from end users needing a tool for this, but the task is inherently fraught on stateful systems and is probably best addressed at the package-manager level.) > Fair point. I am also biased from PRs also trying to insert flake.nix into projects. Just as fair. They mean well (and generally just want to make the project easier to distribute or contribute to), but they can be a bit ~deaf to reasonable concerns about adding to the maintenance burden. > My issue is that nix is doing something nonstandard and it feels like projects are having to accommodate nix's oddities instead of nix being the one to accommodate what already exists. Also fair, though I hope you'll keep your eyes open for cases where people trying to package a project with Nix are shaking loose portability/reproducibility/underspecification problems that are already latent in the project and are worth fixing even if you ultimately reject the .nix file. (This won't be everything. There are certainly cases where Nix is the only one needing the patch and should do the work to keep up with it.) Anecdotal, but it's reasonably common to run into projects with hardcoded paths that leave the build/test processes working cleanly on exactly one person's mutable system without anything anywhere saying what that system is or how they bootstrap it. I've seen this include ~snapshotted test outputs that will only pass on the authors system because it's affected by files or even dotfiles that may be in the project directory but not committed, or higher up in the directory tree on the system. This kind of stuff is just as likely to trip up non-Nix contributors. It may also be a big hurdle to the broader OSS community being able to pick up the torch for them if they get burned out, fall ill, change careers, etc. (Sometimes maintainers are standoffish about fixing these, especially if they distribute their own binaries or directly push artifacts out to package repositories and so on. They may not understand why we want to build from source or run their test suite or build scripts or build the manual. I'm sympathetic on some level, but I must admit I'm flummoxed when people seem actively incurious about reports that suggest they might have trouble building the project if they lost access to their device). > Not all instances of it in build scripts are properly rewritten. Any example? There are definitely asterisks (https://github.com/NixOS/nixpkgs/blob/a4d0fe7270cc03eeb1aba4...), and the default behavior here is one driver for people going out to ask for `/usr/bin/env` (because those can get autopatched). But we do still have the tools to patch them. It isn't the end of the world if you tell us to kick rocks. > Also there would be work in creating a migration plan to not breaking people who currently rely on its existence. Yes (though, perhaps ironically, the closest I have to a pitch for Nix is what an incredible lever nix/nixpkgs/NixOS are for experimenting with the feasibility of ideas like this at scale).
In What's your go to Nix/NixOS pitch?
Completions have in general been of interest, though the shell-specific completions I've looked at so far were all too dynamic. I'd forgotten all about Fig since I saw your launch post here last year, so thanks for reminder. (I don't think I had quite started to work on parsing specific external commands, yet, so it wouldn't have clicked at the time. Was still focused on just identifying the likely presence of exec in the executables.) Are you familiar with the parse code? Are you handling painful stuff like combined short flags with a trailing option? (If I ferreted out some of the more painful cases I've had to wrangle, I am curious if you'd have a gut sense of whether your approach handles it. Would you mind if I reach out? I am working on this for https://github.com/abathur/resholve)
In Building the Future of the Command Line
@dloreto @robrich A little aside from the announcement, but since it seems like you both work on this I wanted to surface something that came up down in a subthread: I'm curious if you attempted to support macOS by doing this with Nix's dockerTools and cross-compiling (there may be better sources, but it's at least hinted at in https://nix.dev/tutorials/building-and-running-docker-images...)? If so, I'm wondering where that failed or bogged down? --- Background: I build a tool (https://github.com/abathur/resholve) for ~packaging Bash/Shell (i.e., for demanding all dependencies be present). The tool's technically agnostic, but I built it specifically to fix Shell packaging in Nix. I think it could benefit a lot of other Shell projects, since one of Shell's big tribulations is dealing with heterogenous environments, but most Shell projects
Read the rest
wouldn't see much reason to endure the pain of adopting Nix if they still had to support the heterogenous environments. Much like you're doing here, I've been hoping to figure out how to build a Nix-based packaging flow that can generate deployable standalone bundles or containers. It'd be a heavy way to bundle Shell, but I imagine some projects would take the tradeoff for predictability and reduced support load. But since it would need to take place within a Nix build, I'd need to cross-compile for it to work on macOS. Hoping you know if it's a dead-end or not :)
In Show HN: Devbox – Easy, predictable shells and containers
For a concrete example, I've been developing a tool (https://github.com/abathur/resholve) that can ~build/link Bash/Shell scripts--i.e., rewrite them with external executables converted to absolute paths. (This helps ensure dependencies are known, declared, present, and don't have to be on the global PATH for the script to execute cleanly.) There's a devilish sub-problem, which is that any given executable can potentially exec arbitrary arguments. For now I handle this with a very crude automated binary/executable analysis that needs to be augmented by human source analysis. Deep multi-language source analysis wouldn't be very scalable, but I suspect fairly-standardized structural annotations could improve the results in a scalable way. I have to imagine there are other applications of the same information.
In Ask HN: Why aren't code diagram generating tools more common?
I came here to say this, too :) But, of course, it isn't a silver bullet... 1. You still have to have a sane PATH. A fair amount of the Nix install-related issues that get opened are PATH problems, and you can also run into problems with PATH in cron/launchd (as @tyingq noted). 2. You still have to know what the script depends on. This can get tricky beyond small scripts you wrote yourself. (I write a tool for discovering and ~linking/resolving external dependencies in Shell scripts, https://github.com/abathur/resholve. As I've been working on converting some of nixpkgs' existing Shell packages to use it, I almost always find dependencies the initial packager missed.)
In On env Shebangs

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.