||1 year ago|
|.gitignore||1 year ago|
|LICENSE||1 year ago|
|Makefile||1 year ago|
|README.md||1 year ago|
|TODO.md||1 year ago|
|builtins.go||1 year ago|
|commandRunner.go||1 year ago|
|go.mod||1 year ago|
|go.sum||1 year ago|
|main.go||1 year ago|
|rc.go||1 year ago|
|slosh.1||1 year ago|
|utils.go||1 year ago|
slosh is a new interactive shell designed for use at
ssh [user]@colorfield.space to replace the very limited shell that has been in use there for some time.
Lets get the elephant in the room out of the way: there is no reason most people reading this should want to use this shell. It does not do anything new or inovative (though does combine a few previous shell styles), it is more limited than most shells - by design (you can always run
bash scripts from slosh, so there is no need to write a whole programming language into a simple shell), and it lacks many common features.
So why write a new shell at all? Because I like writing and owning my tools. Because it was a good learning experience (it turns out that many things shells implement are more complicated than they seem like they would be). Because I was bored in the evening for a few days and it was something to do. Because my ssh server community was in need of an upgrade from an even more limited shell.
So you've decided to forge ahead (or are on one of my systems and trying to make the best of it). Cool. This section will go over the feature set I have decided on for slosh (or, SLOum's SHell).
For starters, slosh features command completion for anything on the $PATH. Completion is also available for file paths, with a small caveat that will be talked about next. slosh also offers command history via the up/down arrows. In general, emacs bindings are supported for moving around the command input (see the underlying library liner for more info on those key bindings).
You can group text into a string at the shell by surrounding the text with quotes. This treats it as a single value being passed to the given application. Variables get expanded in double quoted strings and do not in single quoted strings.
# echo "I am $SHELL" I am /usr/local/bin/slosh # echo 'I am $SHELL' I am $SHELL
All filepaths must start with
~. So if you are trying to complete a file in the current directory named
myfile.txt you cannot type
myf<tab>. You must type
./myf<tab>, or the like. The same goes for running an executable in the current directory named 'myexecutable'. If you just run
myexecutable you will be met with a message saying that it was not found on your $PATH. However, typing
./myexecutable works as expected.
This path specificity enables slosh to know that it is working with a filepath, which in turn enables us to ditch the
dir command. Instead of using cd you can just type the path and hit enter and you will move there.
# pwd /home/myuser/go/src/git.rawtext.club/sloum/slosh # ~/Documents # pwd /home/myuser/Documents
dir are both aliased to this behavior. So you may, at your option, include
dir if you like.
Also of note, tab completion always expands the filepath. This takes up more screen real estate but increases clarity (a design goal).
File globbing works as you would expect (using
**), but file paths that include globs will not be autocompleted.
Additionally there is a builtin called
up that takes a number as an argument. It will move you up the number of directories given:
# pwd /usr/local/share/man/man1 # up 3 # pwd /usr/local
Piping works as you have come to expect:
# ls -la | grep *.go | lolcat
slosh only supports very basic output redirection. There is no separation of stdout and stderr. If you redirect, you will get both. Redirection works with the same syntax you are likely used to (with the former creating/overwriting a file and the later appending to a file):
# ls -la | grep *.go | lolcat > ~/some-file.txt # echo "set PATH $PATH:/home/myuser/bin" >> ~/.slosh
You can run multiple commands from the same line of input via the
&& command. If any command in the line fails, the following ones will not run. The
&& opperator is particularly useful for allow the
let command (see below) to function and provide commands with local environment variables.
# echo "Starting thing1..." && some-program Starting thing1... [...]
# let GOOS linux && let GOARCH arm && go build -ldflags "-w -s" -o slosh
There is not another way to chain commands (other than pipes) in slosh. If you want two+ commands to run one after the other but do not want their execution to rely on the previous command having exited successfully: put them on separate lines.
slosh has two types of variables: global and local.
A global variable is much like a regular bash or sh style variable, but uses csh syntax (mostly) in its definition:
# set myvar1 "I am a variable in the $SHELL shell" # echo $myvar1 I am a variable in the /usr/local/bin/slosh shell # set myvar2 I am a $SHELL variable # echo $myvar2 I am a /usr/local/bin/slosh variable # set myvar2 'I am a $SHELL' # echo $myvar3 I am a $SHELL
set builtin takes the variable name as its first argument and any subsequent arguments are concatenated into a double quoted string (they will have variable references expanded). You can, of course, use single quotes to not trigger variable expansion.
You can remove the reference to a global variable with the
# set myvar 'Hello, world' # echo $myvar Hello, world # unset myvar # echo $myvar
Local variables have the same syntax as global variables, except they use
let instead of
set. Where you use them is different though. Instead of affecting the shell environment a let variable is passed into the execution environment of subsequent applications called as a part of the same shell execution. For example:
# let GOOS linux && let GOARCH arm && go build -o ./slosh
In the above example
GOOS is set to
linux and passed to the next command's execution environment (without adding it to the global environment that the shell itself draws from).
GOARCH is then set to
arm and both are passed into the
go build command, which will use those variables. This behavior also works with pipes (
Be aware that when you create the local variable it gets passed forward, but never backward. So if you add a local variable in the middle of a series of commands it will not be available to commands that came before it. The local scope gets cleared when the whole command entry line is finished.
Local variables are not available to the shell itself, only to commands run by the shell:
# let myvar 12345 && echo $myvar
...nothing gets echoed in the above because
$myvar does not exist in the scope of the shell, only in the scope of the echo program (and the code for echo does not call a variable named
You can set an alias the same way you set a variable (but with the
alias ll ls -lah
The first argument if the name of the new alias and the arguments that follow are the value of the alias. An alias will not look up another alias. So if you set
ls -la and
ls --color=auto the
-la does not get added to the
You can remove an alias with
slosh will look for a file named
.slosh in your home directory. If it is present, it will be read when slosh is launched. This is a good place to set aliases and global variables. There is nothing special about the slosh file in terms of execution. The shell reads each line and treats them as if they were typed in at the shell at runtime. This is different than things like a .bashrc or various script files for shells where they are run as a script and have their own environment. If you are just using it for variables and aliases you should have no trouble with that difference. You could also use the file to launch programs at runtime.
Comments can be added to a
.slosh file. Comments are always the whole line and always start with
#. There are no multiline comments or comments than come after content on a line.
alias c clear # Prompt options # %c - Current dir # %d - Short dir listing # %D - Full dir listing # %h - Host name # %u - Current user set SLOSH_PROMPT "%u@%h - %c # "
If you make changes to your slosh file while running slosh and want to reload the file into the current runtime, you can do so with
lsf (load slosh file). This will clear all aliases before loading any new ones, so be aware of that. At present
lsf cannot be used to load arbitrary files with slosh oriented commands in them, though that is being looked into for a future release.
slosh supports prompt customization via the global variable
SLOSH_PROMPT. As such, you could put something like the following in your
set SLOSH_PROMPT "%u@%h [%c] -> "
Escape codes have no effect within this variable and may have unexpected results. This is due to a limitation in the underlying line editing library being used by slosh. You may have noticed in the above example that there are a few weird
%-based instructions. The following are currently avaialable:
%c- current base directory (example:
%d- a short path, consisting of the last three path segments (example:
%D- the full path (example:
%h- the current host (example:
%u- the current user's username (example:
slosh is not a programming language the way bash and many other shell/command languages are. There are no if statements, no loops, etc. The general ethos behind slosh has been: if you want to program you can either write a bash script and execute it with bash or you can use a programming language (Lua, Python, C, or anything else you like). slosh is meant to be a very minimal shell that provides a basic feature set to allow you to navigate a system successfully, but not much more.
As mentioned above, redirection of stderr, stdout, and stdin is not possible in a granular way.
slosh does not support job control (
ctrl-z on most systems then
fg) and likely will not in the future. A simple multiplexer like
dvtm makes this less necessary.
At present it is not possible to run a job in the background via the
& command. However, this is planned for a future version.
git clone https://git.rawtext.club/sloum/slosh && cd slosh go build -ldflags "-w -s" -o slosh
Alternatively you can use the Makefile...
git clone https://git.rawtext.club/sloum/slosh && cd slosh make
I recommend running
upx -9 ./slosh if you have
upx and want a smaller binary. But it will work fine either way, so not a big worry.
If you'd prefer to just run it once for fun:
git clone https://git.rawtext.club/sloum/slosh && cd slosh && go run *.go
slosh is released under the floodgap free software license, a copy of which is included in the repo.