______   __       ______   ______   __  __    
/\  ___\ /\ \     /\  __ \ /\  ___\ /\ \_\ \   
\ \___  \\ \ \____\ \ \/\ \\ \___  \\ \  __ \  
 \/\_____\\ \_____\\ \_____\\/\_____\\ \_\ \_\ 
  \/_____/ \/_____/ \/_____/ \/_____/ \/_/\/_/ 

the slosh guide : quickstart

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).

Login Shell

This quickstart assumes that you are running slosh as your login shell. If you have not set it up as such you may do so by making sure that the path to the slosh executable is listed in the /etc/shells file. If it is, then you should be able to use chsh to set your shell to slosh. See man chsh for more details.

Command Completion and Basic Shell Features

slosh, like all shells, takes commands and performs actions or provides output based on those commands. Commands, as well as their arguments, are words (strings of non-whitespace characters) separated by whitespace characters.

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 in the paths section of this document. Completion can be enacted by typing and then pressing the tab key. If more than one completion value is found a list of possibilities will be displayed.

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).

Strings

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

Paths

All filepaths must start with /, ./, .., or ~. 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 cd/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

Internally, cd and dir are both aliased to this behavior. So you may, at your option, type cd or dir before a path if you like.

Also of note, tab completion always expands the filepath to an absolute path. This takes up more screen real estate but increases clarity (a design goal).

File globbing works as you would expect (using * or **), but file paths that include globs will not be autocompleted (past the glob portion).

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

Pipes

Piping works as you have come to expect:


$ ls -la | grep *.go | lolcat
[...]

Redirection

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

Command Chaining/Continuation

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 allowing the let command (see local variables, 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 and check the value of $?.

Variables

slosh has two types of variables: global and local.

Global

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

The 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 unset command:


$ set myvar 'Hello, world'
$ echo $myvar
Hello, world
$ unset myvar
$ echo $myvar


Local

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 myvar).

Aliasing

You can set an alias the same way you set a variable (but with the alias builtin):


$ alias ll ls -lah

The first argument is 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 to ls -la and ll to ls --color=auto the -la does not get added to the ll alias.

You can remove an alias with unalias:


$ unalias ll

Slosh File

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.

Custom Prompt

slosh supports prompt customization via the global variable SLOSH_PROMPT. As such, you could put something like the following in your ~/.slosh file:


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:

Limitations

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 jobs and fg) and likely will not in the future. A simple multiplexer like dvtm or mtm 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.