oldratlee/useful-scripts: Java and Shell utilities for production debugging
🐌 useful scripts for making developer's everyday life easier and happier, involved java, shell etc.
At a glance
- What is it?
- A Bash 3.2+ script collection whose Java tools answer two questions fast: which threads are burning CPU, and which jar is shadowing a class. Useful if you already live in a terminal and run Java in production.
- Who is it for?
- Adopt it if you debug Java processes on Linux boxes where top shows high us and you want the thread stack without attaching a profiler, or if you keep hitting NoSuchMethodError from a jar conflict. Skip it if you need a maintained, versioned release line: the newest tag is v3.0.0-Alpha from 2024-04-15 and the README points at a release-3.x branch for the self-installer.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 103 days ago.
- What is it written in?
- Mainly Shell, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The two Java questions these scripts answer in one command
The Java side of this repository is small and specific. show-busy-java-threads targets CPU performance problems, described in the README as the case where the top us value is too high. It finds the running Java processes that are consuming CPU, identifies the threads inside them doing that work, and prints those thread stacks, so the method call responsible is visible without a profiler attached. show-duplicate-java-classes goes after class conflicts: it finds duplicate classes across jar files and class directories, which is the situation behind the classic NoSuchMethodError or wrong-bean-loading bug. find-in-jars is the third, a search across every jar in a directory for a class or resource file. All three assume you are on a machine where the process is running and you can see it from a shell, which is exactly the situation where a full APM agent is not deployed yet and you need an answer in the next two minutes.
How the scripts are laid out and why Bash 3.2 is the floor
The repository keeps bin/, lib/, docs/ and test/ at the top level, with the default branch named dev-3.x. The README states a development rule for scripts in the library: they use Bash 3.2+ and are written for production environments with a preference for strict, safe construction. The reason given for Bash rather than another shell is deployment reality (it is still the default in most environments), the Google Shell Style Guide position that Bash is the only shell language allowed for scripts, and the cost of porting across sh, zsh, fish, csh, tcsh, ksh, ash and dash. That is a deliberate constraint, not an accident, and it means the scripts are portable to old base images where a modern Bash is not installed. It also means you should not expect them to run under sh invoked as dash, and the README does not claim they do. The author notes that Python is used in some script implementations as well.
Installing useful-scripts and running show-busy-java-threads for the first time
The README's quick path is a self-installer fetched and sourced in one line. Sourcing matters: it runs in your current shell rather than a subshell, which is how the installer can put the scripts onto your PATH for the session. The README points to docs/install.md for the other download and usage methods, so treat this line as the shortcut rather than the whole story.
source <(curl -fsSL https://raw.githubusercontent.com/oldratlee/useful-scripts/release-3.x/test/self-installer.sh)After that, the first real use is the CPU case. You run the Java script against a host where top shows high us, and the README says it automatically finds the Java process consuming CPU and prints the thread stacks behind it. You should expect output that names threads and shows the stack frames they are executing, which is what lets you point at a method rather than guess.
show-busy-java-threadsThe second common use is the class conflict case, where the goal is to see which jars and class directories contain the same class name so you can work out which one is winning on the classpath.
show-duplicate-java-classesIf you only need to know whether a class or resource exists anywhere under a directory of jars, find-in-jars is the search tool for that, and the README describes it as searching all jar files under a directory for a class or resource file.
The Shell helpers are a different product with a different audience
Half the repository has nothing to do with Java. c prints a command line as-is and copies stdout to the system clipboard, removing a Ctrl+C step when moving between the terminal and another application. coat and taoc are colored cat and tac for reading files line by line. a2l prints arguments one per line with color. uq deduplicates input lines without sorting first, which is the difference from the system uniq, since uniq only collapses adjacent duplicates. ap and rp convert file paths to absolute or relative form, following links and normalizing. cp-into-docker-run copies a local executable into a running docker container and runs it there. tcp-connection-state-counter counts TCP connections per state for connection load questions. xpl and xpf open or select a file or folder in a file browser from the command line. On the development side there is echo-args for debugging script arguments with red brackets, console-text-color-themes.sh for previewing Terminator color combinations, and parseOpts.sh, an option parsing library that adds support for options with multiple values. None of this is a framework. Each script is a small standalone answer to a repeated manual action, which is the stated premise of the repository.
Where it stops being the right tool
The release cadence is the first thing to weigh. The most recent tag listed is v3.0.0-Alpha from 2024-04-15, described in its own release title as a work-in-progress cleanup release, with v2.5.4 and v2.5.3 before it in April and February 2024. The last push to the repository was on 2026-06-19, so the code is not abandoned, but the tagged release line is old and the newest tag is explicitly an alpha. If your policy is to install only from stable tags, you are choosing between an alpha and a 2.5.x release. Second, these are diagnostic scripts, not monitoring. show-busy-java-threads gives you a snapshot of thread stacks at the moment you run it; it does not record, aggregate, or alert, and a CPU spike that has already passed will not be in the output. Third, the Java scripts depend on the host where the JVM runs, so a container built from a slim image without the JDK command line tools is a poor fit. Fourth, the whole library is Bash, so Windows users need a POSIX-like environment, and the README does not document a native Windows path.
Compared with attaching a profiler or a JFR recording
The obvious alternative for the CPU case is a sampling profiler or a Java Flight Recorder session, which gives you flame graphs, allocation data, and a timeline you can replay. That is strictly more information. The difference in approach is what you pay for it. A profiler or JFR run requires either a restart with the right flags or an attach step, produces a file you then have to move and open in a viewer, and on a production box during an incident the attach itself can be a negotiation. show-busy-java-threads takes the opposite position: no recording, no viewer, no artifacts, just thread stacks printed to the terminal you are already in. For class conflicts, the alternative is the JVM's own class loading diagnostics or a build tool's dependency tree, which tells you the declared graph rather than which jars on disk actually contain the class. show-duplicate-java-classes inspects the files, which is closer to the failure you are chasing when the classpath was assembled at deploy time. Pick the profiler when you need history or allocation detail; pick these scripts when you need to know which method is spinning right now.
Licence, contribution route and what upgrading costs you
The repository is Apache-2.0, and the README links to the licence text at apache.org. For most internal use that is a permissive licence with a patent grant, but the usual Apache-2.0 obligations apply, including keeping the licence and notice files when you redistribute. This is a description of the licence, not legal advice; check with your own counsel if you plan to vendor the scripts into a product. On upgrades, there is a practical trap worth naming: the README's quick-start line fetches from release-3.x, while the repository's default branch is dev-3.x and the newest tag is v3.0.0-Alpha. Those are three different things, and a team that installs via the self-installer and a team that clones the default branch are not running the same code. The README also points to docs/install.md for the full set of download and usage methods, and that file is where the pinned options live. Contribution is through issues and pull requests from a fork, and the README asks users who deploy it at their company to report that in the who's-using issue.
Editorial conclusion
Adopt it if you debug Java processes on Linux boxes where top shows high us and you want the thread stack without attaching a profiler, or if you keep hitting NoSuchMethodError from a jar conflict. Skip it if you need a maintained, versioned release line: the newest tag is v3.0.0-Alpha from 2024-04-15 and the README points at a release-3.x branch for the self-installer. Before putting it in a runbook, check that your shell is Bash 3.2 or newer, that the target host has the JDK tools the scripts call, and read docs/install.md rather than assuming the curl line is the only path.
Frequently asked questions
Which shell does oldratlee/useful-scripts require?
The README states that scripts in the library use Bash 3.2+ and are written for production environments. The author chose Bash because it is still the default shell in most environments and because the Google Shell Style Guide allows only Bash for shell scripts.
How do I install oldratlee/useful-scripts?
The README gives a one-line self-installer that you source from the release-3.x branch, and points to docs/install.md for the other download and usage methods. Sourcing runs it in your current shell rather than a subshell.
What does show-busy-java-threads do in oldratlee/useful-scripts?
It targets Java CPU performance problems where the top us value is too high. According to the README it automatically finds the running Java processes consuming CPU and prints the thread stacks responsible, so you can identify the method call causing the load.
What is the latest release of oldratlee/useful-scripts?
The most recent tag listed is v3.0.0-Alpha from 2024-04-15, which its own release title describes as a work-in-progress cleanup release. Before it, v2.5.4 was released on 2024-04-12 and v2.5.3 on 2024-02-18.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/oldratlee-useful-scripts)