hshell¶
A bash competitor that lets you write shell-like scripts in Kotlin, with many other useful features that bash doesn't provide.
Warning
This site provides docs for an unreleased product! PROCEED WITH CAUTION AND LOW EXPECTATIONS.
Additionally, these docs are incomplete and do not reflect the full API available. They're intended as a brief guide to be read in combination with in-house API docs and IDE auto completion.
Let's get started¶
demo.shell.kts | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
Run hshell demo.shell.kts
or chmod +x demo.shell.kts; ./demo.shell.kts
.
List directories and print tables¶
Print the current directory contents as colored ls
style output, and a table:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
Find the path to the script, and its containing directory:
1 2 |
|
Shell operations¶
For mv
, cp
, find
etc see the Shell API. For wget
see downloading things.
Other string utilities¶
1 |
|
File ops¶
See shell API.
Dependencies¶
Brace expansion in coordinates works:
1 2 3 4 5 6 |
|
XML¶
1 2 3 4 5 6 7 8 9 10 |
|
Cleaning up¶
Instead of writing foo.use { foo -> foo.whatever() }
to clean things up, you can write foo.closeAtEnd().whatever()
:
1 |
|
The closeAtEnd()
function uses defer
to register a code block to run when the script finishes:
1 2 |
|
The last block deferred is run first.
Use exit(exitCode)
to terminate early. Don't call exitProcess
unless you're sure you want immediate termination without any finally
or deferred blocks running.
Disk caching¶
A LocalDiskCache
will give you a directory associated with an arbitrary string key, passing it to a handler to fill with content if
the key misses in the cache:
1 2 3 4 5 |
|
The cache will automatically keep its size in check, is thread safe and can be configured in various ways. You can also force cache misses and edit content in place.
Subshells and concurrency¶
Shell commands can be modified by global state, to avoid long repetitive argument lists (copyOptions
, diffOptions
etc). subshell
yields a new shell with a copy of all the current shell's state, which can then be used safely from another thread.
1 2 3 4 5 6 7 8 |
|
A better way is like this:
1 2 3 |
|
If the path is a file this function just invokes operation on it and returns. Otherwise, it walks over the given directory and executes operation on each entry in parallel on a thread pool, blocking whilst the entire operation completes.
The operation is invoked for all entries of a directory before the directory itself, meaning you can delete directories, sum their sizes etc. Or in other words the operation is invoked deepest first and path comes last.
The symLinkFollowing
mode is respected. If it's set to SymlinkFollowing.FOLLOW_EXTERNAL
or SymlinkFollowing.ALWAYS_FOLLOW
that means
you may be passed paths that are not children of path, or be passed the same paths more than once, so be ready for that.
WARNING: Circular symlinks aren't currently detected.
Sockets, mmapping files etc¶
hshell doesn't provide anything specific for this, but the whole Java API is available so you can simply use that instead.
Logging things¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
On the console:
When running hshell --show-log
:
Logging how long a code block took is easy, and you can give a time threshold below which no log line is made:
1 2 3 4 |
|